]> git.sur5r.net Git - cc65/commitdiff
New function cc65_symbol_inrange. Fixed an error in cc65_symbol_byname.
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 11 Aug 2010 19:31:30 +0000 (19:31 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Wed, 11 Aug 2010 19:31:30 +0000 (19:31 +0000)
Restructured the dbgtest.c source.

git-svn-id: svn://svn.cc65.org/cc65/trunk@4806 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/dbginfo/dbginfo.c
src/dbginfo/dbginfo.h
src/dbginfo/dbgtest.c

index c8b4c788601f43dd8dcbef0f90d6e5dbd883b1b5..a7897240878653e683dec2058c978ffc313157d0 100644 (file)
@@ -89,8 +89,9 @@ struct DbgInfo {
     Collection  SegInfoById;            /* Segment infos sorted by id */
     Collection  FileInfoByName;         /* File infos sorted by name */
     Collection  FileInfoById;           /* File infos sorted by id */
-    Collection  LineInfoByAddr;         /* Line information sorted by address */
-    Collection  SymInfoByName;          /* Symbol information sorted by name */
+    Collection  LineInfoByAddr;         /* Line infos sorted by address */
+    Collection  SymInfoByName;          /* Symbol infos sorted by name */
+    Collection  SymInfoByVal;           /* Symbol infos sorted by value */
 };
 
 /* Input tokens */
@@ -880,13 +881,30 @@ static void FreeSymInfo (SymInfo* S)
 static int CompareSymInfoByName (const void* L, const void* R)
 /* Helper function to sort symbol infos in a collection by name */
 {
-    /* Sort by file name */
+    /* Sort by symbol name */
     return strcmp (((const SymInfo*) L)->SymName,
                    ((const SymInfo*) R)->SymName);
 }
 
 
 
+static int CompareSymInfoByVal (const void* L, const void* R)
+/* Helper function to sort symbol infos in a collection by value */
+{
+    /* Sort by symbol value. If both are equal, sort by symbol name so it
+     * looks nice when such a list is returned.
+     */
+    if (((const SymInfo*) L)->Value > ((const SymInfo*) R)->Value) {
+        return 1;
+    } else if (((const SymInfo*) L)->Value < ((const SymInfo*) R)->Value) {
+        return -1;
+    } else {
+        return CompareSymInfoByName (L, R);
+    }
+}
+
+
+
 /*****************************************************************************/
 /*                                Debug info                                 */
 /*****************************************************************************/
@@ -906,6 +924,7 @@ static DbgInfo* NewDbgInfo (void)
     InitCollection (&Info->FileInfoById);
     InitCollection (&Info->LineInfoByAddr);
     InitCollection (&Info->SymInfoByName);
+    InitCollection (&Info->SymInfoByVal);
 
     /* Return it */
     return Info;
@@ -940,6 +959,7 @@ static void FreeDbgInfo (DbgInfo* Info)
         FreeSymInfo (CollAt (&Info->SymInfoByName, I));
     }
     DoneCollection (&Info->SymInfoByName);
+    DoneCollection (&Info->SymInfoByVal);
 
     /* Free the structure itself */
     xfree (Info);
@@ -975,6 +995,18 @@ static void CopyLineInfo (cc65_linedata* D, const LineInfo* L)
 
 
 
