]> git.sur5r.net Git - cc65/commitdiff
Use line infos to output more verbose error and warning messages whenever
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 29 Jan 2011 18:43:36 +0000 (18:43 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 29 Jan 2011 18:43:36 +0000 (18:43 +0000)
possible.

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

src/ca65/asserts.c
src/ca65/condasm.c
src/ca65/error.c
src/ca65/error.h
src/ca65/fragment.c
src/ca65/lineinfo.c
src/ca65/lineinfo.h
src/ca65/scanner.c
src/ca65/studyexpr.c
src/ca65/symentry.c
src/ca65/ulabel.c

index 84b2621c700b4daa7bfe17a276ebc30bcd298683..d70f8f6023e230ff3dc33aa2270479ddd0ce1589 100644 (file)
@@ -84,7 +84,7 @@ static Assertion* NewAssertion (ExprNode* Expr, AssertAction Action, unsigned Ms
     A->Action   = Action;
     A->Msg      = Msg;
     A->LI       = EmptyCollection;
-    GetFullLineInfo (&A->LI);
+    GetFullLineInfo (&A->LI, 1);
 
     /* Return the new struct */
     return A;
index 28c9f4bd4016cd515b0f19304b6f3db7adda5ae1..567abc7d9b00dc56f32a2751958260706f60e078 100644 (file)
@@ -37,6 +37,7 @@
 #include "error.h"
 #include "expr.h"
 #include "instr.h"
+#include "lineinfo.h"
 #include "nexttok.h"
 #include "symbol.h"
 #include "symtab.h"
@@ -73,7 +74,7 @@ enum {
 typedef struct IfDesc IfDesc;
 struct IfDesc {
     unsigned           Flags;          /* Bitmapped flags, see above */
-    FilePos            Pos;            /* File position of the .IF */
+    Collection  LineInfos;      /* File position of the .IF */
     const char* Name;          /* Name of the directive */
 };
 
@@ -97,9 +98,10 @@ static IfDesc* AllocIf (const char* Directive, int NeedTerm)
     ID = &IfStack [IfCount++];
 
     /* Initialize elements */
-    ID->Flags = NeedTerm? ifNeedTerm : ifNone;
-    ID->Pos   = CurTok.Pos;
-    ID->Name  = Directive;
+    ID->Flags     = NeedTerm? ifNeedTerm : ifNone;
+    ID->LineInfos = EmptyCollection;
+    GetFullLineInfo (&ID->LineInfos, 0);
+    ID->Name      = Directive;
 
     /* Return the result */
     return ID;
@@ -218,7 +220,7 @@ void DoConditionals (void)
                    /* Allow an .ELSE */
                    InvertIfCond (D);
                    SetElse (D, 1);
-                   D->Pos = CurTok.Pos;
+                   GetFullLineInfo (&D->LineInfos, 0);
                    D->Name = ".ELSE";
                    IfCond = GetCurrentIfCond ();
                }
@@ -464,6 +466,8 @@ void CheckOpenIfs (void)
  * open .ifs in this file.
  */
 {
+    const LineInfo* LI;
+
     while (1) {
        /* Get the current file number and check if the topmost entry on the
         * .IF stack was inserted with this file number
@@ -474,13 +478,14 @@ void CheckOpenIfs (void)
            break;
        }
 
-       if (D->Pos.Name != CurTok.Pos.Name) {
+        LI = CollConstAt (&D->LineInfos, 0);
+       if (LI->Pos.Name != CurTok.Pos.Name) {
            /* The .if is from another file, bail out */
            break;
        }
 
                /* Start of .if is in the file we're about to leave */
-       PError (&D->Pos, "Conditional assembly branch was never closed");
+       LIError (&D->LineInfos, "Conditional assembly branch was never closed");
        FreeIf ();
     }
 }
index e43e480b22bbdbf92f267b7aa1a97a0e2b3dce4d..7aeaa7854b3aadde232da43dc2f184a07f2ae871 100644 (file)
@@ -69,45 +69,49 @@ unsigned WarningCount       = 0;
 
 
 
-static void FormatVMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
-                        const char* Format, va_list ap)
-/* Format an error/warning message into S. A trailing newline and a NUL
- * terminator will be added to S.
- */
+static void VPrintMsg (const FilePos* Pos, const char* Desc,
+                       const char* Format, va_list ap)
+/* Format and output an error/warning message. */
 {
+    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(%lu): %s: ",
+    SB_Printf (&S, "%s(%lu): %s: ",
                SB_GetConstBuf (GetFileName (Pos->Name)),
                Pos->Line,
                Desc);
 
     /* Append the message to the message header */
-    SB_Append (S, &Msg);
+    SB_Append (&S, &Msg);
 
     /* Delete the formatted message */
     SB_Done (&Msg);
 
-    /* Add a new line and terminate the generated message */
-    SB_AppendChar (S, '\n');
-    SB_Terminate (S);
+    /* 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 FormatMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
-                       const char* Format, ...)
-/* Format an error/warning message into S. A trailing newline and a NUL
- * terminator will be added to 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);
-    FormatVMsg (S, Pos, Desc, Format, ap);
+    VPrintMsg (Pos, Desc, Format, ap);
     va_end (ap);
 }
 
@@ -116,8 +120,6 @@ static void FormatMsg (StrBuf* S, const FilePos* Pos, const char* Desc,
 static void AddNotifications (const Collection* LineInfos)
 /* Output additional notifications for an error or warning */
 {
-    StrBuf Msg = STATIC_STRBUF_INITIALIZER;
-
     /* 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 additional notifications if they're
@@ -130,38 +132,37 @@ static void AddNotifications (const Collection* LineInfos)
         /* Check the type and output an appropriate note */
         unsigned Type = GetLineInfoType (LI);
         if (Type == LI_TYPE_EXT) {
-            FormatMsg (&Msg, GetSourcePos (LI), "Note",
-                       "Assembler code generated from this line");
-            fputs (SB_GetConstBuf (&Msg), stderr);
-
+            PrintMsg (GetSourcePos (LI), "Note",
+                      "Assembler code generated from this line");
         } else if (Type == LI_TYPE_MACRO) {
-
+            PrintMsg (GetSourcePos (LI), "Note",
+                      "Macro expansion was here");
         }
     }
-
-    SB_Done (&Msg);
 }
 
 
 
 /*****************************************************************************/
