X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fca65%2Ferror.c;h=85511d10744ccd6013df531e56e814fe2c2afd84;hb=2fbebd25cf9460060e73398abd244ea253d20807;hp=06bbf26153bf48b3d3f84e68b8acbbffa21733b4;hpb=4555fdcad17b14439dc4876ec1ac275accdb5c14;p=cc65 diff --git a/src/ca65/error.c b/src/ca65/error.c index 06bbf2615..85511d107 100644 --- a/src/ca65/error.c +++ b/src/ca65/error.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 1998-2003 Ullrich von Bassewitz */ -/* Römerstraße 52 */ -/* D-70794 Filderstadt */ -/* EMail: uz@cc65.org */ +/* (C) 1998-2011, Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ +/* D-70794 Filderstadt */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -37,10 +37,14 @@ #include #include +/* common */ +#include "strbuf.h" + /* ca65 */ +#include "error.h" #include "filetab.h" +#include "lineinfo.h" #include "nexttok.h" -#include "error.h" @@ -60,60 +64,196 @@ unsigned WarningCount = 0; /*****************************************************************************/ -/* Warnings */ +/* Helper functions */ /*****************************************************************************/ -void WarningMsg (const FilePos* Pos, unsigned Level, const char* Format, va_list ap) -/* Print warning message. */ +static void VPrintMsg (const FilePos* Pos, const char* Desc, + const char* Format, va_list ap) +/* Format and output an error/warning message. */ { - if (Level <= WarnLevel) { - fprintf (stderr, "%s(%lu): Warning: ", - GetFileName (Pos->Name), Pos->Line); - vfprintf (stderr, Format, ap); - fprintf (stderr, "\n"); - ++WarningCount; - } + 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); } -void Warning (unsigned Level, const char* Format, ...) -/* Print warning message. */ +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); - WarningMsg (&CurPos, Level, Format, ap); + 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"); + } + } + + /* 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 */ +/*****************************************************************************/ + + + +static void WarningMsg (const Collection* LineInfos, const char* Format, va_list ap) +/* Print warning message. */ +{ + /* 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 */ + VPrintMsg (GetSourcePos (LI), "Warning", Format, ap); + + /* Add additional notifications if necessary */ + AddNotifications (LineInfos); + + /* Count warnings */ + ++WarningCount; +} + + + +void Warning (unsigned Level, const char* Format, ...) +/* Print warning message. */ +{ + 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); + } +} + + + 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; + } +} + + + +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; + 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 */ { - fprintf (stderr, "%s(%lu): Error: ", - GetFileName (Pos->Name), Pos->Line); - vfprintf (stderr, Format, ap); - fprintf (stderr, "\n"); + /* 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; } @@ -123,19 +263,30 @@ void Error (const char* Format, ...) /* Print an error message */ { 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 (&CurPos, Format, ap); + ErrorMsg (&LineInfos, Format, ap); va_end (ap); + + /* Free the line info list */ + ReleaseFullLineInfo (&LineInfos); + DoneCollection (&LineInfos); } -void PError (const FilePos* Pos, const char* Format, ...) -/* Print an error message giving an explicit file and position. */ +void LIError (const Collection* LineInfos, const char* Format, ...) +/* Print an error message using the given line infos. */ { + /* Output an error for this position */ va_list ap; va_start (ap, Format); - ErrorMsg (Pos, Format, ap); + ErrorMsg (LineInfos, Format, ap); va_end (ap); } @@ -145,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 (&CurPos, 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 (); } @@ -164,13 +326,17 @@ void Fatal (const char* Format, ...) /* Print a message about a fatal error and die */ { va_list ap; + StrBuf S = STATIC_STRBUF_INITIALIZER; va_start (ap, Format); - fprintf (stderr, "Fatal error: "); - vfprintf (stderr, Format, ap); - fprintf (stderr, "\n"); + SB_VPrintf (&S, Format, ap); + SB_Terminate (&S); va_end (ap); + fprintf (stderr, "Fatal error: %s\n", SB_GetConstBuf (&S)); + + SB_Done (&S); + /* And die... */ exit (EXIT_FAILURE); } @@ -178,14 +344,19 @@ void Fatal (const char* Format, ...) void Internal (const char* Format, ...) -/* Print a message about an internal compiler error and die. */ +/* Print a message about an internal assembler error and die. */ { va_list ap; + StrBuf S = STATIC_STRBUF_INITIALIZER; + va_start (ap, Format); - fprintf (stderr, "Internal assembler error:\n"); - vfprintf (stderr, Format, ap); + SB_VPrintf (&S, Format, ap); + SB_Terminate (&S); va_end (ap); - fprintf (stderr, "\n"); + + fprintf (stderr, "Internal assembler error: %s\n", SB_GetConstBuf (&S)); + + SB_Done (&S); exit (EXIT_FAILURE); }