]> git.sur5r.net Git - cc65/blobdiff - src/ca65/error.c
Started to add debug infos for C functions and symbols.
[cc65] / src / ca65 / error.c
index 67bf2909251ae795a185689f9750c47f72da52fc..85511d10744ccd6013df531e56e814fe2c2afd84 100644 (file)
@@ -69,49 +69,114 @@ unsigned WarningCount      = 0;
 
 
 
-static int FindAsmEntry (const Collection* LineInfos)
-/* Return the last entry of type LI_TYPE_ASM in the given line infos. If none
- * was found, return -1.
- */
+static void VPrintMsg (const FilePos* Pos, const char* Desc,
+                       const char* Format, va_list ap)
+/* Format and output an error/warning message. */
 {
-    unsigned I = CollCount (LineInfos);
-    while (I > 0) {
-        const LineInfo* LI = CollConstAt (LineInfos, --I);
-        if ((LI->Type & LI_MASK_TYPE) == LI_TYPE_ASM) {
-            /* Found */
-            return (int) I;
+    StrBuf S = STATIC_STRBUF_INITIALIZER;
+
+    /* Format the actual message */
+    StrBuf Msg = STATIC_STRBUF_INITIALIZER;
+    SB_VPrintf (&Msg, Format, ap);
+    SB_Terminate (&Msg);
+
+    /* Format the message header */
+    SB_Printf (&S, "%s(%u): %s: ",
+               SB_GetConstBuf (GetFileName (Pos->Name)),
+               Pos->Line,
+               Desc);
+
+    /* Append the message to the message header */
+    SB_Append (&S, &Msg);
+
+    /* Delete the formatted message */
+    SB_Done (&Msg);
+
+    /* Add a new line and terminate the generated full message */
+    SB_AppendChar (&S, '\n');
+    SB_Terminate (&S);
+
+    /* Output the full message */
+    fputs (SB_GetConstBuf (&S), stderr);
+
+    /* Delete the buffer for the full message */
+    SB_Done (&S);
+}
+
+
+
+static void PrintMsg (const FilePos* Pos, const char* Desc,
+                      const char* Format, ...)
+/* Format and output an error/warning message. */
+{
+    va_list ap;
+    va_start (ap, Format);
+    VPrintMsg (Pos, Desc, Format, ap);
+    va_end (ap);
+}
+
+
+
+static void AddNotifications (const Collection* LineInfos)
+/* Output additional notifications for an error or warning */
+{
+    unsigned I;
+    unsigned Skipped;
+
+    /* The basic line info is always in slot zero. It has been used to
+     * output the actual error or warning. The following slots may contain
+     * more information. Check them and print additional notifications if
+     * they're present, but limit the number to a reasonable value.
+     */
+    unsigned MaxCount = CollCount (LineInfos);
+    if (MaxCount > 6) {
+        MaxCount = 6;
+    }
+    Skipped = CollCount (LineInfos) - MaxCount;
+    for (I = 1; I < MaxCount; ++I) {
+        /* Get next line info */
+        const LineInfo* LI = CollConstAt (LineInfos, I);
+        /* Check the type and output an appropriate note */
+        unsigned Type = GetLineInfoType (LI);
+        if (Type == LI_TYPE_EXT) {
+            PrintMsg (GetSourcePos (LI), "Note",
+                      "Assembler code generated from this line");
+        } else if (Type == LI_TYPE_MACRO) {
+            PrintMsg (GetSourcePos (LI), "Note",
+                      "Macro was defined here");
         }
     }
 
-    /* Not found */
-    return -1;
+    /* Add a note if we have more stuff that we won't output */
+    if (Skipped > 0) {
+        const LineInfo* LI = CollConstAt (LineInfos, 0);
+        PrintMsg (GetSourcePos (LI), "Note",
+                  "Dropping %u additional line infos", Skipped);
+    }
 }
 
 
 
 /*****************************************************************************/
-/*                                Warnings                                  */
+/*                                Warnings                                  */
 /*****************************************************************************/
 
 
 
-void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list ap)
+static void WarningMsg (const Collection* LineInfos, const char* Format, va_list ap)
 /* Print warning message. */
 {
-    if (Level <= WarnLevel) {
+    /* The first entry in the collection is that of the actual source pos */
+    const LineInfo* LI = CollConstAt (LineInfos, 0);
 
-        StrBuf S = STATIC_STRBUF_INITIALIZER;
-        SB_VPrintf (&S, Format, ap);
-        SB_Terminate (&S);
+    /* Output a warning for this position */
+    VPrintMsg (GetSourcePos (LI), "Warning", Format, ap);
 
-               fprintf (stderr, "%s(%lu): Warning: %s\n",
-                 SB_GetConstBuf (GetFileName (Pos->Name)),
-                 Pos->Line,
-                 SB_GetConstBuf (&S));
-       ++WarningCount;
+    /* Add additional notifications if necessary */
+    AddNotifications (LineInfos);
 
-        SB_Done (&S);
-    }
+    /* Count warnings */
+    ++WarningCount;
 }
 
 
@@ -119,10 +184,23 @@ void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list
 void Warning (unsigned Level, const char* Format, ...)
 /* Print warning message. */
 {
-    va_list ap;
-    va_start (ap, Format);
-    WarningMsg (&CurTok.Pos, Level, Format, ap);
-    va_end (ap);
+    if (Level <= WarnLevel) {
+
+        va_list ap;
+        Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
+
+        /* Get line infos for the current position */
+        GetFullLineInfo (&LineInfos);
+
+        /* Output the message */
+        va_start (ap, Format);
+        WarningMsg (&LineInfos, Format, ap);
+        va_end (ap);
+
+        /* Free the line info list */
+        ReleaseFullLineInfo (&LineInfos);
+        DoneCollection (&LineInfos);
+    }
 }
 
 
@@ -130,10 +208,15 @@ void Warning (unsigned Level, const char* Format, ...)
 void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
 /* Print warning message giving an explicit file and position. */
 {
-    va_list ap;
-    va_start (ap, Format);
-    WarningMsg (Pos, Level, Format, ap);
-    va_end (ap);
+    if (Level <= WarnLevel) {
+        va_list ap;
+        va_start (ap, Format);
+        VPrintMsg (Pos, "Warning", Format, ap);
+        va_end (ap);
+
+        /* Count warnings */
+        ++WarningCount;
+    }
 }
 
 
@@ -141,46 +224,37 @@ void PWarning (const FilePos* Pos, unsigned Level, const char* Format, ...)
 void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format, ...)
 /* Print warning message using the given line infos */
 {
-    const LineInfo* LI;
-    va_list ap;
-
-    /* Search backwards in LI for the first entry of type LI_TYPE_ASM. */
-    int I = FindAsmEntry (LineInfos);
-
-    /* We must have such an entry */
-    CHECK (I >= 0);
-
-    /* Get the position for this entry */
-    LI = CollConstAt (LineInfos, I);
-
-    /* Output a warning for this position */
-    va_start (ap, Format);
-    WarningMsg (&LI->Pos, Level, Format, ap);
-    va_end (ap);
+    if (Level <= WarnLevel) {
+        /* Output the message */
+        va_list ap;
+        va_start (ap, Format);
+        WarningMsg (LineInfos, Format, ap);
+        va_end (ap);
+    }
 }
 
 
 
 /*****************************************************************************/