-/*                                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 Msg = STATIC_STRBUF_INITIALIZER;
-        FormatVMsg (&Msg, Pos, "Warning", Format, ap);
-        fputs (SB_GetConstBuf (&Msg), stderr);
-        SB_Done (&Msg);
+    /* Output a warning for this position */
+    VPrintMsg (GetSourcePos (LI), "Warning", Format, ap);
 
-       ++WarningCount;
-    }
+    /* Add additional notifications if necessary */
+    AddNotifications (LineInfos);
+
+    /* Count warnings */
+    ++WarningCount;
 }
 
 
@@ -169,10 +170,22 @@ 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, 0);
+
+        /* Output the message */
+        va_start (ap, Format);
+        WarningMsg (&LineInfos, Format, ap);
+        va_end (ap);
+
+        /* Free the line info list */
+        DoneCollection (&LineInfos);
+    }
 }
 
 
@@ -180,10 +193,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;
+    }
 }
 
 
@@ -192,19 +210,11 @@ void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format,
 /* Print warning message using the given line infos */
 {
     if (Level <= WarnLevel) {
-
+        /* Output the message */
         va_list ap;
-
-        /* The first entry in the collection is that of the actual source pos */
-        const LineInfo* LI = CollConstAt (LineInfos, 0);
-
-        /* Output a warning for this position */
         va_start (ap, Format);
-        WarningMsg (GetSourcePos (LI), Level, Format, ap);
+        WarningMsg (LineInfos, Format, ap);
         va_end (ap);
-
-        /* Add additional notifications if necessary */
-        AddNotifications (LineInfos);
     }
 }
 
