]> git.sur5r.net Git - cc65/blobdiff - src/cc65/error.c
Renamed the defines in symdefs.h to something more meaningful. They were named
[cc65] / src / cc65 / error.c
index 2f443f28d6a9ae002be25add342f7aa205bc858e..f73f0a4a0c24dbde36d2b65de714936ed1837d29 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2000 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@musoftware.de                                            */
+/* (C) 1998-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 #include <stdlib.h>
 #include <stdarg.h>
 
+/* common */
+#include "print.h"
+
+/* cc65 */
 #include "global.h"
 #include "input.h"
+#include "lineinfo.h"
 #include "scanner.h"
 #include "stmt.h"
 #include "error.h"
 unsigned ErrorCount    = 0;
 unsigned WarningCount  = 0;
 
+/* Warning and error options */
+IntStack WarnEnable         = INTSTACK(1);  /* Enable warnings */
+IntStack WarningsAreErrors  = INTSTACK(0);  /* Treat warnings as errors */
+IntStack WarnStructParam    = INTSTACK(1);  /* Warn about structs passed by val */
+IntStack WarnUnusedLabel    = INTSTACK(1);  /* Warn about unused labels */
+IntStack WarnUnusedParam    = INTSTACK(1);  /* Warn about unused parameters */
+IntStack WarnUnusedVar      = INTSTACK(1);  /* Warn about unused variables */
+IntStack WarnUnknownPragma  = INTSTACK(1);  /* Warn about unknown #pragmas */
+
+/* Map the name of a warning to the intstack that holds its state */
+typedef struct WarnMapEntry WarnMapEntry;
+struct WarnMapEntry {
+    IntStack*   Stack;
+    const char* Name;
+};
+static WarnMapEntry WarnMap[] = {
+    /* Keep sorted, even if this isn't used for now */
+    { &WarningsAreErrors,       "error"                 },
+    { &WarnStructParam,         "struct-param"          },
+    { &WarnUnknownPragma,       "unknown-pragma"        },
+    { &WarnUnusedLabel,         "unused-label"          },
+    { &WarnUnusedParam,         "unused-param"          },
+    { &WarnUnusedVar,           "unused-var"            },
+};
+
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                         Handling of fatal errors                          */
 /*****************************************************************************/
 
 
 
