From: uz Date: Sat, 29 Jan 2011 18:43:36 +0000 (+0000) Subject: Use line infos to output more verbose error and warning messages whenever X-Git-Tag: V2.13.3~510 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1072edb0d880cf9b823eeffef658153a043ab380;p=cc65 Use line infos to output more verbose error and warning messages whenever possible. git-svn-id: svn://svn.cc65.org/cc65/trunk@4950 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/ca65/asserts.c b/src/ca65/asserts.c index 84b2621c7..d70f8f602 100644 --- a/src/ca65/asserts.c +++ b/src/ca65/asserts.c @@ -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; diff --git a/src/ca65/condasm.c b/src/ca65/condasm.c index 28c9f4bd4..567abc7d9 100644 --- a/src/ca65/condasm.c +++ b/src/ca65/condasm.c @@ -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 (); } } diff --git a/src/ca65/error.c b/src/ca65/error.c index e43e480b2..7aeaa7854 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -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 (); } diff --git a/src/ca65/error.h b/src/ca65/error.h index de0e53ac5..4a74aa91a 100644 --- a/src/ca65/error.h +++ b/src/ca65/error.h @@ -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. */ diff --git a/src/ca65/fragment.c b/src/ca65/fragment.c index 059371e77..4660490f9 100644 --- a/src/ca65/fragment.c +++ b/src/ca65/fragment.c @@ -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; diff --git a/src/ca65/lineinfo.c b/src/ca65/lineinfo.c index 7e7ab3a04..06d027c5a 100644 --- a/src/ca65/lineinfo.c +++ b/src/ca65/lineinfo.c @@ -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 */ diff --git a/src/ca65/lineinfo.h b/src/ca65/lineinfo.h index 2e4cb3c22..e47e4bb42 100644 --- a/src/ca65/lineinfo.h +++ b/src/ca65/lineinfo.h @@ -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); diff --git a/src/ca65/scanner.c b/src/ca65/scanner.c index 585deec6b..61bf3c9f8 100644 --- a/src/ca65/scanner.c +++ b/src/ca65/scanner.c @@ -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; diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 33b5c47d0..42a8dbbd6 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -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 { diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index 0c4d9bcf4..999ae32f8 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -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; } diff --git a/src/ca65/ulabel.c b/src/ca65/ulabel.c index 3340a68c8..023dd1375 100644 --- a/src/ca65/ulabel.c +++ b/src/ca65/ulabel.c @@ -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 ());