Added cc65_scope_byname.
git-svn-id: svn://svn.cc65.org/cc65/trunk@5198 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -190,6 +190,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 ModInfoByName; /* Module info sorted by name */
|
||||||
|
Collection ScopeInfoByName;/* Scope infos 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 */
|
||||||
@@ -1340,9 +1341,15 @@ 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 scope name */
|
const ScopeInfo* Left = L;
|
||||||
return strcmp (((const ScopeInfo*) L)->Name,
|
const ScopeInfo* Right = R;
|
||||||
((const ScopeInfo*) R)->Name);
|
|
||||||
|
/* Compare scope name, then id */
|
||||||
|
int Res = strcmp (Left->Name, Right->Name);
|
||||||
|
if (Res == 0) {
|
||||||
|
Res = (int)Left->Id - (int)Right->Id;
|
||||||
|
}
|
||||||
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1833,6 +1840,7 @@ static DbgInfo* NewDbgInfo (const char* FileName)
|
|||||||
|
|
||||||
CollInit (&Info->FileInfoByName);
|
CollInit (&Info->FileInfoByName);
|
||||||
CollInit (&Info->ModInfoByName);
|
CollInit (&Info->ModInfoByName);
|
||||||
|
CollInit (&Info->ScopeInfoByName);
|
||||||
CollInit (&Info->SegInfoByName);
|
CollInit (&Info->SegInfoByName);
|
||||||
CollInit (&Info->SymInfoByName);
|
CollInit (&Info->SymInfoByName);
|
||||||
CollInit (&Info->SymInfoByVal);
|
CollInit (&Info->SymInfoByVal);
|
||||||
@@ -1894,6 +1902,7 @@ static void FreeDbgInfo (DbgInfo* Info)
|
|||||||
/* Free the memory used by the other collections */
|
/* Free the memory used by the other collections */
|
||||||
CollDone (&Info->FileInfoByName);
|
CollDone (&Info->FileInfoByName);
|
||||||
CollDone (&Info->ModInfoByName);
|
CollDone (&Info->ModInfoByName);
|
||||||
|
CollDone (&Info->ScopeInfoByName);
|
||||||
CollDone (&Info->SegInfoByName);
|
CollDone (&Info->SegInfoByName);
|
||||||
CollDone (&Info->SymInfoByName);
|
CollDone (&Info->SymInfoByName);
|
||||||
CollDone (&Info->SymInfoByVal);
|
CollDone (&Info->SymInfoByVal);
|
||||||
@@ -2481,16 +2490,17 @@ static void ParseInfo (InputData* D)
|
|||||||
|
|
||||||
case TOK_MODULE:
|
case TOK_MODULE:
|
||||||
CollGrow (&D->Info->ModInfoById, D->IVal);
|
CollGrow (&D->Info->ModInfoById, D->IVal);
|
||||||
CollGrow (&D->Info->ModInfoByName, D->IVal);
|
CollGrow (&D->Info->ModInfoByName, D->IVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_SCOPE:
|
case TOK_SCOPE:
|
||||||
CollGrow (&D->Info->ScopeInfoById, D->IVal);
|
CollGrow (&D->Info->ScopeInfoById, D->IVal);
|
||||||
|
CollGrow (&D->Info->ScopeInfoByName, D->IVal);
|
||||||
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);
|
CollGrow (&D->Info->SegInfoByName, D->IVal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOK_SPAN:
|
case TOK_SPAN:
|
||||||
@@ -3124,6 +3134,7 @@ static void ParseScope (InputData* D)
|
|||||||
|
|
||||||
/* ... and remember it */
|
/* ... and remember it */
|
||||||
CollReplaceExpand (&D->Info->ScopeInfoById, S, Id);
|
CollReplaceExpand (&D->Info->ScopeInfoById, S, Id);
|
||||||
|
CollAppend (&D->Info->ScopeInfoByName, S);
|
||||||
|
|
||||||
ErrorExit:
|
ErrorExit:
|
||||||
/* Entry point in case of errors */
|
/* Entry point in case of errors */
|
||||||
@@ -3900,6 +3911,50 @@ static SegInfo* FindSegInfoByName (Collection* SegInfos, const char* Name)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static int FindScopeInfoByName (const Collection* ScopeInfos, const char* Name,
|
||||||
|
unsigned* Index)
|
||||||
|
/* Find the ScopeInfo for a given scope 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 (ScopeInfos) - 1;
|
||||||
|
int Found = 0;
|
||||||
|
while (Lo <= Hi) {
|
||||||
|
|
||||||
|
/* Mid of range */
|
||||||
|
int Cur = (Lo + Hi) / 2;
|
||||||
|
|
||||||
|
/* Get item */
|
||||||
|
const ScopeInfo* CurItem = CollConstAt (ScopeInfos, 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 FindSymInfoByName (const Collection* SymInfos, const char* Name,
|
static int FindSymInfoByName (const Collection* SymInfos, const char* Name,
|
||||||
unsigned* Index)
|
unsigned* Index)
|
||||||
/* Find the SymInfo for a given file name. The function returns true if the
|
/* Find the SymInfo for a given file name. The function returns true if the
|
||||||
@@ -4273,6 +4328,9 @@ static void ProcessScopeInfo (InputData* D)
|
|||||||
/* Sort the scopes for this module by name */
|
/* Sort the scopes for this module by name */
|
||||||
CollSort (&M->ScopeInfoByName, CompareScopeInfoByName);
|
CollSort (&M->ScopeInfoByName, CompareScopeInfoByName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sort the scope infos */
|
||||||
|
CollSort (&D->Info->ScopeInfoByName, CompareScopeInfoByName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -5478,7 +5536,7 @@ const cc65_symbolinfo* cc65_symbol_byscope (cc65_dbginfo Handle, unsigned ScopeI
|
|||||||
{
|
{
|
||||||
DbgInfo* Info;
|
DbgInfo* Info;
|
||||||
cc65_symbolinfo* D;
|
cc65_symbolinfo* D;
|
||||||
ScopeInfo* S;
|
ScopeInfo* S;
|
||||||
unsigned I;
|
unsigned I;
|
||||||
|
|
||||||
|
|
||||||
@@ -5703,6 +5761,60 @@ const cc65_scopeinfo* cc65_scope_bymodule (cc65_dbginfo Handle, unsigned ModId)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const cc65_scopeinfo* cc65_scope_byname (cc65_dbginfo Handle, const char* Name)
|
||||||
|
/* Return the list of scopes with a given name. Returns NULL if no scope with
|
||||||
|
* the given name was found, otherwise a non empty scope list.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
DbgInfo* Info;
|
||||||
|
unsigned Index;
|
||||||
|
ScopeInfo* S;
|
||||||
|
cc65_scopeinfo* D;
|
||||||
|
unsigned Count;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
|
||||||
|
/* Check the parameter */
|
||||||
|
assert (Handle != 0);
|
||||||
|
|
||||||
|
/* The handle is actually a pointer to a debug info struct */
|
||||||
|
Info = (DbgInfo*) Handle;
|
||||||
|
|
||||||
|
/* Search for the first item with the given name */
|
||||||
|
if (!FindScopeInfoByName (&Info->ScopeInfoByName, Name, &Index)) {
|
||||||
|
/* Not found */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Count scopes with this name */
|
||||||
|
Count = 1;
|
||||||
|
I = Index;
|
||||||
|
while (1) {
|
||||||
|
if (++I >= CollCount (&Info->ScopeInfoByName)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
S = CollAt (&Info->ScopeInfoByName, I);
|
||||||
|
if (strcmp (S->Name, Name) != 0) {
|
||||||
|
/* Next symbol has another name */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++Count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for the data structure returned to the caller */
|
||||||
|
D = new_cc65_scopeinfo (Count);
|
||||||
|
|
||||||
|
/* Fill in the data */
|
||||||
|
for (I = 0; I < Count; ++I, ++Index) {
|
||||||
|
CopyScopeInfo (D->data + I, CollConstAt (&Info->ScopeInfoByName, Index));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result */
|
||||||
|
return D;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const cc65_scopeinfo* cc65_childscopes_byid (cc65_dbginfo Handle, unsigned Id)
|
const cc65_scopeinfo* cc65_childscopes_byid (cc65_dbginfo Handle, unsigned Id)
|
||||||
/* Return the direct child scopes of a scope with a given id. The function
|
/* Return the direct child scopes of a scope with a given id. The function
|
||||||
* returns NULL if no scope with this id was found, otherwise a list of the
|
* returns NULL if no scope with this id was found, otherwise a list of the
|
||||||
|
|||||||
@@ -510,6 +510,11 @@ const cc65_scopeinfo* cc65_scope_bymodule (cc65_dbginfo handle, unsigned module_
|
|||||||
* scope with the given id was found.
|
* scope with the given id was found.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const cc65_scopeinfo* cc65_scope_byname (cc65_dbginfo handle, const char* name);
|
||||||
|
/* Return the list of scopes with a given name. Returns NULL if no scope with
|
||||||
|
* the given name was found, otherwise a non empty scope list.
|
||||||
|
*/
|
||||||
|
|
||||||
const cc65_scopeinfo* cc65_childscopes_byid (cc65_dbginfo handle, unsigned id);
|
const cc65_scopeinfo* cc65_childscopes_byid (cc65_dbginfo handle, unsigned id);
|
||||||
/* Return the direct child scopes of a scope with a given id. The function
|
/* Return the direct child scopes of a scope with a given id. The function
|
||||||
* returns NULL if no scope with this id was found, otherwise a list of the
|
* returns NULL if no scope with this id was found, otherwise a list of the
|
||||||
|
|||||||
@@ -72,6 +72,9 @@ static void CmdShow (Collection* Args);
|
|||||||
static void CmdShowHelp (Collection* Args);
|
static void CmdShowHelp (Collection* Args);
|
||||||
/* Print help for the show command */
|
/* Print help for the show command */
|
||||||
|
|
||||||
|
static void CmdShowChildScopes (Collection* Args);
|
||||||
|
/* Show child scopes from the debug info file */
|
||||||
|
|
||||||
static void CmdShowLibrary (Collection* Args);
|
static void CmdShowLibrary (Collection* Args);
|
||||||
/* Show libraries from the debug info file */
|
/* Show libraries from the debug info file */
|
||||||
|
|
||||||
@@ -165,6 +168,11 @@ static const CmdEntry MainCmds[] = {
|
|||||||
/* Table with show commands */
|
/* Table with show commands */
|
||||||
static const CmdEntry ShowCmds[] = {
|
static const CmdEntry ShowCmds[] = {
|
||||||
{
|
{
|
||||||
|
"childscopes",
|
||||||
|
"Show child scopes of other scopes.",
|
||||||
|
-2,
|
||||||
|
CmdShowChildScopes
|
||||||
|
}, {
|
||||||
"help",
|
"help",
|
||||||
"Show available subcommands",
|
"Show available subcommands",
|
||||||
1,
|
1,
|
||||||
@@ -763,6 +771,52 @@ static void CmdShowHelp (Collection* Args attribute ((unused)))
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void CmdShowChildScopes (Collection* Args)
|
||||||
|
/* Show child scopes from the debug info file */
|
||||||
|
{
|
||||||
|
const cc65_scopeinfo* S;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Be sure a file is loaded */
|
||||||
|
if (!FileIsLoaded ()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the header */
|
||||||
|
PrintScopeHeader ();
|
||||||
|
|
||||||
|
/* Output child scopes for all arguments */
|
||||||
|
for (I = 0; I < CollCount (Args); ++I) {
|
||||||
|
|
||||||
|
/* Parse the argument */
|
||||||
|
unsigned Id;
|
||||||
|
unsigned IdType = ScopeId;
|
||||||
|
if (GetId (CollConstAt (Args, I), &Id, &IdType)) {
|
||||||
|
/* Fetch list depending on type */
|
||||||
|
switch (IdType) {
|
||||||
|
case ScopeId:
|
||||||
|
S = cc65_childscopes_byid (Info, Id);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
S = 0;
|
||||||
|
PrintLine ("Invalid id type");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Invalid id */
|
||||||
|
S = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Output the list */
|
||||||
|
if (S) {
|
||||||
|
PrintScopes (S);
|
||||||
|
cc65_free_scopeinfo (Info, S);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void CmdShowLine (Collection* Args)
|
static void CmdShowLine (Collection* Args)
|
||||||
/* Show lines from the debug info file */
|
/* Show lines from the debug info file */
|
||||||
{
|
{
|
||||||
@@ -982,8 +1036,7 @@ static void CmdShowScope (Collection* Args)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* An invalid id may be a scope name */
|
/* An invalid id may be a scope name */
|
||||||
//S = cc65_scope_byname (Info, CollConstAt (Args, I));
|
S = cc65_scope_byname (Info, CollConstAt (Args, I));
|
||||||
S = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Output the list */
|
/* Output the list */
|
||||||
|
|||||||
Reference in New Issue
Block a user