@@ -70,6 +70,11 @@ uint32_t CodeNoteModel::GetRawPointerValue() const noexcept
7070 return m_pPointerData != nullptr ? m_pPointerData->RawPointerValue : 0xFFFFFFFF ;
7171}
7272
73+ bool CodeNoteModel::HasNestedPointers () const noexcept
74+ {
75+ return m_pPointerData != nullptr && m_pPointerData->HasPointers ;
76+ }
77+
7378static ra::ByteAddress ConvertPointer (ra::ByteAddress nAddress)
7479{
7580 const auto & pConsoleContext = ra::services::ServiceLocator::Get<ra::data::context::ConsoleContext>();
@@ -300,7 +305,19 @@ bool CodeNoteModel::GetNextAddress(ra::ByteAddress nAfterAddress, ra::ByteAddres
300305 return bResult;
301306}
302307
303- void CodeNoteModel::SetNote (const std::wstring& sNote )
308+ std::wstring CodeNoteModel::GetPrimaryNote () const
309+ {
310+ if (m_pPointerData != nullptr )
311+ {
312+ const auto nIndex = m_sNote.find (L" \n +" );
313+ if (nIndex != std::wstring::npos)
314+ return m_sNote.substr (0 , nIndex);
315+ }
316+
317+ return m_sNote;
318+ }
319+
320+ void CodeNoteModel::SetNote (const std::wstring& sNote , bool bImpliedPointer)
304321{
305322 if (m_sNote == sNote )
306323 return ;
@@ -314,28 +331,53 @@ void CodeNoteModel::SetNote(const std::wstring& sNote)
314331 const auto nNextIndex = sNote .find (L' \n ' , nIndex);
315332 sLine = (nNextIndex == std::string::npos) ?
316333 sNote .substr (nIndex) : sNote .substr (nIndex, nNextIndex - nIndex);
317- StringMakeLowercase (sLine );
318- ExtractSize (sLine );
319334
320- if (sLine .find ( L" pointer " ) != std::string::npos )
335+ if (! sLine .empty () )
321336 {
322- if (m_nMemSize == MemSize::Unknown )
337+ if (sLine . at ( 0 ) == ' + ' && bImpliedPointer )
323338 {
324- // pointer size not specified. assume 32-bit
325339 m_nMemSize = MemSize::ThirtyTwoBit;
326340 m_nBytes = 4 ;
341+
342+ // found a line starting with a plus sign, bit no pointer annotation. bImpliedPointer
343+ // must be true. assume the parent note is not described. pass -1 as the note size
344+ // because we already skipped over the newline character
345+ ProcessIndirectNotes (sNote , gsl::narrow_cast<size_t >(-1 ));
346+ m_pPointerData->HeaderLength = 0 ;
347+ break ;
327348 }
328349
329- // if there are any lines starting with a plus sign, extract the indirect code notes
330- nIndex = sNote .find (L" \n +" , nIndex + 1 );
331- if (nIndex != std::string::npos)
332- ProcessIndirectNotes (sNote , nIndex);
350+ StringMakeLowercase (sLine );
351+ ExtractSize (sLine );
333352
334- break ;
335- }
353+ if (sLine .find (L" pointer" ) != std::string::npos)
354+ {
355+ if (m_nMemSize == MemSize::Unknown)
356+ {
357+ // pointer size not specified. assume 32-bit
358+ m_nMemSize = MemSize::ThirtyTwoBit;
359+ m_nBytes = 4 ;
360+ }
336361
337- if (m_nMemSize != MemSize::Unknown) // found a size. stop processing.
338- break ;
362+ // if there are any lines starting with a plus sign, extract the indirect code notes
363+ nIndex = sNote .find (L" \n +" , nIndex + 1 );
364+ if (nIndex != std::string::npos)
365+ ProcessIndirectNotes (sNote , nIndex);
366+
367+ // failed to find nested code notes. create a PointerData object so the note still
368+ // gets treated as a pointer
369+ if (!m_pPointerData)
370+ {
371+ m_pPointerData.reset (new PointerData ());
372+ m_pPointerData->HeaderLength = gsl::narrow_cast<unsigned >(sNote .length ());
373+ }
374+
375+ break ;
376+ }
377+
378+ if (m_nMemSize != MemSize::Unknown) // found a size. stop processing.
379+ break ;
380+ }
339381
340382 if (nNextIndex == std::string::npos) // end of string
341383 break ;
@@ -664,16 +706,27 @@ void CodeNoteModel::ProcessIndirectNotes(const std::wstring& sNote, size_t nInde
664706
665707 // skip over [whitespace] [optional separator] [whitespace]
666708 const wchar_t * pStop = sNextNote .c_str () + sNextNote .length ();
667- while (pEnd < pStop && isspace (*pEnd))
668- pEnd++;
669- if (pEnd < pStop && !isalnum (*pEnd))
709+ while (pEnd < pStop && isspace (*pEnd) && *pEnd != ' \n ' )
710+ ++pEnd;
711+
712+ if (pEnd < pStop)
670713 {
671- pEnd++;
672- while (pEnd < pStop && isspace (*pEnd))
673- pEnd++;
714+ if (*pEnd == ' \n ' )
715+ {
716+ // no separator. found an unannotated note
717+ ++pEnd;
718+ }
719+ else if (!isalnum (*pEnd))
720+ {
721+ // found a separator. skip it and any following whitespace
722+ ++pEnd;
723+
724+ while (pEnd < pStop && isspace (*pEnd))
725+ ++pEnd;
726+ }
674727 }
675728
676- offsetNote.SetNote (sNextNote .substr (pEnd - sNextNote .c_str ()));
729+ offsetNote.SetNote (sNextNote .substr (pEnd - sNextNote .c_str ()), true );
677730 pointerData->HasPointers |= offsetNote.IsPointer ();
678731
679732 offsetNote.SetAddress (gsl::narrow_cast<ra::ByteAddress>(nOffset));
0 commit comments