-static void IntWarning (const char* Filename, unsigned Line, const char* Msg, va_list ap)
-/* Print warning message - internal function. */
+void Fatal (const char* Format, ...)
+/* Print a message about a fatal error and die */
 {
-    if (!NoWarn) {
-               fprintf (stderr, "%s(%u): Warning: ", Filename, Line);
-       vfprintf (stderr, Msg, ap);
-       fprintf (stderr, "\n");
+    va_list ap;
 
-       if (Verbose) {
-           fprintf (stderr, "Line: %s\n", line);
-       }
-       ++WarningCount;
+    const char* FileName;
+    unsigned    LineNum;
+    if (CurTok.LI) {
+       FileName = GetInputName (CurTok.LI);
+       LineNum  = GetInputLine (CurTok.LI);
+    } else {
+       FileName = GetCurrentFile ();
+       LineNum  = GetCurrentLine ();
     }
-}
-
 
+    fprintf (stderr, "%s(%u): Fatal: ", FileName, LineNum);
 
-void Warning (const char* Format, ...)
-/* Print warning message. */
-{
-    va_list ap;
     va_start (ap, Format);
-    IntWarning (GetCurrentFile(), curpos, Format, ap);
+    vfprintf (stderr, Format, ap);
     va_end (ap);
+    fprintf (stderr, "\n");
+
+    if (Line) {
+        Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
+    }
+    exit (EXIT_FAILURE);
 }
 
 
 
-void PPWarning (const char* Format, ...)
-/* Print warning message. For use within the preprocessor. */
+void Internal (const char* Format, ...)
+/* Print a message about an internal compiler error and die. */
 {
     va_list ap;
+
+    const char* FileName;
+    unsigned    LineNum;
+    if (CurTok.LI) {
+       FileName = GetInputName (CurTok.LI);
+       LineNum  = GetInputLine (CurTok.LI);
+    } else {
+       FileName = GetCurrentFile ();
+       LineNum  = GetCurrentLine ();
+    }
+
+    fprintf (stderr, "%s(%u): Internal compiler error:\n",
+            FileName, LineNum);
+
     va_start (ap, Format);
-    IntWarning (GetCurrentFile(), GetCurrentLine(), Format, ap);
+    vfprintf (stderr, Format, ap);
     va_end (ap);
+    fprintf (stderr, "\n");
+
+    if (Line) {
+        fprintf (stderr, "\nInput: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
+    }
+
+    /* Use abort to create a core dump */
+    abort ();
 }
 
 
 
-static void IntError (const char* Filename, unsigned Line, const char* Msg, va_list ap)
+/*****************************************************************************/
+/*                            Handling of errors                             */
+/*****************************************************************************/
+
+
+
+static void IntError (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
 /* Print an error message - internal function*/
 {
-    fprintf (stderr, "%s(%u): Error: ", Filename, Line);
+    fprintf (stderr, "%s(%u): Error: ", Filename, LineNo);
     vfprintf (stderr, Msg, ap);
     fprintf (stderr, "\n");
 
-    if (Verbose) {
-               fprintf (stderr, "Line: %s\n", line);
+    if (Line) {
+        Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
     }
     ++ErrorCount;
     if (ErrorCount > 10) {
@@ -125,7 +185,18 @@ void Error (const char* Format, ...)
 {
     va_list ap;
     va_start (ap, Format);
-    IntError (GetCurrentFile(), curpos, Format, ap);
+    IntError (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
+    va_end (ap);
+}
+
+
+
+void LIError (const LineInfo* LI, const char* Format, ...)
+/* Print an error message with the line info given explicitly */
+{
+    va_list ap;
+    va_start (ap, Format);
+    IntError (GetInputName (LI), GetInputLine (LI), Format, ap);
     va_end (ap);
 }
 
@@ -142,53 +213,98 @@ void PPError (const char* Format, ...)
 
 
 
-void Fatal (const char* Format, ...)
-/* Print a message about a fatal error and die */
+/*****************************************************************************/
+/*                           Handling of warnings                            */
+/*****************************************************************************/
+
+
+
+static void IntWarning (const char* Filename, unsigned LineNo, const char* Msg, va_list ap)
+/* Print warning message - internal function. */
 {
-    va_list ap;
+    if (IS_Get (&WarningsAreErrors)) {
 
-    fprintf (stderr, "%s(%u): Fatal: ", GetCurrentFile(), curpos);
+        /* Treat the warning as an error */
+        IntError (Filename, LineNo, Msg, ap);
 
-    va_start (ap, Format);
-    vfprintf (stderr, Format, ap);
-    va_end (ap);
-    fprintf (stderr, "\n");
+    } else if (IS_Get (&WarnEnable)) {
+
+               fprintf (stderr, "%s(%u): Warning: ", Filename, LineNo);
+       vfprintf (stderr, Msg, ap);
+       fprintf (stderr, "\n");
+
+        if (Line) {
+           Print (stderr, 1, "Input: %.*s\n", (int) SB_GetLen (Line), SB_GetConstBuf (Line));
+        }
+       ++WarningCount;
 
-    if (Verbose) {
-               fprintf (stderr, "Line: %s\n", line);
     }
-    exit (EXIT_FAILURE);
 }
 
 
 
-void Internal (char* Format, ...)
-/* Print a message about an internal compiler error and die. */
+void Warning (const char* Format, ...)
+/* Print warning message. */
 {
     va_list ap;
+    va_start (ap, Format);
+    IntWarning (GetInputName (CurTok.LI), GetInputLine (CurTok.LI), Format, ap);
+    va_end (ap);
+}
+
 
-    fprintf (stderr, "%s(%u): Internal compiler error:\n",
-            GetCurrentFile(), curpos);
 
+void LIWarning (const LineInfo* LI, const char* Format, ...)
+/* Print a warning message with the line info given explicitly */
+{
+    va_list ap;
     va_start (ap, Format);
-    vfprintf (stderr, Format, ap);
+    IntWarning (GetInputName (LI), GetInputLine (LI), Format, ap);
     va_end (ap);
-    fprintf (stderr, "\nLine: %s\n", line);
+}
 
-    /* Use abort to create a core dump */
-    abort ();
+
+
+void PPWarning (const char* Format, ...)
+/* Print warning message. For use within the preprocessor. */
+{
+    va_list ap;
+    va_start (ap, Format);
+    IntWarning (GetCurrentFile(), GetCurrentLine(), Format, ap);
+    va_end (ap);
 }
 
 
 
-void ErrorReport (void)
-/* Report errors (called at end of compile) */
+IntStack* FindWarning (const char* Name)
+/* Search for a warning in the WarnMap table and return a pointer to the
+ * intstack that holds its state. Return NULL if there is no such warning.
+ */
 {
-    if (ErrorCount == 0 && Verbose) {
-       printf ("No errors.\n");
+    unsigned I;
+
+    /* For now, do a linear search */
+    for (I = 0; I < sizeof(WarnMap) / sizeof (WarnMap[0]); ++I) {
+        if (strcmp (WarnMap[I].Name, Name) == 0) {
+            return WarnMap[I].Stack;
+        }
     }
+    return 0;
 }
 
 
 
+/*****************************************************************************/
+/*                                   Code                                    */
+/*****************************************************************************/
+
+
+
+void ErrorReport (void)
+/* Report errors (called at end of compile) */
+{
+    Print (stdout, 1, "%u errors, %u warnings\n", ErrorCount, WarningCount);
+}
+
+