-/*                                 Errors                                   */
+/*                                 Errors                                   */
 /*****************************************************************************/
 
 
 
-void ErrorMsg (const FilePos* Pos, const char* Format, va_list ap)
+void ErrorMsg (const Collection* LineInfos, const char* Format, va_list ap)
 /* Print an error message */
 {
-    StrBuf S = STATIC_STRBUF_INITIALIZER;
-    SB_VPrintf (&S, Format, ap);
-    SB_Terminate (&S);
+    /* The first entry in the collection is that of the actual source pos */
+    const LineInfo* LI = CollConstAt (LineInfos, 0);
 
-    fprintf (stderr, "%s(%lu): Error: %s\n",
-             SB_GetConstBuf (GetFileName (Pos->Name)),
-             Pos->Line,
-             SB_GetConstBuf (&S));
-    ++ErrorCount;
+    /* Output an error for this position */
+    VPrintMsg (GetSourcePos (LI), "Error", Format, ap);
 
-    SB_Done (&S);
+    /* Add additional notifications if necessary */
+    AddNotifications (LineInfos);
+
+    /* Count errors */
+    ++ErrorCount;
 }
 
 
@@ -189,20 +263,19 @@ void Error (const char* Format, ...)
 /* Print an error message */
 {
     va_list ap;
-    va_start (ap, Format);
-    ErrorMsg (&CurTok.Pos, Format, ap);
-    va_end (ap);
-}
-
+    Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
 
+    /* Get line infos for the current position */
+    GetFullLineInfo (&LineInfos);
 
-void PError (const FilePos* Pos, const char* Format, ...)
-/* Print an error message giving an explicit file and position. */
-{
-    va_list ap;
+    /* Output the message */
     va_start (ap, Format);
-    ErrorMsg (Pos, Format, ap);
+    ErrorMsg (&LineInfos, Format, ap);
     va_end (ap);
+
+    /* Free the line info list */
+    ReleaseFullLineInfo (&LineInfos);
+    DoneCollection (&LineInfos);
 }
 
 
@@ -210,21 +283,10 @@ void PError (const FilePos* Pos, const char* Format, ...)
 void LIError (const Collection* LineInfos, const char* Format, ...)
 /* Print an error message using the given line infos. */
 {
-    const LineInfo* LI;
-    va_list ap;
-
-    /* Search backwards in LI for the first entry of type LI_TYPE_ASM. */
-    int I = FindAsmEntry (LineInfos);
-
-    /* We must have such an entry */
-    CHECK (I >= 0);
-
-    /* Get the position for this entry */
-    LI = CollConstAt (LineInfos, I);
-
     /* Output an error for this position */
+    va_list ap;
     va_start (ap, Format);
-    ErrorMsg (&LI->Pos, Format, ap);
+    ErrorMsg (LineInfos, Format, ap);
     va_end (ap);
 }
 
@@ -234,10 +296,21 @@ void ErrorSkip (const char* Format, ...)
 /* Print an error message and skip the rest of the line */
 {
     va_list ap;
+    Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
+
+    /* Get line infos for the current position */
+    GetFullLineInfo (&LineInfos);
+
+    /* Output the message */
     va_start (ap, Format);
-    ErrorMsg (&CurTok.Pos, Format, ap);
+    ErrorMsg (&LineInfos, Format, ap);
     va_end (ap);
 
+    /* Free the line info list */
+    ReleaseFullLineInfo (&LineInfos);
+    DoneCollection (&LineInfos);
+
+    /* Skip tokens until we reach the end of the line */
     SkipUntilSep ();
 }