1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 05:29:30 +00:00

Allow line_bynumber to return more than one result

This commit is contained in:
Matt Seabold 2023-01-11 20:18:51 -05:00
parent 7979f8a41f
commit 8ea0dfe453

View File

@ -4736,14 +4736,18 @@ static SpanInfoListEntry* FindSpanInfoByAddr (const SpanInfoList* L, cc65_addr A
static LineInfo* FindLineInfoByLine (const Collection* LineInfos, cc65_line Line)
/* Find the LineInfo for a given line number. The function returns the line
** info or NULL if none was found.
static int FindLineInfoByLine (const Collection* LineInfos, cc65_line Line,
unsigned *Index)
/* Find the LineInfo for a given line number. The function returns true if the
** name was found. In this case, Index contains the index of the first item
** that matches. If the item wasn't found, the function returns false and
** Index contains the insert position for Name.
*/
{
/* Do a binary search */
int Lo = 0;
int Hi = (int) CollCount (LineInfos) - 1;
int Found = 0;
while (Lo <= Hi) {
/* Mid of range */
@ -4755,16 +4759,20 @@ static LineInfo* FindLineInfoByLine (const Collection* LineInfos, cc65_line Line
/* Found? */
if (Line > CurItem->Line) {
Lo = Cur + 1;
} else if (Line < CurItem->Line) {
Hi = Cur - 1;
} else {
/* Found */
return CurItem;
Hi = Cur - 1;
/* Since we may have duplicates, repeat the search until we've
** the first item that has a match.
*/
if(Line == CurItem->Line) {
Found = 1;
}
}
}
/* Not found */
return 0;
/* Pass back the index. This is also the insert position */
*Index = Lo;
return Found;
}
@ -6134,6 +6142,9 @@ const cc65_lineinfo* cc65_line_bynumber (cc65_dbginfo Handle, unsigned FileId,
const FileInfo* F;
cc65_lineinfo* D;
LineInfo* L = 0;
unsigned I;
unsigned Index;
unsigned Count;
/* Check the parameter */
assert (Handle != 0);
@ -6150,18 +6161,31 @@ const cc65_lineinfo* cc65_line_bynumber (cc65_dbginfo Handle, unsigned FileId,
F = CollAt (&Info->FileInfoById, FileId);
/* Search in the file for the given line */
L = FindLineInfoByLine (&F->LineInfoByLine, Line);
/* Bail out if we didn't find the line */
if (L == 0) {
if(!FindLineInfoByLine (&F->LineInfoByLine, Line, &Index)) {
/* Not found */
return 0;
}
/* Index contains the first position. Count how many lines with this number
** we have. Skip the first one, since we have at least one.
*/
Count = 1;
while ((unsigned) Index + Count < CollCount( &F->LineInfoByLine)) {
L = CollAt (&F->LineInfoByLine, (unsigned) Index + Count);
if (L->Line != Line) {
break;
}
++Count;
}
/* Prepare the struct we will return to the caller */
D = new_cc65_lineinfo (1);
D = new_cc65_lineinfo (Count);
/* Copy the data */
CopyLineInfo (D->data, L);
for (I = 0; I < Count; ++I) {
CopyLineInfo (D->data + I, CollAt (&F->LineInfoByLine, Index++));
}
/* Return the allocated struct */
return D;