+static void CopySymInfo (cc65_symboldata* D, const SymInfo* S)
+/* Copy data from a SymInfo struct to the cc65_symboldata struct returned to
+ * the caller.
+ */
+{
+    D->symbol_name  = S->SymName;
+    D->symbol_type  = S->Type;
+    D->symbol_value = S->Value;
+}
+
+
+
 static void ParseError (InputData* D, cc65_error_severity Type, const char* Msg, ...)
 /* Call the user supplied parse error function */
 {
@@ -1874,6 +1906,7 @@ static void ParseSym (InputData* D)
     /* Create the symbol info and remember it */
     S = NewSymInfo (&SymName, Value, Type);
     CollAppend (&D->Info->SymInfoByName, S);
+    CollAppend (&D->Info->SymInfoByVal, S);
 
 ErrorExit:
     /* Entry point in case of errors */
@@ -2348,9 +2381,11 @@ static void ProcessSymInfo (InputData* D)
 {
     /* Get pointers to the symbol info collections */
     Collection* SymInfoByName = &D->Info->SymInfoByName;
+    Collection* SymInfoByVal  = &D->Info->SymInfoByVal;
 
-    /* Sort the symbol infos by name */
+    /* Sort the symbol infos */
     CollSort (SymInfoByName, CompareSymInfoByName);
+    CollSort (SymInfoByVal,  CompareSymInfoByVal);
 }
 
 
@@ -2398,6 +2433,46 @@ static int FindSymInfoByName (Collection* SymInfos, const char* SymName, int* In
 
 
 
+static int FindSymInfoByValue (Collection* SymInfos, long Value, int* 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;
+}
+
+
+
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
@@ -2806,17 +2881,88 @@ cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo Handle, const char* Name)
 
     /* Fill in the data */
     D->count = Count;
-    while (Count--) {
+    for (I = 0; I < Count; ++I) {
+        /* Copy the data */
+        CopySymInfo (D->data + I, CollAt (SymInfoByName, Index++));
+    }
 
-        /* Get this item */
-        const SymInfo* S = CollAt (SymInfoByName, Index);
+    /* Return the result */
+    return D;
+}
+
+
+
+cc65_symbolinfo* cc65_symbol_inrange (cc65_dbginfo Handle, cc65_addr Start, cc65_addr End)
+/* Return a list of labels in the given range. End is inclusive. The function
+ * return NULL if no symbols withing the given range are found. Non label
+ * symbols are ignored and not returned.
+ */
+{
+    DbgInfo*            Info;
+    Collection*         SymInfoByVal;
+    Collection          SymInfoList = COLLECTION_INITIALIZER;
+    cc65_symbolinfo*    D;
+    unsigned            I;
+    int                 Index;
+
+    /* Check the parameter */
+    assert (Handle != 0);
+
+    /* The handle is actually a pointer to a debug info struct */
+    Info = (DbgInfo*) Handle;
 
+    /* Get a pointer to the symbol list */
+    SymInfoByVal = &Info->SymInfoByVal;
+
+    /* Search for the symbol. Because we're searching for a range, we cannot
+     * make use of the function result.
+     */
+    FindSymInfoByValue (SymInfoByVal, Start, &Index);
+
+    /* Start from the given index, check all symbols until the end address is
+     * reached. Place all symbols into SymInfoList for later.
+     */
+    for (I = Index; I < CollCount (SymInfoByVal); ++I) {
+
+        /* Get the item */
+        SymInfo* Item = CollAt (SymInfoByVal, I);
+
+        /* The collection is sorted by address, so if we get a value larger
+         * than the end address, we're done.
+         */
+        if (Item->Value > (long) End) {
+            break;
+        }
+
+        /* Ignore non-labels */
+        if (Item->Type != CC65_SYM_LABEL) {
+            continue;
+        }
+
+        /* Ok, remember this one */
+        CollAppend (&SymInfoList, Item);
+    }
+
+    /* If we don't have any labels within the range, bail out. No memory has
+     * been allocated for SymInfoList.
+     */
+    if (CollCount (&SymInfoList) == 0) {
+        return 0;
+    }
+
+    /* Allocate memory for the data structure returned to the caller */
+    D = xmalloc (sizeof (*D) + (CollCount (&SymInfoList)- 1) * sizeof (D->data[0]));
+
+    /* Fill in the data */
+    D->count = CollCount (&SymInfoList);
+    for (I = 0; I < CollCount (&SymInfoList); ++I) {
         /* Copy the data */
-        D->data[I].symbol_name  = S->SymName;
-        D->data[I].symbol_type  = S->Type;
-        D->data[I].symbol_value = S->Value;
+        CopySymInfo (D->data + I, CollAt (&SymInfoList, I));
     }
 
+    /* Free the collection */
+    DoneCollection (&SymInfoList);
+
     /* Return the result */
     return D;
 }
index 699091385f38cf29455dcc225ab04ef74a6e3d3a..92d06216c6f88ddf8ad4dd3fd4e7667ca4da7770 100644 (file)
@@ -207,11 +207,18 @@ cc65_segmentinfo* cc65_get_segmentlist (cc65_dbginfo handle);
 void cc65_free_segmentinfo (cc65_dbginfo handle, cc65_segmentinfo* info);
 /* Free a segment info record */
 
-cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo Handle, const char* Name);
+cc65_symbolinfo* cc65_symbol_byname (cc65_dbginfo handle, const char* name);
 /* Return a list of symbols with a given name. The function returns NULL if
  * no symbol with this name was found.
  */
