1
0
mirror of https://github.com/cc65/cc65.git synced 2024-10-01 15:54:59 +00:00

Postprocess file infos. New function cc65_sourceinfo_bymodule.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5145 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
uz 2011-08-10 14:08:18 +00:00
parent d9a35e9652
commit 9d2538f12b
2 changed files with 188 additions and 12 deletions

View File

@ -226,10 +226,7 @@ struct FileInfo {
unsigned Id; /* Id of file */ unsigned Id; /* Id of file */
unsigned long Size; /* Size of file */ unsigned long Size; /* Size of file */
unsigned long MTime; /* Modification time */ unsigned long MTime; /* Modification time */
union { Collection ModInfoByName; /* Modules in which this file is used */
unsigned Id; /* Id of module */
ModInfo* Info; /* Pointer to module info */
} Mod;
Collection LineInfoByLine; /* Line infos sorted by line */ Collection LineInfoByLine; /* Line infos sorted by line */
char Name[1]; /* Name of file with full path */ char Name[1]; /* Name of file with full path */
}; };
@ -608,13 +605,33 @@ static unsigned CollCount (const Collection* C)
static void CollMove (Collection* Source, Collection* Target)
/* Move all data from one collection to another. This function will first free
* the data in the target collection, and - after the move - clear the data
* from the source collection.
*/
{
/* Free the target collection data */
xfree (Target->Items);
/* Now copy the whole bunch over */
*Target = *Source;
/* Empty Source */
Source->Count = 0;
Source->Size = 0;
Source->Items = 0;
}
static void CollGrow (Collection* C, unsigned Size) static void CollGrow (Collection* C, unsigned Size)
/* Grow the collection C so it is able to hold Size items without a resize /* Grow the collection C so it is able to hold Size items without a resize
* being necessary. This can be called for performance reasons if the number * being necessary. This can be called for performance reasons if the number
* of items to be placed in the collection is known in advance. * of items to be placed in the collection is known in advance.
*/ */
{ {
CollEntry* NewItems; CollEntry* NewItems;
/* Ignore the call if the collection is already large enough */ /* Ignore the call if the collection is already large enough */
if (Size <= C->Size) { if (Size <= C->Size) {
@ -631,8 +648,8 @@ static void CollGrow (Collection* C, unsigned Size)
static void CollInsert (Collection* C, void* Item, unsigned Index) static void CollPrepareInsert (Collection* C, unsigned Index)
/* Insert the data at the given position in the collection */ /* Prepare for insertion of the data at a given position in the collection */
{ {
/* Check for invalid indices */ /* Check for invalid indices */
assert (Index <= C->Count); assert (Index <= C->Count);
@ -648,6 +665,15 @@ static void CollInsert (Collection* C, void* Item, unsigned Index)
memmove (C->Items+Index+1, C->Items+Index, (C->Count-Index) * sizeof (void*)); memmove (C->Items+Index+1, C->Items+Index, (C->Count-Index) * sizeof (void*));
} }
++C->Count; ++C->Count;
}
static void CollInsert (Collection* C, void* Item, unsigned Index)
/* Insert the data at the given position in the collection */
{
/* Prepare for insertion (free the given slot) */
CollPrepareInsert (C, Index);
/* Store the new item */ /* Store the new item */
C->Items[Index].Ptr = Item; C->Items[Index].Ptr = Item;
@ -655,6 +681,30 @@ static void CollInsert (Collection* C, void* Item, unsigned Index)
static void CollInsertId (Collection* C, unsigned Id, unsigned Index)
/* Insert the data at the given position in the collection */
{
/* Prepare for insertion (free the given slot) */
CollPrepareInsert (C, Index);
/* Store the new item */
C->Items[Index].Id = Id;
}
static void CollReplace (Collection* C, void* Item, unsigned Index)
/* Replace the item at the given position by a new one */
{
/* Check the index */
assert (Index < C->Count);
/* Replace the element */
C->Items[Index].Ptr = Item;
}
static void CollReplaceExpand (Collection* C, void* Item, unsigned Index) static void CollReplaceExpand (Collection* C, void* Item, unsigned Index)
/* If Index is a valid index for the collection, replace the item at this /* If Index is a valid index for the collection, replace the item at this
* position by the one passed. If the collection is too small, expand it, * position by the one passed. If the collection is too small, expand it,
@ -697,6 +747,15 @@ static void CollAppend (Collection* C, void* Item)
static void CollAppendId (Collection* C, unsigned Id)
/* Append an id to the end of the collection */
{
/* Insert the id at the end of the current list */
CollInsertId (C, Id, C->Count);
}
static void* CollAt (Collection* C, unsigned Index) static void* CollAt (Collection* C, unsigned Index)
/* Return the item at the given index */ /* Return the item at the given index */
{ {
@ -709,6 +768,18 @@ static void* CollAt (Collection* C, unsigned Index)
static unsigned CollIdAt (Collection* C, unsigned Index)
/* Return the id at the given index */
{
/* Check the index */
assert (Index < C->Count);
/* Return the element */
return C->Items[Index].Id;
}
static void* CollFirst (Collection* C) static void* CollFirst (Collection* C)
/* Return the first item in a collection */ /* Return the first item in a collection */
{ {
@ -882,6 +953,7 @@ static FileInfo* NewFileInfo (const StrBuf* Name)
FileInfo* F = xmalloc (sizeof (FileInfo) + SB_GetLen (Name)); FileInfo* F = xmalloc (sizeof (FileInfo) + SB_GetLen (Name));
/* Initialize it */ /* Initialize it */
InitCollection (&F->ModInfoByName);
InitCollection (&F->LineInfoByLine); InitCollection (&F->LineInfoByLine);
memcpy (F->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1); memcpy (F->Name, SB_GetConstBuf (Name), SB_GetLen (Name) + 1);
@ -1361,6 +1433,15 @@ static void CopyModInfo (cc65_moduledata* D, const ModInfo* M)
static int CompareModInfoByName (const void* L, const void* R)
/* Helper function to sort module infos in a collection by name */
{
/* Compare module name */
return strcmp (((const ModInfo*) L)->Name, ((const ModInfo*) R)->Name);
}
/*****************************************************************************/ /*****************************************************************************/
/* Scope info */ /* Scope info */
/*****************************************************************************/ /*****************************************************************************/
@ -1428,7 +1509,7 @@ static void CopyScopeInfo (cc65_scopedata* D, const ScopeInfo* S)
static int CompareScopeInfoByName (const void* L, const void* R) static int CompareScopeInfoByName (const void* L, const void* R)
/* Helper function to sort scope infos in a collection by name */ /* Helper function to sort scope infos in a collection by name */
{ {
/* Compare symbol name */ /* Compare scope name */
return strcmp (((const ScopeInfo*) L)->Name, return strcmp (((const ScopeInfo*) L)->Name,
((const ScopeInfo*) R)->Name); ((const ScopeInfo*) R)->Name);
} }
@ -2064,7 +2145,7 @@ static void ParseFile (InputData* D)
unsigned Id = 0; unsigned Id = 0;
unsigned long Size = 0; unsigned long Size = 0;
unsigned long MTime = 0; unsigned long MTime = 0;
unsigned ModId = CC65_INV_ID; Collection ModIds = COLLECTION_INITIALIZER;
StrBuf Name = STRBUF_INITIALIZER; StrBuf Name = STRBUF_INITIALIZER;
FileInfo* F; FileInfo* F;
enum { enum {
@ -2133,14 +2214,14 @@ static void ParseFile (InputData* D)
if (!IntConstFollows (D)) { if (!IntConstFollows (D)) {
goto ErrorExit; goto ErrorExit;
} }
ModId = D->IVal; CollAppendId (&ModIds, (unsigned) D->IVal);
InfoBits |= ibModId;
NextToken (D); NextToken (D);
if (D->Tok != TOK_PLUS) { if (D->Tok != TOK_PLUS) {
break; break;
} }
NextToken (D); NextToken (D);
} }
InfoBits |= ibModId;
break; break;
case TOK_NAME: case TOK_NAME:
@ -2194,12 +2275,13 @@ static void ParseFile (InputData* D)
F->Id = Id; F->Id = Id;
F->Size = Size; F->Size = Size;
F->MTime = MTime; F->MTime = MTime;
F->Mod.Id = ModId; CollMove (&F->ModInfoByName, &ModIds);
CollReplaceExpand (&D->Info->FileInfoById, F, Id); CollReplaceExpand (&D->Info->FileInfoById, F, Id);
CollAppend (&D->Info->FileInfoByName, F); CollAppend (&D->Info->FileInfoByName, F);
ErrorExit: ErrorExit:
/* Entry point in case of errors */ /* Entry point in case of errors */
DoneCollection (&ModIds);
SB_Done (&Name); SB_Done (&Name);
return; return;
} }
@ -3446,6 +3528,54 @@ static void ProcessSegInfo (InputData* D)
static void ProcessFileInfo (InputData* D) static void ProcessFileInfo (InputData* D)
/* Postprocess file infos */ /* Postprocess file infos */
{ {
/* Walk over all file infos and resolve the module ids */
unsigned I;
for (I = 0; I < CollCount (&D->Info->FileInfoById); ++I) {
/* Get this file info */
FileInfo* F = CollAt (&D->Info->FileInfoById, I);
/* Resolve the module ids */
unsigned J;
for (J = 0; I < CollCount (&F->ModInfoByName); ++J) {
/* Get the id of this module */
unsigned ModId = CollIdAt (&F->ModInfoByName, J);
if (ModId >= CollCount (&D->Info->ModInfoById)) {
ParseError (D,
CC65_ERROR,
"Invalid module id %u for file with id %u",
ModId, F->Id);
CollReplace (&F->ModInfoByName, 0, J);
} else {
/* Get a pointer to the module */
ModInfo* M = CollAt (&D->Info->ModInfoById, ModId);
/* Replace the id by the pointer */
CollReplace (&F->ModInfoByName, M, J);
/* Insert a backpointer into the module */
CollAppend (&M->FileInfoByName, F);
}
}
/* If we didn't have any errors, sort the modules by name */
if (D->Errors == 0) {
CollSort (&F->ModInfoByName, CompareModInfoByName);
}
}
/* Now walk over all modules and sort the file infos by name */
for (I = 0; I < CollCount (&D->Info->ModInfoById); ++I) {
/* Get this module info */
ModInfo* M = CollAt (&D->Info->ModInfoById, I);
/* Sort the files by name */
CollSort (&M->FileInfoByName, CompareFileInfoByName);
}
/* Sort the file infos by name, so we can do a binary search */ /* Sort the file infos by name, so we can do a binary search */
CollSort (&D->Info->FileInfoByName, CompareFileInfoByName); CollSort (&D->Info->FileInfoByName, CompareFileInfoByName);
} }
@ -4419,6 +4549,45 @@ cc65_sourceinfo* cc65_sourceinfo_byid (cc65_dbginfo Handle, unsigned Id)
cc65_sourceinfo* cc65_sourceinfo_bymodule (cc65_dbginfo Handle, unsigned ModId)
/* Return information about the source files used to build a module. The
* function returns NULL if the module id is invalid (no such module) and
* otherwise a cc65_sourceinfo structure with one entry per source file.
*/
{
DbgInfo* Info;
ModInfo* M;
cc65_sourceinfo* D;
unsigned I;
/* Check the parameter */
assert (Handle != 0);
/* The handle is actually a pointer to a debug info struct */
Info = (DbgInfo*) Handle;
/* Check if the module id is valid */
if (ModId >= CollCount (&Info->ModInfoById)) {
return 0;
}
/* Get a pointer to the module info */
M = CollAt (&Info->ModInfoById, ModId);
/* Allocate memory for the data structure returned to the caller */
D = new_cc65_sourceinfo (CollCount (&M->FileInfoByName));
/* Fill in the data */
for (I = 0; I < CollCount (&M->FileInfoByName); ++I) {
CopyFileInfo (D->data + I, CollAt (&M->FileInfoByName, I));
}
/* Return the result */
return D;
}
void cc65_free_sourceinfo (cc65_dbginfo Handle, cc65_sourceinfo* Info) void cc65_free_sourceinfo (cc65_dbginfo Handle, cc65_sourceinfo* Info)
/* Free a source info record */ /* Free a source info record */
{ {

View File

@ -275,6 +275,13 @@ cc65_sourceinfo* cc65_sourceinfo_byid (cc65_dbginfo handle, unsigned id);
* source file information. * source file information.
*/ */
cc65_sourceinfo* cc65_sourceinfo_bymodule (cc65_dbginfo handle,
unsigned module_id);
/* Return information about the source files used to build a module. The
* function returns NULL if the module id is invalid (no such module) and
* otherwise a cc65_sourceinfo structure with one entry per source file.
*/
void cc65_free_sourceinfo (cc65_dbginfo handle, cc65_sourceinfo* info); void cc65_free_sourceinfo (cc65_dbginfo handle, cc65_sourceinfo* info);
/* Free a source info record */ /* Free a source info record */