@@ -216,14 +226,19 @@ void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format,
 
 
 
-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 Msg = STATIC_STRBUF_INITIALIZER;
-    FormatVMsg (&Msg, Pos, "Error", Format, ap);
-    fputs (SB_GetConstBuf (&Msg), stderr);
-    SB_Done (&Msg);
+    /* The first entry in the collection is that of the actual source pos */
+    const LineInfo* LI = CollConstAt (LineInfos, 0);
+
+    /* Output an error for this position */
+    VPrintMsg (GetSourcePos (LI), "Error", Format, ap);
 
+    /* Add additional notifications if necessary */
+    AddNotifications (LineInfos);
+
+    /* Count errors */
     ++ErrorCount;
 }
 
@@ -233,20 +248,18 @@ 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, 0);
 
-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 */
+    DoneCollection (&LineInfos);
 }
 
 
@@ -254,18 +267,11 @@ 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. */
 {
-    va_list ap;
-
-    /* The first entry in the collection is that of the actual source pos */
-    const LineInfo* LI = CollConstAt (LineInfos, 0);
-
     /* Output an error for this position */
+    va_list ap;
     va_start (ap, Format);
-    ErrorMsg (GetSourcePos (LI), Format, ap);
+    ErrorMsg (LineInfos, Format, ap);
     va_end (ap);
-
-    /* Add additional notifications if necessary */
-    AddNotifications (LineInfos);
 }
 
 
@@ -274,10 +280,20 @@ 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, 0);
+
+    /* Output the message */
     va_start (ap, Format);
-    ErrorMsg (&CurTok.Pos, Format, ap);
+    ErrorMsg (&LineInfos, Format, ap);
     va_end (ap);
 
+    /* Free the line info list */
+    DoneCollection (&LineInfos);
+
+    /* Skip tokens until we reach the end of the line */
     SkipUntilSep ();
 }
 
index de0e53ac52a7e7a2a7b741ab62793b7b14ea7685..4a74aa91a3f71e48e488789c2fa51d5d1d71241c 100644 (file)
@@ -78,9 +78,6 @@ void LIWarning (const Collection* LineInfos, unsigned Level, const char* Format,
 void Error (const char* Format, ...) attribute ((format (printf, 1, 2)));
 /* Print an error message */
 
-void PError (const FilePos* Pos, const char* Format, ...) attribute ((format (printf, 2, 3)));
-/* Print an error message giving an explicit file and position. */
-
 void LIError (const Collection* LineInfos, const char* Format, ...) attribute ((format (printf, 2, 3)));
 /* Print an error message using the given line infos. */
 
index 059371e77374c24cbfa2138b340b0a0b411f47b4..4660490f98b6e1c1bdab8048e3bf6e8ae80cdb74 100644 (file)
@@ -59,7 +59,7 @@ Fragment* NewFragment (unsigned char Type, unsigned short Len)
     F->Next    = 0;
     F->LineList = 0;
     F->LI       = EmptyCollection;
-    GetFullLineInfo (&F->LI);
+    GetFullLineInfo (&F->LI, 1);
     F->Len     = Len;
     F->Type    = Type;
 
index 7e7ab3a04d3e091c5967341d91ab262ceda28799..06d027c5a3c21f84cbbaf6a990c72a07ea947a11 100644 (file)
@@ -94,29 +94,15 @@ static LineInfo* NewLineInfo (unsigned Type, const FilePos* Pos)
     LI->Index   = INV_LINEINFO_INDEX;
     LI->Pos     = *Pos;
 
+    /* Add the line info to the list of all line infos */
+    CollAppend (&LineInfoColl, LI);
+
     /* Return the new struct */
     return LI;
 }
 
 
 
-static void FreeLineInfo (LineInfo* LI)
-/* "Free" line info. If the usage counter is non zero, move it to the
- * collection that contains all line infos, otherwise delete it.
- * The function handles a NULL pointer transparently.
- */
-{
-    if (LI) {
-        if (LI->Usage > 0) {
-            CollAppend (&LineInfoColl, LI);
-        } else {
-            xfree (LI);
-        }
-    }
-}
-
-
-
 /*****************************************************************************/
 /*                                          Code                                    */
 /*****************************************************************************/
