Postprocess module infos. Add new index for modules sorted by name.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5147 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz
2011-08-10 20:44:20 +00:00
parent 060b297a78
commit ebfa369319

View File

@@ -184,6 +184,7 @@ struct DbgInfo {
/* Collections with other sort criteria */ /* Collections with other sort criteria */
Collection FileInfoByName; /* File infos sorted by name */ Collection FileInfoByName; /* File infos sorted by name */
Collection ModInfoByName; /* Module info sorted by name */
Collection SegInfoByName; /* Segment infos sorted by name */ Collection SegInfoByName; /* Segment infos sorted by name */
Collection SymInfoByName; /* Symbol infos sorted by name */ Collection SymInfoByName; /* Symbol infos sorted by name */
Collection SymInfoByVal; /* Symbol infos sorted by value */ Collection SymInfoByVal; /* Symbol infos sorted by value */
@@ -1711,6 +1712,7 @@ static DbgInfo* NewDbgInfo (void)
CollInit (&Info->SymInfoById); CollInit (&Info->SymInfoById);
CollInit (&Info->FileInfoByName); CollInit (&Info->FileInfoByName);
CollInit (&Info->ModInfoByName);
CollInit (&Info->SegInfoByName); CollInit (&Info->SegInfoByName);
CollInit (&Info->SymInfoByName); CollInit (&Info->SymInfoByName);
CollInit (&Info->SymInfoByVal); CollInit (&Info->SymInfoByVal);
@@ -1751,7 +1753,7 @@ static void FreeDbgInfo (DbgInfo* Info)
FreeSymInfo (CollAt (&Info->SymInfoById, I)); FreeSymInfo (CollAt (&Info->SymInfoById, I));
} }
/* Free the memory used by the collections themselves */ /* Free the memory used by the id collections */
CollDone (&Info->FileInfoById); CollDone (&Info->FileInfoById);
CollDone (&Info->LibInfoById); CollDone (&Info->LibInfoById);
CollDone (&Info->LineInfoById); CollDone (&Info->LineInfoById);
@@ -1760,7 +1762,9 @@ static void FreeDbgInfo (DbgInfo* Info)
CollDone (&Info->SegInfoById); CollDone (&Info->SegInfoById);
CollDone (&Info->SymInfoById); CollDone (&Info->SymInfoById);
/* Free the memory used by the other collections */
CollDone (&Info->FileInfoByName); CollDone (&Info->FileInfoByName);
CollDone (&Info->ModInfoByName);
CollDone (&Info->SegInfoByName); CollDone (&Info->SegInfoByName);
CollDone (&Info->SymInfoByName); CollDone (&Info->SymInfoByName);
CollDone (&Info->SymInfoByVal); CollDone (&Info->SymInfoByVal);
@@ -2332,7 +2336,8 @@ static void ParseInfo (InputData* D)
switch (Tok) { switch (Tok) {
case TOK_FILE: case TOK_FILE:
CollGrow (&D->Info->FileInfoById, D->IVal); CollGrow (&D->Info->FileInfoById, D->IVal);
CollGrow (&D->Info->FileInfoByName, D->IVal);
break; break;
case TOK_LIBRARY: case TOK_LIBRARY:
@@ -2340,11 +2345,12 @@ static void ParseInfo (InputData* D)
break; break;
case TOK_LINE: case TOK_LINE:
/*CollGrow (&D->Info->LineInfoById, D->IVal);*/ CollGrow (&D->Info->LineInfoById, D->IVal);
break; break;
case TOK_MODULE: case TOK_MODULE:
CollGrow (&D->Info->ModInfoById, D->IVal); CollGrow (&D->Info->ModInfoById, D->IVal);
CollGrow (&D->Info->ModInfoByName, D->IVal);
break; break;
case TOK_SCOPE: case TOK_SCOPE:
@@ -2352,11 +2358,14 @@ static void ParseInfo (InputData* D)
break; break;
case TOK_SEGMENT: case TOK_SEGMENT:
CollGrow (&D->Info->SegInfoById, D->IVal); CollGrow (&D->Info->SegInfoById, D->IVal);
CollGrow (&D->Info->SegInfoByName, D->IVal);
break; break;
case TOK_SYM: case TOK_SYM:
CollGrow (&D->Info->SymInfoById, D->IVal); CollGrow (&D->Info->SymInfoById, D->IVal);
CollGrow (&D->Info->SymInfoByName, D->IVal);
CollGrow (&D->Info->SymInfoByVal, D->IVal);
break; break;
default: default:
@@ -2800,6 +2809,7 @@ static void ParseModule (InputData* D)
/* ... and remember it */ /* ... and remember it */
CollReplaceExpand (&D->Info->ModInfoById, M, Id); CollReplaceExpand (&D->Info->ModInfoById, M, Id);
CollAppend (&D->Info->ModInfoByName, M);
ErrorExit: ErrorExit:
/* Entry point in case of errors */ /* Entry point in case of errors */
@@ -2809,9 +2819,6 @@ ErrorExit:
static void ParseScope (InputData* D) static void ParseScope (InputData* D)
/* Parse a SCOPE line */ /* Parse a SCOPE line */
{ {
@@ -3517,11 +3524,159 @@ static int FindFileInfoByName (Collection* FileInfos, const char* Name,
static void ProcessSegInfo (InputData* D) static LineInfoListEntry* FindLineInfoByAddr (const LineInfoList* L, cc65_addr Addr)
/* Postprocess segment infos */ /* Find the index of a LineInfo for a given address. Returns 0 if no such
* lineinfo was found.
*/
{ {
/* Sort the segment infos by name */ /* Do a binary search */
CollSort (&D->Info->SegInfoByName, CompareSegInfoByName); int Lo = 0;
int Hi = (int) L->Count - 1;
while (Lo <= Hi) {
/* Mid of range */
int Cur = (Lo + Hi) / 2;
/* Get item */
LineInfoListEntry* CurItem = &L->List[Cur];
/* Found? */
if (CurItem->Addr > Addr) {
Hi = Cur - 1;
} else if (CurItem->Addr < Addr) {
Lo = Cur + 1;
} else {
/* Found */
return CurItem;
}
}
/* Not found */
return 0;
}
static int FindLineInfoByLine (Collection* LineInfos, cc65_line Line,
unsigned* Index)
/* Find the LineInfo for a given line number. The function returns true if the
* line 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 the line.
*/
{
/* Do a binary search */
int Lo = 0;
int Hi = (int) CollCount (LineInfos) - 1;
int Found = 0;
while (Lo <= Hi) {
/* Mid of range */
int Cur = (Lo + Hi) / 2;
/* Get item */
const LineInfo* CurItem = CollAt (LineInfos, Cur);
/* Found? */
if (Line > CurItem->Line) {
Lo = Cur + 1;
} else {
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;
}
}
}
/* Pass back the index. This is also the insert position */
*Index = Lo;
return Found;
}
static int FindSymInfoByName (Collection* SymInfos, const char* Name, unsigned* Index)
/* Find the SymInfo for a given file name. 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 (SymInfos) - 1;
int Found = 0;
while (Lo <= Hi) {
/* Mid of range */
int Cur = (Lo + Hi) / 2;
/* Get item */
SymInfo* CurItem = CollAt (SymInfos, Cur);
/* Compare */
int Res = strcmp (CurItem->Name, Name);
/* Found? */
if (Res < 0) {
Lo = Cur + 1;
} else {
Hi = Cur - 1;
/* Since we may have duplicates, repeat the search until we've
* the first item that has a match.
*/
if (Res == 0) {
Found = 1;
}
}
}
/* Pass back the index. This is also the insert position */
*Index = Lo;
return Found;
}
static int FindSymInfoByValue (Collection* SymInfos, long Value, unsigned* Index)
/* Find the SymInfo for a given value. The function returns true if the
* value 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 the given value.
*/
{
/* Do a binary search */
int Lo = 0;
int Hi = (int) CollCount (SymInfos) - 1;
int Found = 0;
while (Lo <= Hi) {
/* Mid of range */
int Cur = (Lo + Hi) / 2;
/* Get item */
SymInfo* CurItem = CollAt (SymInfos, Cur);
/* Found? */
if (Value > CurItem->Value) {
Lo = Cur + 1;
} else {
Hi = Cur - 1;
/* Since we may have duplicates, repeat the search until we've
* the first item that has a match.
*/
if (Value == CurItem->Value) {
Found = 1;
}
}
}
/* Pass back the index. This is also the insert position */
*Index = Lo;
return Found;
} }
@@ -3666,76 +3821,120 @@ static void ProcessLineInfo (InputData* D)
static LineInfoListEntry* FindLineInfoByAddr (const LineInfoList* L, cc65_addr Addr) static void ProcessModInfo (InputData* D)
/* Find the index of a LineInfo for a given address. Returns 0 if no such /* Postprocess module infos */
* lineinfo was found.
*/
{ {
/* Do a binary search */ unsigned I;
int Lo = 0;
int Hi = (int) L->Count - 1;
while (Lo <= Hi) {
/* Mid of range */ /* Walk over all scopes and resolve the ids */
int Cur = (Lo + Hi) / 2; for (I = 0; I < CollCount (&D->Info->ModInfoById); ++I) {
/* Get item */ /* Get this module info */
LineInfoListEntry* CurItem = &L->List[Cur]; ModInfo* M = CollAt (&D->Info->ModInfoById, I);
/* Found? */ /* Resolve the main file */
if (CurItem->Addr > Addr) { if (M->File.Id >= CollCount (&D->Info->FileInfoById)) {
Hi = Cur - 1; ParseError (D,
} else if (CurItem->Addr < Addr) { CC65_ERROR,
Lo = Cur + 1; "Invalid file id %u for module with id %u",
M->File.Id, M->Id);
M->File.Info = 0;
} else { } else {
/* Found */ M->File.Info = CollAt (&D->Info->FileInfoById, M->File.Id);
return CurItem; }
/* Resolve the library */
if (M->Lib.Id == CC65_INV_ID) {
M->Lib.Info = 0;
} else if (M->Lib.Id >= CollCount (&D->Info->LibInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid library id %u for module with id %u",
M->Lib.Id, M->Id);
M->Lib.Info = 0;
} else {
M->Lib.Info = CollAt (&D->Info->LibInfoById, M->Lib.Id);
} }
} }
/* Not found */ /* Sort the collection that contains the module info by name */
return 0; CollSort (&D->Info->ModInfoByName, CompareModInfoByName);
} }
static int FindLineInfoByLine (Collection* LineInfos, cc65_line Line, static void ProcessScopeInfo (InputData* D)
unsigned* Index) /* Postprocess scope infos */
/* Find the LineInfo for a given line number. The function returns true if the
* line 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 the line.
*/
{ {
/* Do a binary search */ unsigned I;
int Lo = 0;
int Hi = (int) CollCount (LineInfos) - 1;
int Found = 0;
while (Lo <= Hi) {
/* Mid of range */ /* Walk over all scopes. Resolve the ids and add the scopes to the list
int Cur = (Lo + Hi) / 2; * of scopes for a module.
*/
for (I = 0; I < CollCount (&D->Info->ScopeInfoById); ++I) {
/* Get item */ /* Get this scope info */
const LineInfo* CurItem = CollAt (LineInfos, Cur); ScopeInfo* S = CollAt (&D->Info->ScopeInfoById, I);
/* Found? */ /* Resolve the module */
if (Line > CurItem->Line) { if (S->Mod.Id >= CollCount (&D->Info->ModInfoById)) {
Lo = Cur + 1; ParseError (D,
CC65_ERROR,
"Invalid module id %u for scope with id %u",
S->Mod.Id, S->Id);
S->Mod.Info = 0;
} else { } else {
Hi = Cur - 1; S->Mod.Info = CollAt (&D->Info->ModInfoById, S->Mod.Id);
/* Since we may have duplicates, repeat the search until we've
* the first item that has a match. /* Add the scope to the list of scopes for this module */
*/ CollAppend (&S->Mod.Info->ScopeInfoByName, S);
if (Line == CurItem->Line) { }
Found = 1;
} /* Resolve the parent scope */
if (S->Parent.Id == CC65_INV_ID) {
S->Parent.Info = 0;
} else if (S->Parent.Id >= CollCount (&D->Info->ScopeInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid parent scope id %u for scope with id %u",
S->Parent.Id, S->Id);
S->Parent.Info = 0;
} else {
S->Parent.Info = CollAt (&D->Info->ScopeInfoById, S->Parent.Id);
}
/* Resolve the label */
if (S->Label.Id == CC65_INV_ID) {
S->Label.Info = 0;
} else if (S->Label.Id >= CollCount (&D->Info->SymInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid label id %u for scope with id %u",
S->Label.Id, S->Id);
S->Label.Info = 0;
} else {
S->Label.Info = CollAt (&D->Info->SymInfoById, S->Label.Id);
} }
} }
/* Pass back the index. This is also the insert position */ /* Walk over all modules and sort the scopes by name */
*Index = Lo; for (I = 0; I < CollCount (&D->Info->ModInfoById); ++I) {
return Found;
/* Get this module */
ModInfo* M = CollAt (&D->Info->ModInfoById, I);
/* Sort the scopes for this module by name */
CollSort (&M->ScopeInfoByName, CompareScopeInfoByName);
}
}
static void ProcessSegInfo (InputData* D)
/* Postprocess segment infos */
{
/* Sort the segment infos by name */
CollSort (&D->Info->SegInfoByName, CompareSegInfoByName);
} }
@@ -3822,156 +4021,6 @@ static void ProcessSymInfo (InputData* D)
static int FindSymInfoByName (Collection* SymInfos, const char* Name, unsigned* Index)
/* Find the SymInfo for a given file name. 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 (SymInfos) - 1;
int Found = 0;
while (Lo <= Hi) {
/* Mid of range */
int Cur = (Lo + Hi) / 2;
/* Get item */
SymInfo* CurItem = CollAt (SymInfos, Cur);
/* Compare */
int Res = strcmp (CurItem->Name, Name);
/* Found? */
if (Res < 0) {
Lo = Cur + 1;
} else {
Hi = Cur - 1;
/* Since we may have duplicates, repeat the search until we've
* the first item that has a match.
*/
if (Res == 0) {
Found = 1;
}
}
}
/* Pass back the index. This is also the insert position */
*Index = Lo;
return Found;
}
static int FindSymInfoByValue (Collection* SymInfos, long Value, unsigned* Index)
/* Find the SymInfo for a given value. The function returns true if the
* value 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 the given value.
*/
{
/* Do a binary search */
int Lo = 0;
int Hi = (int) CollCount (SymInfos) - 1;
int Found = 0;
while (Lo <= Hi) {
/* Mid of range */
int Cur = (Lo + Hi) / 2;
/* Get item */
SymInfo* CurItem = CollAt (SymInfos, Cur);
/* Found? */
if (Value > CurItem->Value) {
Lo = Cur + 1;
} else {
Hi = Cur - 1;
/* Since we may have duplicates, repeat the search until we've
* the first item that has a match.
*/
if (Value == CurItem->Value) {
Found = 1;
}
}
}
/* Pass back the index. This is also the insert position */
*Index = Lo;
return Found;
}
static void ProcessScopeInfo (InputData* D)
/* Postprocess scope infos */
{
unsigned I;
/* Walk over all scopes. Resolve the ids and add the scopes to the list
* of scopes for a module.
*/
for (I = 0; I < CollCount (&D->Info->ScopeInfoById); ++I) {
/* Get this scope info */
ScopeInfo* S = CollAt (&D->Info->ScopeInfoById, I);
/* Resolve the module */
if (S->Mod.Id >= CollCount (&D->Info->ModInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid module id %u for scope with id %u",
S->Mod.Id, S->Id);
S->Mod.Info = 0;
} else {
S->Mod.Info = CollAt (&D->Info->ModInfoById, S->Mod.Id);
/* Add the scope to the list of scopes for this module */
CollAppend (&S->Mod.Info->ScopeInfoByName, S);
}
/* Resolve the parent scope */
if (S->Parent.Id == CC65_INV_ID) {
S->Parent.Info = 0;
} else if (S->Parent.Id >= CollCount (&D->Info->ScopeInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid parent scope id %u for scope with id %u",
S->Parent.Id, S->Id);
S->Parent.Info = 0;
} else {
S->Parent.Info = CollAt (&D->Info->ScopeInfoById, S->Parent.Id);
}
/* Resolve the label */
if (S->Label.Id == CC65_INV_ID) {
S->Label.Info = 0;
} else if (S->Label.Id >= CollCount (&D->Info->SymInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid label id %u for scope with id %u",
S->Label.Id, S->Id);
S->Label.Info = 0;
} else {
S->Label.Info = CollAt (&D->Info->SymInfoById, S->Label.Id);
}
}
/* Walk over all modules and sort the scopes by name */
for (I = 0; I < CollCount (&D->Info->ModInfoById); ++I) {
/* Get this module */
ModInfo* M = CollAt (&D->Info->ModInfoById, I);
/* Sort the scopes for this module by name */
CollSort (&M->ScopeInfoByName, CompareScopeInfoByName);
}
}
/*****************************************************************************/ /*****************************************************************************/
/* Debug info files */ /* Debug info files */
/*****************************************************************************/ /*****************************************************************************/
@@ -4139,11 +4188,12 @@ CloseAndExit:
/* We do now have all the information from the input file. Do /* We do now have all the information from the input file. Do
* postprocessing. * postprocessing.
*/ */
ProcessSegInfo (&D);
ProcessFileInfo (&D); ProcessFileInfo (&D);
ProcessLineInfo (&D); ProcessLineInfo (&D);
ProcessSymInfo (&D); ProcessModInfo (&D);
ProcessScopeInfo (&D); ProcessScopeInfo (&D);
ProcessSegInfo (&D);
ProcessSymInfo (&D);
#if DEBUG #if DEBUG
/* Debug output */ /* Debug output */