-                                                                            
+
+cc65_symbolinfo* cc65_symbol_inrange (cc65_dbginfo handle,
+                                      cc65_addr start, cc65_addr end);
+/* Return a list of labels in the given range. end is inclusive. The function
+ * return NULL if no symbols withing the given range are found. Non label
+ * symbols are ignored and not returned.
+ */
+
 void cc65_free_symbolinfo (cc65_dbginfo Handle, cc65_symbolinfo* Info);
 /* Free a symbol info record */
 
index 82b5cced039caded1c18d75cc2131ca66e032184..da4af88200bb7aa5877dfc5bf6937b6b3d12eb03 100644 (file)
@@ -61,6 +61,101 @@ static void Usage (void)
 
 
 
+static void PrintSourceData (const cc65_sourcedata* D)
+/* Print the data for one source file */
+{
+    printf ("  %s\n", D->source_name);
+}
+
+
+
+static void PrintSegmentData (const cc65_segmentdata* D)
+/* Print the data for one segment */
+{
+    printf ("  %-20s $%06lX $%04lX",
+            D->segment_name,
+            (unsigned long) D->segment_start,
+            (unsigned long) D->segment_size);
+    if (D->output_name) {
+        printf ("  %-20s $%06lX", D->output_name, D->output_offs);
+    }
+    putchar ('\n');
+}
+
+
+
+static void PrintLineData (const cc65_linedata* D)
+/* Print the data for one source line */
+{
+    printf ("  %s(%lu)", D->source_name, (unsigned long) D->source_line);
+    if (D->output_name) {
+        printf (" [%s($%06lX)]", D->output_name, D->output_offs);
+    }
+    putchar ('\n');
+}
+
+
+
+static void PrintSymbolData (const cc65_symboldata* D)
+/* Print the data for one symbol */
+{
+    printf ("  %-20s = %04lX\n", D->symbol_name, D->symbol_value);
+}
+
+
+
+static void PrintSourceInfo (cc65_sourceinfo* Sources)
+/* Output the list of source files */
+{
+    unsigned I;
+    if (Sources) {
+        for (I = 0; I < Sources->count; ++I) {
+            PrintSourceData (Sources->data + I);
+        }
+    }
+}
+
+
+
+static void PrintSegmentInfo (cc65_segmentinfo* Segments)
+/* Output the list of segments */
+{
+    unsigned I;
+    if (Segments) {
+        for (I = 0; I < Segments->count; ++I) {
+            PrintSegmentData (Segments->data + I);
+        }
+    }
+}
+
+
+
+static void PrintLineInfo (const cc65_lineinfo* Info)
+/* Print a list of line infos */
+{
+    unsigned I;
+    if (Info) {
+        for (I = 0; I < Info->count; ++I) {
+            PrintLineData (Info->data + I);
+        }
+    }
+}
+
+
+
+static void PrintSymbolInfo (const cc65_symbolinfo* Symbols)
+/* Print a list of symbol infos */
+{
+    unsigned I;
+    if (Symbols) {
+        for (I = 0; I < Symbols->count; ++I) {
+            PrintSymbolData (Symbols->data + I);
+        }
+    }
+}
+
+
+
 int main (int argc, char** argv)
 {
     const char*         Input;
@@ -69,8 +164,7 @@ int main (int argc, char** argv)
     cc65_segmentinfo*   Segments;
     cc65_lineinfo*      Lines;
     cc65_symbolinfo*    Symbols;
-    unsigned            I;
-    unsigned long       Addr;
+    cc65_addr           Addr;
 
 
     /* Input file is argument */
@@ -90,26 +184,13 @@ int main (int argc, char** argv)
     /* Output a list of files */
     printf ("List of source files:\n");
     Sources = cc65_get_sourcelist (Info);
-    for (I = 0; I < Sources->count; ++I) {
-        printf ("  %s\n", Sources->data[I].source_name);
-    }
+    PrintSourceInfo (Sources);
     cc65_free_sourceinfo (Info, Sources);
 
     /* Output a list of segments */
     printf ("Segments processed when linking:\n");
     Segments = cc65_get_segmentlist (Info);
-    for (I = 0; I < Segments->count; ++I) {
-        printf ("  %-20s $%06lX $%04lX",
-                Segments->data[I].segment_name,
-                (unsigned long) Segments->data[I].segment_start,
-                (unsigned long) Segments->data[I].segment_size);
-        if (Segments->data[I].output_name) {
-            printf ("  %-20s $%06lX",
-                    Segments->data[I].output_name,
-                    Segments->data[I].output_offs);
-        }
-        putchar ('\n');
-    }
+    PrintSegmentInfo (Segments);
     cc65_free_segmentinfo (Info, Segments);
 
     /* Check one line */
@@ -118,9 +199,7 @@ int main (int argc, char** argv)
     if (Lines == 0) {
         printf ("  Not found\n");
     } else {
-        printf ("  Code range is $%04X-$%04X\n",
-                Lines->data[0].line_start,
-                Lines->data[0].line_end);
+        PrintLineInfo (Lines);
         cc65_free_lineinfo (Info, Lines);
     }
 
@@ -131,23 +210,8 @@ int main (int argc, char** argv)
     for (Addr = 0; Addr < 0x10000; ++Addr) {
         Lines = cc65_lineinfo_byaddr (Info, Addr);
         if (Lines) {
-            unsigned I;
-            printf ("  $%04lX: ", Addr);
-            for (I = 0; I < Lines->count; ++I) {
-                if (I > 0) {
-                    printf (", ");
-                }
-                printf ("%s(%lu)",
-                        Lines->data[I].source_name,
-                        (unsigned long) Lines->data[I].source_line);
-                if (Lines->data[I].output_name) {
-                    printf ("  %s($%06lX)",
-                            Lines->data[I].output_name,
-                            Lines->data[I].output_offs);
-
-                }
-            }
-            printf ("\n");
+            printf ("  $%04lX:\n", (unsigned long) Addr);
+            PrintLineInfo (Lines);
             cc65_free_lineinfo (Info, Lines);
         }
     }
@@ -157,16 +221,23 @@ int main (int argc, char** argv)
     Symbols = cc65_symbol_byname (Info, "_main");
     if (Symbols == 0) {
         printf ("  Not found\n");
-    } else {                             
-        unsigned I;
-        for (I = 0; I < Symbols->count; ++I) {
-            printf ("  %-20s = %04lX\n", 
-                    Symbols->data[I].symbol_name,
-                    Symbols->data[I].symbol_value);
-        }
+        Addr = 0x800;
+    } else {
+        PrintSymbolInfo (Symbols);
+        Addr = Symbols->data[0].symbol_value;
         cc65_free_symbolinfo (Info, Symbols);
     }
 
+    /* Print symbols for the next $100 bytes starting from main (or 0x800) */
+    printf ("Requesting labels for $%04lX-$%04lX:\n",           
+            (unsigned long) Addr, (unsigned long) Addr + 0xFF);
+    Symbols = cc65_symbol_inrange (Info, Addr, Addr + 0xFF);
+    if (Symbols == 0) {
+        printf ("  None found\n");
+    } else {
+        PrintSymbolInfo (Symbols);
+        cc65_free_symbolinfo (Info, Symbols);
+    }
 
     /* Free the debug info */
     cc65_free_dbginfo (Info);