@@ -128,6 +114,9 @@ void InitLineInfo (void)
 {
     static const FilePos DefaultPos = STATIC_FILEPOS_INITIALIZER;
 
+    /* Increase the initial count of the line info collection */
+    CollGrow (&LineInfoColl, 200);
+
     /* Allocate 8 slots */
     AllocatedSlots = 8;
     CurLineInfo = xmalloc (AllocatedSlots * sizeof (LineInfoSlot));
@@ -177,7 +166,7 @@ void FreeLineInfoSlot (unsigned Slot)
     PRECONDITION (Slot == UsedSlots - 1);
 
     /* Free the last entry */
-    FreeLineInfo (CurLineInfo[Slot].Info);
+    CurLineInfo[Slot].Info = 0;
     --UsedSlots;
 }
 
@@ -189,19 +178,10 @@ void GenLineInfo (unsigned Slot, const FilePos* Pos)
     /* Get a pointer to the slot */
     LineInfoSlot* S = CurLineInfo + Slot;
 
-    /* Check if we already have data */
-    if (S->Info) {
-        /* Generate new data only if it is different from the existing. */
-        if (CompareFilePos (&S->Info->Pos, Pos) == 0) {
-            /* Already there */
-            return;
-        }
-
-        /* We have data, but it's not identical. If it is in use, copy it to
-         * line info collection, otherwise delete it.
-         */
-        FreeLineInfo (S->Info);
-
+    /* Generate new data only if it is different from the existing. */
+    if (S->Info && CompareFilePos (&S->Info->Pos, Pos) == 0) {
+        /* Already there */
+        return;
     }
 
     /* Allocate new data */
@@ -213,33 +193,33 @@ void GenLineInfo (unsigned Slot, const FilePos* Pos)
 void ClearLineInfo (unsigned Slot)
 /* Clear the line info in the given slot */
 {
-    /* Get a pointer to the slot */
-    LineInfoSlot* S = CurLineInfo + Slot;
-
-    /* Free the struct and zero the pointer */
-    FreeLineInfo (S->Info);
-    S->Info = 0;
+    /* Zero the pointer */
+    CurLineInfo[Slot].Info = 0;
 }
 
 
 
-void GetFullLineInfo (Collection* LineInfos)
+void GetFullLineInfo (Collection* LineInfos, unsigned IncUsage)
 /* Return full line infos, that is line infos for all slots in LineInfos. The
- * function does also increase the usage counter for all line infos returned.
+ * function will clear LineInfos before usage and will increment the usage
+ * counter by IncUsage for all line infos returned.
  */
 {
-   unsigned I;
+    unsigned I;
+
+    /* Clear the collection */
+    CollDeleteAll (LineInfos);
 
     /* Copy all valid line infos to the collection */
     for (I = 0; I < UsedSlots; ++I) {
 
-        /* Get the slot */
-        LineInfoSlot* S = CurLineInfo + I;
+        /* Get the line info from the slot */
+        LineInfo* LI = CurLineInfo[I].Info;
 
         /* Ignore empty slots */
-        if (S->Info) {
-            ++S->Info->Usage;
-            CollAppend (LineInfos, S->Info);
+        if (LI) {
+            LI->Usage += IncUsage;
+            CollAppend (LineInfos, LI);
         }
     }
 }
@@ -330,12 +310,7 @@ void MakeLineInfoIndex (void)
 {
     unsigned I;
 
-    /* Be sure to move pending line infos to the global list */
-    for (I = 0; I < UsedSlots; ++I) {
-        FreeLineInfo (CurLineInfo[I].Info);
-    }
-
-    /* Sort the collection */
+    /* Sort the line info list */
     CollSort (&LineInfoColl, CmpLineInfo, 0);
 
     /* Walk over the list, index the line infos and count the used ones */
index 2e4cb3c225c97233bb387c52c2f23a401889ade4..e47e4bb42f5a37eb18746cfffbc288e82267424e 100644 (file)
@@ -107,9 +107,10 @@ void GenLineInfo (unsigned Slot, const FilePos* Pos);
 void ClearLineInfo (unsigned Slot);
 /* Clear the line info in the given slot */
 
-void GetFullLineInfo (Collection* LineInfos);
+void GetFullLineInfo (Collection* LineInfos, unsigned IncUsage);
 /* Return full line infos, that is line infos for all slots in LineInfos. The
- * function does also increase the usage counter for all line infos returned.
+ * function will clear LineInfos before usage and will increment the usage
+ * counter by IncUsage for all line infos returned.
  */
 
 LineInfo* UseLineInfo (LineInfo* LI);
index 585deec6b56adba12785072eef5e7dab88f903dc..61bf3c9f8b6ed5bf9d8370fbe7cd7c1cd5add4cc 100644 (file)
@@ -1103,12 +1103,14 @@ CharAgain:
                 CurTok.Tok = TOK_DIV;
             } else if (CComments) {
                 /* Remember the position, then skip the '*' */
-                FilePos Pos = CurTok.Pos;
+                Collection LineInfos = STATIC_COLLECTION_INITIALIZER;
+                GetFullLineInfo (&LineInfos, 0);
                 NextChar ();
                 do {
                     while (C !=  '*') {
                         if (C == EOF) {
-                            PError (&Pos, "Unterminated comment");
+                            LIError (&LineInfos, "Unterminated comment");
+                            DoneCollection (&LineInfos);
                             goto CharAgain;
                         }
                         NextChar ();
@@ -1116,6 +1118,7 @@ CharAgain:
                     NextChar ();
                 } while (C != '/');
                 NextChar ();
+                DoneCollection (&LineInfos);
                 goto Again;
             }
            return;
index 33b5c47d090da302ffb0dac907df0e5b4763d7fb..42a8dbbd6a748b513b53791aad8cc49a6ebc357c 100644 (file)
@@ -510,9 +510,9 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
             if (Verbosity > 0) {
                 DumpExpr (Expr, SymResolve);
             }
-            PError (GetSymPos (Sym),
-                    "Circular reference in definition of symbol `%m%p'",
-                    GetSymName (Sym));
+            LIError (&Sym->LineInfos,
+                     "Circular reference in definition of symbol `%m%p'",
+                     GetSymName (Sym));
             ED_Invalidate (D);
         } else {
 
index 0c4d9bcf4f5f50708ef65380e6e17937bb2c21df..999ae32f80418ef464ca32129772b6632e8584bf 100644 (file)
@@ -87,7 +87,7 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags)
     S->Locals            = 0;
     S->Sym.Tab    = 0;
     S->LineInfos  = EmptyCollection;
-    GetFullLineInfo (&S->LineInfos);
+    GetFullLineInfo (&S->LineInfos, 1);
     for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) {
         S->GuessedUse[I] = 0;
     }
index 3340a68c8ece5f6d8786c59f14b5e59a1def1501..023dd13757e12f3fcf461d952f58ec0a37a3df41 100644 (file)
@@ -83,7 +83,7 @@ static ULabel* NewULabel (ExprNode* Val)
 
     /* Initialize the fields */
     L->LineInfos = EmptyCollection;
-    GetFullLineInfo (&L->LineInfos);
+    GetFullLineInfo (&L->LineInfos, 0);
     L->Val       = Val;
     L->Ref       = 0;
 
@@ -161,8 +161,7 @@ void ULabDef (void)
        ULabel* L = CollAtUnchecked (&ULabList, ULabDefCount);
        CHECK (L->Val == 0);
        L->Val = GenCurrentPC ();
-        CollDeleteAll (&L->LineInfos);
-        GetFullLineInfo (&L->LineInfos);
+        GetFullLineInfo (&L->LineInfos, 0);
     } else {
        /* There is no such label, create it */
                NewULabel (GenCurrentPC ());