]> git.sur5r.net Git - cc65/commitdiff
Added cc65_scope_byname.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 17 Aug 2011 21:20:10 +0000 (21:20 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 17 Aug 2011 21:20:10 +0000 (21:20 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@5198 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/dbginfo/dbginfo.c
src/dbginfo/dbginfo.h
src/dbginfo/dbgsh.c

index 924cf676e5433678e20d27516a633e07c3f0b3b5..23d8302c7c1f80a42e0d389b8dab6c7a9194d2c2 100644 (file)
@@ -190,6 +190,7 @@ struct DbgInfo {
     /* 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 */
@@ -1340,9 +1341,15 @@ static void CopyScopeInfo (cc65_scopedata* D, const ScopeInfo* S)
 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;
 }
 
 
@@ -1833,6 +1840,7 @@ static DbgInfo* NewDbgInfo (const char* FileName)
 
     CollInit (&Info->FileInfoByName);
     CollInit (&Info->ModInfoByName);
+    CollInit (&Info->ScopeInfoByName);
     CollInit (&Info->SegInfoByName);
     CollInit (&Info->SymInfoByName);
     CollInit (&Info->SymInfoByVal);
@@ -1894,6 +1902,7 @@ static void FreeDbgInfo (DbgInfo* Info)
     /* 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);
@@ -2481,16 +2490,17 @@ static void ParseInfo (InputData* D)
 
             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:
@@ -3124,6 +3134,7 @@ static void ParseScope (InputData* D)
 
     /* ... and remember it */
     CollReplaceExpand (&D->Info->ScopeInfoById, S, Id);
+    CollAppend (&D->Info->ScopeInfoByName, S);
 
 ErrorExit:
     /* 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,
                               unsigned* Index)
 /* 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 */
         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;
     cc65_symbolinfo*    D;
-    ScopeInfo*          S;                 
+    ScopeInfo*          S;
     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)
 /* 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
index e8246728b25d1de3b2c4af7360a5ae4b77f2e8a4..0e28225b3d589b1bf34fc4a7f2bdfd0798e4dcff 100644 (file)
@@ -510,6 +510,11 @@ const cc65_scopeinfo* cc65_scope_bymodule (cc65_dbginfo handle, unsigned module_
  * 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);
 /* 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
index f5c49dd4f87442e05fb6910a7346ee25e348fd1d..7e0716a3f66917edf2b975f48490acf68cfc90c9 100644 (file)
@@ -72,6 +72,9 @@ static void CmdShow (Collection* Args);
 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 */
 
@@ -165,6 +168,11 @@ static const CmdEntry MainCmds[] = {
 /* Table with show commands */
 static const CmdEntry ShowCmds[] = {
     {
+        "childscopes",
+        "Show child scopes of other scopes.",
+        -2,
+        CmdShowChildScopes
+    }, {
         "help",
         "Show available subcommands",
         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)
 /* Show lines from the debug info file */
 {
@@ -982,8 +1036,7 @@ static void CmdShowScope (Collection* Args)
                 }
             } 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 */