/* Collections with other sort criteria */
Collection FileInfoByName; /* File infos 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 SymInfoByName; /* Symbol infos sorted by name */
Collection SymInfoByVal; /* Symbol infos sorted by value */
static int CompareScopeInfoByName (const void* L, const void* R)
/* Helper function to sort scope infos in a collection by name */
{
- /* Compare scope name */
- return strcmp (((const ScopeInfo*) L)->Name,
- ((const ScopeInfo*) R)->Name);
+ const ScopeInfo* Left = L;
+ const ScopeInfo* Right = R;
+
+ /* Compare scope name, then id */
+ int Res = strcmp (Left->Name, Right->Name);
+ if (Res == 0) {
+ Res = (int)Left->Id - (int)Right->Id;
+ }
+ return Res;
}
CollInit (&Info->FileInfoByName);
CollInit (&Info->ModInfoByName);
+ CollInit (&Info->ScopeInfoByName);
CollInit (&Info->SegInfoByName);
CollInit (&Info->SymInfoByName);
CollInit (&Info->SymInfoByVal);
/* Free the memory used by the other collections */
CollDone (&Info->FileInfoByName);
CollDone (&Info->ModInfoByName);
+ CollDone (&Info->ScopeInfoByName);
CollDone (&Info->SegInfoByName);
CollDone (&Info->SymInfoByName);
CollDone (&Info->SymInfoByVal);
case TOK_MODULE:
CollGrow (&D->Info->ModInfoById, D->IVal);
- CollGrow (&D->Info->ModInfoByName, D->IVal);
+ CollGrow (&D->Info->ModInfoByName, D->IVal);
break;
case TOK_SCOPE:
CollGrow (&D->Info->ScopeInfoById, D->IVal);
+ CollGrow (&D->Info->ScopeInfoByName, D->IVal);
break;
case TOK_SEGMENT:
CollGrow (&D->Info->SegInfoById, D->IVal);
- CollGrow (&D->Info->SegInfoByName, D->IVal);
+ CollGrow (&D->Info->SegInfoByName, D->IVal);
break;
case TOK_SPAN:
/* ... and remember it */
CollReplaceExpand (&D->Info->ScopeInfoById, S, Id);
+ CollAppend (&D->Info->ScopeInfoByName, S);
ErrorExit:
/* Entry point in case of errors */
+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,
unsigned* Index)
/* Find the SymInfo for a given file name. The function returns true if the
/* Sort the scopes for this module by name */
CollSort (&M->ScopeInfoByName, CompareScopeInfoByName);
}
+
+ /* Sort the scope infos */
+ CollSort (&D->Info->ScopeInfoByName, CompareScopeInfoByName);
}
{
DbgInfo* Info;
cc65_symbolinfo* D;
- ScopeInfo* S;
+ ScopeInfo* S;
unsigned I;
+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)
/* 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
static void CmdShowHelp (Collection* Args);
/* Print help for the show command */
+static void CmdShowChildScopes (Collection* Args);
+/* Show child scopes from the debug info file */
+
static void CmdShowLibrary (Collection* Args);
/* Show libraries from the debug info file */
/* Table with show commands */
static const CmdEntry ShowCmds[] = {
{
+ "childscopes",
+ "Show child scopes of other scopes.",
+ -2,
+ CmdShowChildScopes
+ }, {
"help",
"Show available subcommands",
1,
+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)
/* Show lines from the debug info file */
{
}
} else {
/* An invalid id may be a scope name */
- //S = cc65_scope_byname (Info, CollConstAt (Args, I));
- S = 0;
+ S = cc65_scope_byname (Info, CollConstAt (Args, I));
}
/* Output the list */