]> andersk Git - splint.git/blobdiff - src/llerror.c
Fixed scanf %x problem.
[splint.git] / src / llerror.c
index 6807d83004b0468a488fcaa7f654829c5038aff6..3e6978e916e194e1d91d8b8c6ead86b44c426844 100644 (file)
@@ -1,6 +1,6 @@
 /*
-** LCLint - annotation-assisted static program checker
-** Copyright (C) 1994-2000 University of Virginia,
+** Splint - annotation-assisted static program checker
+** Copyright (C) 1994-2003 University of Virginia,
 **         Massachusetts Institute of Technology
 **
 ** This program is free software; you can redistribute it and/or modify it
@@ -17,9 +17,9 @@
 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 ** MA 02111-1307, USA.
 **
-** For information on lclint: lclint-request@cs.virginia.edu
-** To report a bug: lclint-bug@cs.virginia.edu
-** For more information: http://lclint.cs.virginia.edu
+** For information on splint: info@splint.org
+** To report a bug: splint-bug@splint.org
+** For more information: http://www.splint.org
 */
 /*
 ** llerror.c
 ** error reporting procedures
 */
 
-# include "lclintMacros.nf"
+# include "splintMacros.nf"
 # include <string.h>
 # include <errno.h>
-# include "llbasic.h"
+# include "basic.h"
 # include "llmain.h"
-# include "version.h"
+# include "cpperror.h"
+# include "Headers/version.h" /* Visual C++ finds a different version.h on some path! */
+
+/* Don't allow possibly-recursive assertion failures. */
+# undef llassert
+# define llassert llassertprotect
 
 static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
    /*@modifies *p_stream@*/ ;
 
-# ifndef NOLCL
-static int lclerrors = 0;
-# endif
-
-static int lastfileloclen = 10;
-static /*@only@*/ cstring lastmsg = cstring_undefined;
-static int mcount = 0;
+static bool s_scanOpen = FALSE;
+static int s_lclerrors = 0;
+static size_t s_lastfileloclen = 10;
+static /*@only@*/ cstring s_lastmsg = cstring_undefined;
+static int s_mcount = 0;
 static /*@only@*/ cstring saveOneMessage = cstring_undefined;
 static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
 static /*@only@*/ fileloc lastbug = fileloc_undefined;
-static bool llgenerrorreal (/*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
-                 /*@modifies g_msgstream@*/ ;
-static bool llgenerroraux (/*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
-                 /*@modifies g_msgstream@*/ ;
+static bool llgenerrorreal (flagcode p_code, 
+                           char *p_srcFile, int p_srcLine, 
+                           /*@only@*/ cstring p_s,
+                           /*@temp@*/ cstring p_addtext,
+                           fileloc p_fl, bool p_iserror, bool p_indent)
+                 /*@modifies g_warningstream@*/ ;
+static bool llgenerroraux (flagcode p_code, char *p_srcFile, int p_srcLine, 
+                          /*@only@*/ cstring p_s,
+                          /*@temp@*/ cstring p_addtext,
+                          fileloc p_fl, bool p_iserror, bool p_indent)
+                 /*@modifies g_warningstream@*/ ;
+
+static void generateCSV (flagcode p_code, cstring p_s, cstring p_addtext, fileloc p_fl) 
+     /*@modifies g_csvstream@*/ ;
+
 static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
-   /*@globals lastfileloclen @*/
+   /*@globals s_lastfileloclen @*/
    /*@modifies *p_stream@*/ ;
 static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
    /*@modifies *p_stream@*/ ;
 
+static void llgenhint (/*@only@*/ cstring p_s) /*@modifies g_warningstream@*/ ;
+
+static void showSourceLoc (char *srcFile, int srcLine)
+     /*@modifies g_warningstream@*/
+{
+  if (context_getFlag (FLG_SHOWSOURCELOC)) {
+    llgenhint (message ("%s:%d: Source code error generation point.",
+                       cstring_fromChars (srcFile), srcLine));
+  }
+  
+}
+
 static /*@null@*/ char *
 maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
 {
@@ -67,22 +93,25 @@ maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
 static void
 printBugReport (void)
 {
-  fprintf (stderr, "     *** Please report bug to %s ***\n",
-          LCLINT_MAINTAINER);
+  fprintf (g_errorstream, "     *** Please report bug to %s ***\n",
+          SPLINT_MAINTAINER);
   llflush ();
   /* don't exit (EXIT_FAILURE); */
 }
 
 static bool s_needsPrepare = TRUE;
 
-void prepareMessage (void)
+void prepareMessage ()
 {
-  if (context_isPreprocessing ()
+  DPRINTF (("Prepare message: %s", bool_unparse (context_loadingLibrary ())));
+  showHerald ();
+
+  if ((context_isPreprocessing () || context_loadingLibrary ())
       && s_needsPrepare
-      && context_getDebug (FLG_SHOWSCAN))
+      && context_getFlag (FLG_SHOWSCAN))
     {
       llflush ();
-      fprintf (stderr, " >\n");
+      displayScanClose ();
       s_needsPrepare = FALSE;
     }
 
@@ -92,12 +121,11 @@ void prepareMessage (void)
 void closeMessage (void)
 {
   if (context_isPreprocessing ()
-      && context_getDebug (FLG_SHOWSCAN))
+      && context_getFlag (FLG_SHOWSCAN))
     {
       llflush ();
-      fprintf (stderr, "< more preprocessing .");
-
-      llassert (!s_needsPrepare);
+      displayScanOpen (cstring_makeLiteral ("more preprocessing ."));
+      llassertprotect (!s_needsPrepare);
       s_needsPrepare = TRUE;
     }
   else
@@ -111,17 +139,31 @@ llmsg (/*@only@*/ cstring s)
 {
   context_setNeednl ();
   prepareMessage ();
-  printMessage (g_msgstream, s);
+  printMessage (g_messagestream, s);
   closeMessage ();
 }
 
 void
 lldiagmsg (/*@only@*/ cstring s)
 {
+  static bool inmsg = FALSE;
+
+  if (inmsg)
+    {
+      fprintf (g_errorstream,
+              "Recursive message call detected: %s\n", 
+              cstring_toCharsSafe (s));
+      llexit (LLFAILURE);
+    }
+
+  inmsg = TRUE;
+
   context_setNeednl ();
   prepareMessage ();
-  printMessage (stderr, s);
+  printMessage (g_messagestream, s);
   closeMessage ();
+
+  inmsg = FALSE;
 }
 
 void
@@ -129,32 +171,31 @@ llmsgplain (/*@only@*/ cstring s)
 {
   context_setNeednl ();
   prepareMessage ();
-  printMessage (g_msgstream, s);
+  printMessage (g_messagestream, s);
   closeMessage ();
 }
 
-void flagWarning (cstring s)
+void llerror_flagWarning (cstring s)
 {
   if (context_getFlag (FLG_WARNFLAGS))
     {
-      showHerald ();
-
-      if (fileloc_isBuiltin (g_currentloc))
-       {
-         llmsg (message ("Warning: %s", s));
-       }
-      else
-       {
-         llgenmsg (message ("Warning: %s", s), g_currentloc);
-       }
+      llgenmsg (s, g_currentloc);
+    }
+  else
+    {
+      cstring_free (s);
     }
 }
 
 static void
-llgenhint (/*@only@*/ cstring s) /*@modifies g_msgstream@*/
+llgenhint (/*@only@*/ cstring s) /*@modifies g_warningstream@*/
 {
+  int indent = context_getIndentSpaces () - 1;
+
+  if (indent < 0) indent = 0;
+
   context_setNeednl ();
-  printIndentMessage (g_msgstream, s, 2);
+  printIndentMessage (g_warningstream, s, indent);
 }
 
 void
@@ -188,18 +229,80 @@ llshowhint (flagcode f)
     }
 }
 
+static void
+llsuppresshint2 (char c, flagcode f1, flagcode f2)
+{
+
+  if (context_getFlag (FLG_HINTS))
+    {
+      if ((flagcode_numReported (f1) == 0
+          || flagcode_numReported (f2) == 0)
+         || context_getFlag (FLG_FORCEHINTS))
+       {
+         cstring desc = flagcodeHint (f1);
+         context_setNeednl ();
+         s_lastfileloclen = 8;
+
+         if (cstring_isUndefined (desc))
+           {
+             desc = flagcodeHint (f2);
+           }
+
+         if (flagcode_isNamePrefixFlag (f1))
+           {
+             f1 = FLG_NAMECHECKS;
+           }
+
+         if (flagcode_isNamePrefixFlag (f2))
+           {
+             f2 = FLG_NAMECHECKS;
+           }
+
+         if (f1 == f2)
+           {
+             if (cstring_isDefined (desc))
+               {
+                 llgenhint (message ("%s (Use %h%s to inhibit warning)", desc,
+                                     c,
+                                     flagcode_unparse (f1)));
+               }
+             else
+               {
+                 llgenhint (message ("(Use %h%s to inhibit warning)", 
+                                     c, flagcode_unparse (f1)));
+               }
+           }
+         else
+           {
+             if (cstring_isDefined (desc))
+               {
+                 llgenhint (message ("%s (Use either %h%s or %h%s to inhibit warning)", desc, 
+                                     c,
+                                     flagcode_unparse (f1),
+                                     c,
+                                     flagcode_unparse (f2)));
+               }
+             else
+               {
+                 llgenhint (message ("(Use either %h%s or %h%s to inhibit warning)", c,
+                                     flagcode_unparse (f1),
+                                     c, flagcode_unparse (f2)));
+               }
+           }
+       }
+    }
+}
 
 static void
 llsuppresshint (char c, flagcode f)
 {
-
   if (context_getFlag (FLG_HINTS))
     {
       if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
        {
          cstring desc = flagcodeHint (f);
          context_setNeednl ();
-         lastfileloclen = 8;
+         s_lastfileloclen = 8;
 
          if (flagcode_isNamePrefixFlag (f))
            {
@@ -208,13 +311,13 @@ llsuppresshint (char c, flagcode f)
 
          if (cstring_isDefined (desc))
            {
-             llgenhint (message ("%s (%h%s will suppress message)", desc, c,
-                                 flagcode_name (f)));
+             llgenhint (message ("%s (Use %h%s to inhibit warning)", desc, c,
+                                 flagcode_unparse (f)));
            }
          else
            {
-             llgenhint (message ("(%h%s will suppress message)", c,
-                                 flagcode_name (f)));
+             llgenhint (message ("(Use %h%s to inhibit warning)", c,
+                                 flagcode_unparse (f)));
            }
        }
     }
@@ -223,16 +326,15 @@ llsuppresshint (char c, flagcode f)
 static void
 llnosuppresshint (flagcode f)
 {
-
   if (context_getFlag (FLG_FORCEHINTS))
     {
       cstring desc = flagcodeHint (f);
       context_setNeednl ();
-      lastfileloclen = 8;
+      s_lastfileloclen = 8;
 
       if (cstring_isDefined (desc))
        {
-         printError (g_msgstream, message ("    %s", desc));
+         printError (g_warningstream, message ("    %s", desc));
        }
     }
 }
@@ -245,6 +347,17 @@ llnosuppresshint (flagcode f)
 
 typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
 
+/*
+** mstring_split
+**
+** Divides a string into lines of up to maxline characters.
+**
+** Initial string: *sp
+**
+** Output split: *sp / *tp
+**                     possibly null
+*/
+
 static void
 mstring_split (/*@returned@*/ char **sp,
               /*@out@*/ nd_charp *tp,
@@ -253,9 +366,12 @@ mstring_split (/*@returned@*/ char **sp,
   char *nl;
   char *t;
   char *s = *sp;
+  char *osp = *sp;
 
   *tp = NULL;
 
+  DPRINTF (("Split: %s / %d", *sp, maxline));
+
   if (maxline < MINLINELEN)
     {
       maxline = MINLINELEN;
@@ -264,16 +380,15 @@ mstring_split (/*@returned@*/ char **sp,
   if (*indentchars > 0)
     {
       s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
+      osp = s;
     }
 
-  nl = strchr (s, '\n');
-
   /*
   ** splitting:
   **
   **    if there is a newline in first maxline characters, split there
   **    if line len is <= maxline, return no split
-  **    if there is a ':' or ';' followed by ' ' in first maxline characters,
+  **    if there is a ':' or ';' or ',' followed by ' ' in first maxline characters,
   **       split there unless the ' ' is followed by a '}', then
   **       split after '}'
   **       of the ';' is inside quotation marks
@@ -284,6 +399,8 @@ mstring_split (/*@returned@*/ char **sp,
   **
   */
 
+  nl = strchr (s, '\n');
+
   if ((nl != NULL) && ((nl - s) < maxline))
     {
       *nl = '\0';
@@ -291,6 +408,7 @@ mstring_split (/*@returned@*/ char **sp,
 
       if (*t == '\0')
        {
+         llassertprotect (*tp == NULL || (*tp > osp));
          return;
        }
 
@@ -298,21 +416,23 @@ mstring_split (/*@returned@*/ char **sp,
        {
          *indentchars += (int) (*t - '\1') + 1;
          t++;
-               }
-
+       }
+      
       *tp = t;
       return;
     }
   else if (size_toInt (strlen (s)) < maxline)
     {
+      llassertprotect (*tp == NULL);
       return;
     }
   else
     {
       int i = 0;
       char savechar;
-      char *lcolon, *lsemi, *splitat;
-
+      char *lcolon, *lsemi, *lcomma;
+      char *splitat;
+      
       splitat = NULL;
 
       t = s + maxline - 1;
@@ -321,20 +441,49 @@ mstring_split (/*@returned@*/ char **sp,
       *t = '\0';
       lcolon = strrchr (s, ':');
       lsemi = strrchr (s, ';');
+      lcomma = strrchr (s, ',');
+
       *t = savechar;
 
       splitat = maxcp (lcolon, lsemi);
 
       if (splitat != NULL && ((int)(splitat - s) > MINLINE)
-         && *(splitat + 1) == ' ' && *(splitat + 2) != '}')
+         && *(splitat) != '\0'
+         && *(splitat + 1) == ' ' 
+         && (*(splitat + 2) != '}'
+             && *(splitat + 2) != ',' 
+             && (*(splitat + 2) != '\0'))) 
        {
          *(splitat + 1) = '\0';
          t = splitat + 2;
          *tp = t;
+         llassertprotect (*tp == NULL || (*tp > osp));
          return;
        }
 
-      while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
+      if (lcomma != NULL && ((lcomma - s) > maxline - 5))
+       {
+         splitat = lcomma;
+         
+         if (splitat != NULL && ((int)(splitat - s) > MINLINE)
+             && *(splitat) != '\0'
+             && *(splitat + 1) == ' ' 
+             && (*(splitat + 2) != '}'
+                 && (*(splitat + 2) != '\0'))) 
+           {
+             *(splitat + 1) = '\0';
+             t = splitat + 2;
+             *tp = t;
+             llassertprotect (*tp == NULL || (*tp > osp));
+             return;
+           }
+       }
+      
+      /*
+      ** Search for any breaking point (at least 4 letters past s)
+      */
+
+      while (*t != ' ' && *t != '\t' && i < MAXSEARCH && t > (s + 4))
        {
          t--;
          i++;
@@ -342,24 +491,28 @@ mstring_split (/*@returned@*/ char **sp,
 
       if (*t != ' ' && *t != '\t')
        {
+         llassertprotect (maxline > 0);
          t = mstring_copy (s + maxline);
          *(s + maxline) = '\0';
 
          if (*t == '\0')
            {
              sfree (t);
+             llassertprotect (*tp == NULL || (*tp > osp));
              return;
            }
 
          mstring_markFree (t);
          *tp = t;
+         /* Won't be true since t is a copy: llassertprotect (*tp == NULL || (*tp > osp)); */
          return;
        }
       else
        {
+
          *t = '\0';
          t++;
-
+         
          if (*t == '\0') return;
 
          /*
@@ -367,15 +520,19 @@ mstring_split (/*@returned@*/ char **sp,
          */
 
          *tp = t;
+
+         llassert (*sp != *tp);
          return;
        }
     }
+
+  BADBRANCH;
 }
 
 static
 void limitmessage (/*@only@*/ cstring s, fileloc loc)
 {
-  if (mcount > context_getLimit () + 1)
+  if (s_mcount > context_getLimit () + 1)
     {
       cstring_free (s);
     }
@@ -383,7 +540,7 @@ void limitmessage (/*@only@*/ cstring s, fileloc loc)
     {
       cstring flstring = fileloc_unparse (loc);
 
-      lastfileloclen = cstring_length (flstring);
+      s_lastfileloclen = cstring_length (flstring);
       cstring_free (saveOneMessage);
       saveOneMessage = message ("%q: %q", flstring, s);
     }
@@ -401,14 +558,14 @@ void cleanupMessages ()
     }
   else
     {
-      int unprinted = mcount - context_getLimit ();
+      int unprinted = s_mcount - context_getLimit ();
 
       if (unprinted > 0)
        {
          if (unprinted == 1 && cstring_isDefined (saveOneMessage))
            {
              prepareMessage ();
-             printError (g_msgstream, saveOneMessage);
+             printError (g_warningstream, saveOneMessage);
              closeMessage ();
              saveOneMessage = cstring_undefined;
            }
@@ -420,24 +577,24 @@ void cleanupMessages ()
                  saveOneMessage = cstring_undefined;
                }
 
-             fprintf (g_msgstream, "%s: (%d more similar errors unprinted)\n",
+             fprintf (g_warningstream, "%s: (%d more similar errors unprinted)\n",
                       cstring_toCharsSafe (fileloc_filename (g_currentloc)),
-                      mcount - context_getLimit ());
+                      s_mcount - context_getLimit ());
            }
        }
     }
 
-  mcount = 0;
+  s_mcount = 0;
 }
 
 void
 llgenmsg (/*@only@*/ cstring s, fileloc fl)
 {
   cstring flstring = fileloc_unparse (fl);
-  lastfileloclen = cstring_length (flstring);
+  s_lastfileloclen = cstring_length (flstring);
 
   prepareMessage ();
-  (void) printError (g_msgstream, message ("%q: %q", flstring, s));
+  (void) printError (g_warningstream, message ("%q: %q", flstring, s));
   closeMessage ();
 }
 
@@ -445,9 +602,12 @@ void
 llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
 {
   cstring flstring = fileloc_unparse (fl);
-
+  int indentspaces = context_getLocIndentSpaces ();
   prepareMessage ();
-  (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), 3);
+  
+  (void) printIndentMessage (g_warningstream, message ("%q: %q", flstring, s),
+                            indentspaces);
+
   closeMessage ();
 }
 
@@ -455,13 +615,14 @@ void
 llgenindentmsgnoloc (/*@only@*/ cstring s)
 {
   prepareMessage ();
-  (void) printIndentMessage (g_msgstream, s, 3);
+  (void) printIndentMessage (g_warningstream, s, context_getIndentSpaces ());
   closeMessage ();
 }
 
 static bool
-  llgentypeerroraux (flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
-                    /*@only@*/ cstring s, fileloc fl)
+llgentypeerroraux (char *srcFile, int srcLine,
+                  flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
+                  /*@only@*/ cstring s, fileloc fl)
 {
   cstring hint = cstring_undefined;
   flagcode code = ocode;
@@ -469,7 +630,8 @@ static bool
   ctype ut1 = t1;
   ctype ut2 = t2;
 
-  DPRINTF (("Type error: %s / %s : %s / %s",
+  DPRINTF (("Type error [%s]: %s / %s : %s / %s",
+           flagcode_unparse (ocode),
            exprNode_unparse (e1), exprNode_unparse (e2),
            ctype_unparse (t1), ctype_unparse (t2)));
   
@@ -486,18 +648,22 @@ static bool
     ut2 = ctype_baseArrayPtr (ut2);
   }
 
-  if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
-      || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
+  if (ctype_isRealNumAbstract (ut1) && exprNode_isNumLiteral (e2)) 
+    {
+      hcode = FLG_NUMABSTRACTLIT;
+    }
+  else if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
+          || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
     {
       hcode = FLG_FLOATDOUBLE;
     }
-  else if ((exprNode_isCharLit (e1) && ctype_isInt (ut2))
-          || (exprNode_isCharLit (e2) && ctype_isInt (ut1)))
+  else if ((exprNode_isCharLiteral (e1) && ctype_isInt (ut2))
+          || (exprNode_isCharLiteral (e2) && ctype_isInt (ut1)))
     {
       hcode = FLG_CHARINTLITERAL;
     }
-  else if ((exprNode_isNumLit (e1) && ctype_isReal (ut2))
-          || (exprNode_isNumLit (e2) && ctype_isReal (ut1)))
+  else if ((exprNode_isNumLiteral (e1) && ctype_isReal (ut2))
+          || (exprNode_isNumLiteral (e2) && ctype_isReal (ut1)))
     {
       hcode = FLG_NUMLITERAL;
     }
@@ -518,7 +684,35 @@ static bool
     {
       if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
        {
-         hcode = FLG_IGNORESIGNS;
+         if (ctype_isArbitraryIntegral (ctype_realType (ut1))
+             && !ctype_isArbitraryIntegral (ctype_realType (ut2)))
+           {
+             hcode = FLG_MATCHANYINTEGRAL;
+           }
+         else if (ctype_isArbitraryIntegral (ctype_realType (ut2))
+                  && !ctype_isArbitraryIntegral (ctype_realType (ut1)))
+           {
+             hcode = FLG_MATCHANYINTEGRAL;
+           }
+         else
+           /*drl 4-270-2003 even if ignoresigns is set there may be another
+             problem that is causing splint to complain about a type error.
+             Don't tell the user that they can add +ignoresigns if it's
+             already on*/
+           {
+             DPRINTF(("TEST INGORESIGNS"));
+             if (context_getFlag(FLG_IGNORESIGNS) )
+               {
+                 DPRINTF(("INGORESIGNS SET"));
+                 hcode = FLG_IGNOREQUALS;
+               }
+           
+             else
+               {
+                 DPRINTF(("INGORESIGNS NOT SET"));
+                 hcode = FLG_IGNORESIGNS;
+               }
+           }
        }
       else
        {
@@ -527,25 +721,27 @@ static bool
     }
   else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
     {
+      DPRINTF (("HERE: %s", ctype_unparse (ctype_realType (ut2))));
+
       if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
        {
          hcode = FLG_MATCHANYINTEGRAL;
        }
-      else if (ctype_match (ut2, ctype_ulint))
+      else if (ctype_equal (ut2, ctype_ulint))
        {
          hcode = FLG_LONGUNSIGNEDINTEGRAL;
        }
-      else if (ctype_match (ut2, ctype_lint))
+      else if (ctype_equal (ut2, ctype_lint))
        {
          hcode = FLG_LONGINTEGRAL;
        }
       else if (ctype_isInt (ut2))
        {
          hcode = FLG_MATCHANYINTEGRAL;
-       }
+       }         
       else
        {
-         ;
+         hcode = FLG_TYPE;
        }
     }
   else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
@@ -595,62 +791,108 @@ static bool
          ;
        }
     }
-  else if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
+  else
+    {
+      ;
+    }
+
+  if (hcode == INVALID_FLAG)
     {
-      uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
-      ctype ct = uentry_getType (ue1);
+      DPRINTF (("[%s] %s - %s / %s",
+               ctype_unparse (ut1),
+               bool_unparse (ctype_isEnum (ut1)),
+               bool_unparse (ctype_isEnum (ctype_realType (ut1))),
+               bool_unparse (ctype_isInt (ut2))));
 
-      if (ctype_match (ct, ut2))
+      if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
        {
-         code = FLG_ABSTRACT;
-         hint = message ("Underlying types match, but %s is an "
-                         "abstract type that is not accessible here.",
-                         ctype_unparse (t1));
+         uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
+         ctype ct = uentry_getType (ue1);
+         
+         if (ctype_match (ct, ut2))
+           {
+             code = FLG_ABSTRACT;
+             hint = message ("Underlying types match, but %s is an "
+                             "abstract type that is not accessible here.",
+                             ctype_unparse (t1));
+           }
        }
-    }
-  else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
-    {
-      uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
-      ctype ct = uentry_getType (ue);
+      else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
+       {
+         uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
+         ctype ct = uentry_getType (ue);
+         
+         if (ctype_match (ct, ut1))
+           {
+             if (ctype_isNumAbstract (ut2)) 
+               {
+                 if (exprNode_isNumLiteral (e1))
+                   {
+                     code = FLG_NUMABSTRACTLIT;
+                     hint = message ("Underlying types match, but %s is a "
+                                     "numabstract type that is not accessible here. "
+                                     "(Use +numabstractlit to allow numeric literals "
+                                     "to be used as numabstract type values.)",
+                                     ctype_unparse (t2));
+                   }
+                 else
+                   {
+                     code = FLG_NUMABSTRACT;
+                     hint = message ("Underlying types match, but %s is a "
+                                     "numabstract type that is not accessible here.",
+                                     ctype_unparse (t2));
+                   }
+               }
+             else
+               {
+                 code = FLG_ABSTRACT;
+                 hint = message ("Underlying types match, but %s is an "
+                                 "abstract type that is not accessible here.",
+                                 ctype_unparse (t2));
+               }
+           }
+       }
+      else
+       {
+         ; /* Not an abstract mismatch. */
+       }
+                                      
 
-      if (ctype_match (ct, ut1))
+      if (hcode == INVALID_FLAG)
        {
-         code = FLG_ABSTRACT;
-         hint = message ("Underlying types match, but %s is an "
-                         "abstract type that is not accessible here.",
-                         ctype_unparse (t2));
+         if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
+             || (ctype_isEnum (ut2) && ctype_isInt (ut1))) 
+           {
+             hcode = FLG_ENUMINT;
+           }
+         else if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
+                  || (ctype_isEnum (ut2) && ctype_isInt (ut1))) 
+           {
+             hcode = FLG_ENUMINT;
+           }
+         else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
+                  || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
+           {
+             hcode = FLG_CHARUNSIGNEDCHAR;
+           }
+         else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2)) 
+           {
+             hcode = FLG_RELAXTYPES;
+             DPRINTF (("Setting relax types!"));
+           }
+         else
+           {
+             DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
+                       ctype_unparse (ut2)));
+           }
        }
     }
-  else if ((ctype_isEnum (ut1) && ctype_isArbitraryIntegral (ut2))
-          || (ctype_isEnum (ut2) && ctype_isArbitraryIntegral (ut1))) 
-    {
-      code = FLG_ENUMINT;
-    }
-  else if ((ctype_isEnum (ut1) && ctype_isArbitraryIntegral (ut2))
-          || (ctype_isEnum (ut2) && ctype_isArbitraryIntegral (ut1))) 
-    {
-      code = FLG_ENUMINT;
-    }
-  else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
-          || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
-    {
-      code = FLG_CHARUNSIGNEDCHAR;
-    }
-  else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2)) 
-    {
-      code = FLG_RELAXTYPES;
-    }
-  else
-    {
-      DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
-               ctype_unparse (ut2)));
-    }
 
   if (cstring_isDefined (hint))
     {
       if (!context_suppressFlagMsg (ocode, fl))
        {
-         return llgenhinterror (code, s, hint, fl);
+         return xllgenhinterror (srcFile, srcLine, code, s, hint, fl);
        }
       else
        {
@@ -661,14 +903,27 @@ static bool
     }
   else
     {
-      if (llgenerroraux (s, fl, TRUE, FALSE))
+      if (hcode != INVALID_FLAG && hcode != ocode)
        {
-         if (hcode != INVALID_FLAG && hcode != ocode)
+         code = hcode;
+       }
+      
+      if (llgenerroraux (ocode, srcFile, srcLine, s,
+                        flagcodeHint (code), fl, TRUE, FALSE))
+       {
+         if (code != ocode) 
            {
-             code = hcode;
-             llshowhint (code);
-
-           }
+             if (context_flagOn (code, fl))
+               {
+                 /* The flag is alreay set, something buggy in the flag code */
+                 llcontbug (message ("No hint available, flag %s is already set.",
+                                     flagcode_unparse (code)));
+               }
+             else
+               {
+                 llshowhint (code);
+               }
+         } 
          else
            {
              llsuppresshint ('-', code);
@@ -683,23 +938,48 @@ static bool
 }
 
 bool
-llgentypeerror (ctype t1, exprNode e1, ctype t2, exprNode e2,
-               /*@only@*/ cstring s, fileloc fl)
+xllgentypeerror (char *srcFile, int srcLine,
+                ctype t1, exprNode e1, ctype t2, exprNode e2,
+                /*@only@*/ cstring s, fileloc fl)
 {
-  return llgentypeerroraux (FLG_TYPE, t1, e1, t2, e2, s, fl);
+  return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
 }
 
 bool
-llgenformattypeerror (ctype t1, exprNode e1, ctype t2, exprNode e2,
-                     /*@only@*/ cstring s, fileloc fl)
+xllgenformattypeerror (char *srcFile, int srcLine,
+                      ctype t1, exprNode e1, ctype t2, exprNode e2,
+                      /*@only@*/ cstring s, fileloc fl)
 {
-  return llgentypeerroraux (FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
+  if (!context_suppressFlagMsg (FLG_FORMATTYPE, fl))
+    {
+      if (ctype_isInt (t1)
+         && ctype_isNumAbstract (t2))
+       {
+         if (!context_suppressFlagMsg (FLG_NUMABSTRACTPRINT, fl))
+           {
+             return llgentypeerroraux (srcFile, srcLine, FLG_NUMABSTRACTPRINT, t1, e1, t2, e2, s, fl);
+           }
+         else
+           {
+             return FALSE;
+           }
+       }
+      else
+       {
+         return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
+       }
+    }
+  else
+    {
+      cstring_free (s);
+      return FALSE;
+    }
 }
 
 bool
-llgenerror (flagcode o, /*@only@*/ cstring s, fileloc fl)
+xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
 {
-  if (llgenerroraux (s, fl, TRUE, FALSE))
+  if (llgenerroraux (o, srcFile, srcLine, s, flagcodeHint (o), fl, TRUE, FALSE))
     {
       llnosuppresshint (o);
       flagcode_recordError (o);
@@ -714,12 +994,13 @@ llgenerror (flagcode o, /*@only@*/ cstring s, fileloc fl)
 }
 
 bool
-llgenhinterror (flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
-               fileloc fl)
+xllgenhinterror (char *srcFile, int srcLine,
+                flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
+                fileloc fl)
 {
   if (!context_suppressFlagMsg (o, fl))
     {
-      if (llgenerroraux (s, fl, TRUE, FALSE))
+      if (llgenerroraux (o, srcFile, srcLine, s, hint, fl, TRUE, FALSE))
        {
          flagcode_recordError (o);
 
@@ -749,38 +1030,73 @@ llgenhinterror (flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
 }
 
 static bool
-llrealerror (/*@only@*/ cstring s, fileloc fl)
+llrealerror (flagcode code, char *srcFile, int srcLine, /*@only@*/ cstring s, /*@temp@*/ cstring addtext, fileloc fl)
 {
-  return (llgenerrorreal (s, fl, TRUE, FALSE));
+  return (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, TRUE, FALSE));
 }
 
 static bool
-llgenerroraux (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
+llgenerroraux (flagcode code,
+              char *srcFile, int srcLine,
+              /*@only@*/ cstring s, 
+              cstring addtext,
+              fileloc fl, bool iserror, bool indent)
 {
-
   if (context_inSuppressZone (fl))
     {
       cstring_free (s);
       return FALSE;
     }
-  else
-    {
-      ;
-    }
-
-  return (llgenerrorreal (s, fl, iserror, indent));
+  
+  if (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, iserror, indent)) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
 }
 
-void
-llforceerror (flagcode code, /*@only@*/ cstring s, fileloc fl)
+bool
+xllforceerror (char *srcFile, int srcLine, 
+              flagcode code, /*@only@*/ cstring s, fileloc fl)
 {
   flagcode_recordError (code);
-  (void) llgenerrorreal (s, fl, TRUE, FALSE);
-  closeMessage ();
+
+  if (llgenerrorreal (code, srcFile, srcLine, s, cstring_undefined, fl, TRUE, FALSE)) {
+    closeMessage ();
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+static void generateCSV (flagcode code, cstring s, cstring addtext, fileloc fl)
+{
+
+  if (g_csvstream != NULL) {
+    /* Warning, Flag Code, Flag Name, Priority, File, Line, Column, Warning Text, Additional Text */
+    fprintf (g_csvstream, "%d,%d,%s,%d,%s,%d,%d,\"%s\"",
+            context_numErrors (),
+            (int) code, /* flag code */
+            cstring_toCharsSafe (flagcode_unparse (code)), /* flag name */
+            flagcode_priority (code), /* priority */
+            cstring_toCharsSafe (fileloc_outputFilename (fl)),
+            fileloc_lineno (fl),
+            fileloc_column (fl),
+            cstring_toCharsSafe (s));
+
+    if (cstring_isDefined (addtext)) {
+      fprintf (g_csvstream, ",\"%s\"\n", cstring_toCharsSafe (addtext));
+    } else {
+      fprintf (g_csvstream, "\n");
+    }
+  }
 }
 
 static bool
-llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
+llgenerrorreal (flagcode code, char *srcFile, int srcLine, 
+               /*@only@*/ cstring s, 
+               cstring addtext,
+               fileloc fl, bool iserror, bool indent)
 {
   cstring flstring;
 
@@ -788,10 +1104,18 @@ llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
 
   if (!messageLog_add (context_messageLog (), fl, s))
     {
+      DPRINTF (("Duplicate message suppressed! %s / %s",
+               fileloc_unparse (fl), s));
       cstring_free (s);
       return FALSE;
     }
 
+  /*
+  ** If herald has not been displayed, display it before the first message.
+  */
+
+  showHerald ();
+
   if (iserror) context_hasError ();
 
   if (context_unlimitedMessages ())
@@ -821,16 +1145,16 @@ llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
          *savechar = ':';
        }
 
-      if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
+      if (cstring_equal (s_lastmsg, cstring_fromChars (tmpmsg)))
        {
-         mcount++;
-         if (mcount == (context_getLimit () + 1))
+         s_mcount++;
+         if (s_mcount == (context_getLimit () + 1))
            {
              limitmessage (s, fl);
              return FALSE;
            }
 
-         if (mcount > (context_getLimit ()))
+         if (s_mcount > (context_getLimit ()))
            {
              cstring_free (s);
              return FALSE;
@@ -839,12 +1163,14 @@ llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
       else
        {
          cleanupMessages ();
-         mcount = 0;
-         cstring_free (lastmsg);
-         lastmsg = cstring_fromCharsNew (tmpmsg);
+         s_mcount = 0;
+         cstring_free (s_lastmsg);
+         s_lastmsg = cstring_fromCharsNew (tmpmsg);
        }
     }
 
+  DPRINTF (("Here..."));
+
   if (context_hasAliasAnnote ())
     {
       char *sc = cstring_toCharsSafe (s);
@@ -901,24 +1227,24 @@ llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
 
       if (context_inIterDef ())
        {
-         fprintf (g_msgstream, "%s: (in iter %s)\n",
+         fprintf (g_warningstream, "%s: (in iter %s)\n",
                   cstring_toCharsSafe (fname),
                   cstring_toCharsSafe (context_inFunctionName ()));
        }
       else if (context_inIterEnd ())
        {
-         fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
+         fprintf (g_warningstream, "%s: (in iter finalizer %s)\n",
                   cstring_toCharsSafe (fname),
                   cstring_toCharsSafe (context_inFunctionName ()));
        }
       else if (context_inMacro ())
        {
-         fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
+         fprintf (g_warningstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
                   cstring_toCharsSafe (context_inFunctionName ()));
        }
       else
        {
-         fprintf (g_msgstream, "%s: (in function %s)\n",
+         fprintf (g_warningstream, "%s: (in function %s)\n",
                   cstring_toCharsSafe (fname),
                   cstring_toCharsSafe (context_inFunctionName ()));
        }
@@ -928,18 +1254,21 @@ llgenerrorreal (/*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
     }
 
   flstring = fileloc_unparse (fl);
+  s_lastfileloclen = cstring_length (flstring);
 
-  lastfileloclen = cstring_length (flstring);
+  generateCSV (code, s, addtext, fl);
 
   if (indent)
     {
-      printError (g_msgstream, message ("   %q: %q", flstring, s));
+      printError (g_warningstream, message ("   %q: %q", flstring, s));
     }
   else
     {
-      printError (g_msgstream, message ("%q: %q", flstring, s));
+      printError (g_warningstream, message ("%q: %q", flstring, s));
     }
 
+  showSourceLoc (srcFile, srcLine);
+            
   return TRUE;
 }
 
@@ -962,37 +1291,46 @@ void printMessage (FILE *stream, /*@only@*/ cstring s)
 static
 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
 {
+  static bool inbody = FALSE;
   int maxlen = context_getLineLen ();
   char *s = cstring_toCharsSafe (sc);
+  char *olds = NULL;
 
+  llassertprotect (!inbody);
+  inbody = TRUE;
 
   do
     {
       char *t = NULL;
       char *st = s;
 
+      llassertprotect (st != olds);
+      olds = st;
       mstring_split (&st, &t, maxlen, &indent);
       fprintf (stream, "%s\n", st);
-      llassert (t != s);
+      llassertprotect (t != s);
       s = t;
     } while (s != NULL) ;
 
   cstring_free (sc);
+  inbody = FALSE;
 }
 
 static
 void printError (FILE *stream, /*@only@*/ cstring sc)
 {
   int maxlen = context_getLineLen ();
-  int nspaces = lastfileloclen + 5;
-  int nextlen = maxlen - nspaces;
-  int len = cstring_length (sc);
+  size_t nspaces = s_lastfileloclen + 5;
+  int nextlen = maxlen - size_toInt (nspaces);
+  size_t len = cstring_length (sc);
   int indent = 0;
   char *s = cstring_toCharsSafe (sc);
   char *os = s;
   char *t = NULL;
 
-  if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
+  DPRINTF (("Print error: [%s]", sc));
+
+  if (size_toInt (len) < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
     {
       mstring_split (&s, &t, maxlen, &indent);
 
@@ -1002,8 +1340,8 @@ void printError (FILE *stream, /*@only@*/ cstring sc)
        {
          len = mstring_length (t);
 
-         if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
-             && len > (nextlen - 1))
+         if (size_toInt (len) < (maxlen - 3) && (strchr (t, '\n') == NULL)
+             && size_toInt (len) > (nextlen - 1))
            {
              fprintf (stream, "    %s\n", t);
            }
@@ -1012,7 +1350,7 @@ void printError (FILE *stream, /*@only@*/ cstring sc)
              char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
              int i;
 
-             for (i = 0; i < nspaces; i++)
+             for (i = 0; i < size_toInt (nspaces); i++)
                {
                  spaces[i] = ' ';
                }
@@ -1032,13 +1370,15 @@ void printError (FILE *stream, /*@only@*/ cstring sc)
     }
   else
     {
-      if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
+      DPRINTF (("Here 1: [%s]", sc));
+
+      if (size_toInt (len) < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
        {
          nspaces = ((maxlen + maxlen - 1) - len) / 2;
 
          if (nspaces < 1) nspaces = 1;
 
-         nextlen = maxlen - nspaces;
+         nextlen = size_toInt (maxlen - nspaces);
 
          mstring_split (&s, &t, maxlen, &indent);
 
@@ -1049,7 +1389,7 @@ void printError (FILE *stream, /*@only@*/ cstring sc)
              char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
              int i;
 
-             for (i = 0; i < nspaces; i++)
+             for (i = 0; i < size_toInt (nspaces); i++)
                {
                  spaces[i] = ' ';
                }
@@ -1070,16 +1410,18 @@ void printError (FILE *stream, /*@only@*/ cstring sc)
       else
        {
          nspaces = 4;
-         nextlen = maxlen - nspaces;
+         nextlen = size_toInt (maxlen - nspaces);
 
+         DPRINTF (("Here 2: [%s]", s));
          mstring_split (&s, &t, maxlen, &indent);
+         DPRINTF (("Here 3: [%s] [%s]", s, t));
 
          fprintf (stream, "%s\n", s);
 
          if (t != NULL)
            {
              char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
-             int i;
+             size_t i;
 
              for (i = 0; i < nspaces; i++)
                {
@@ -1091,8 +1433,11 @@ void printError (FILE *stream, /*@only@*/ cstring sc)
              while (t != NULL)
                {
                  char *st = t;
+                 DPRINTF (("Loop: [%s]", t));
                  mstring_split (&st, &t, nextlen, &indent);
+                 DPRINTF (("Split: [%s] [%s]", st, t));
                  fprintf (stream, "%s%s\n", spaces, st);
+                 DPRINTF (("Next..."));
                }
 
              sfree (spaces);
@@ -1100,32 +1445,32 @@ void printError (FILE *stream, /*@only@*/ cstring sc)
        }
     }
 
+  DPRINTF (("Done"));
   sfree (os);
 }
 
 void
-llfatalbug (/*@only@*/ cstring s)
+xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
 {
   prepareMessage ();
-  printError (stderr, message ("%q: *** Fatal bug: %q",
-                              fileloc_unparse (g_currentloc), s));
+  printError (g_errorstream, message ("%q: *** Fatal bug: %q",
+                                     fileloc_unparse (g_currentloc), s));
+  showSourceLoc (srcFile, srcLine);
   printCodePoint ();
   printBugReport ();
   llexit (LLFAILURE);
 }
 
-# ifndef NOLCL
 void
 lclfatalbug (char *msg)
 {
   prepareMessage ();
-  printError (stderr,
+  printError (g_errorstream,
              message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
   printCodePoint ();
   printBugReport ();
   llexit (LLFAILURE);
 }
-# endif
 
 void
 checkParseError (void)
@@ -1143,11 +1488,14 @@ void llbugaux (cstring file, int line, /*@only@*/ cstring s)
   static int numbugs = 0;
   static bool inbug = FALSE;
 
+  context_recordBug ();
+
   if (inbug)
     {
       cstring temps = fileloc_unparseRaw (file, line);
 
-      fprintf (stderr, "%s: Recursive bug detected: %s\n",
+      fprintf (g_errorstream,
+              "%s: Recursive bug detected: %s\n",
               cstring_toCharsSafe (temps),
               cstring_toCharsSafe (s));
       cstring_free (temps);
@@ -1159,108 +1507,92 @@ void llbugaux (cstring file, int line, /*@only@*/ cstring s)
 
   prepareMessage ();
 
-  if (fileloc_isRealLib (g_currentloc))
-    {
-      llfatalerror (message ("%q: Library file appears to be corrupted.  Error: %q:%s",
-                            fileloc_unparse (g_currentloc), 
-                            fileloc_unparseRaw (file, line), s));
-    }
-
   if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
     {
       llfatalerror (message ("%q: Cannot recover from parse error.",
                             fileloc_unparse (g_currentloc)));
     }
 
-  (void) fflush (g_msgstream);
-  printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
-                              fileloc_unparse (g_currentloc),
-                              fileloc_unparseRaw (file, line),
-                              s, errno));
-  printCodePoint ();
+  (void) fflush (g_warningstream);
 
-  (void) fflush (stderr);
-  perror ("Possible system error diagnostic: ");
-  (void) fflush (stderr);
+  printError (g_errorstream,
+             message ("%q: *** Internal Bug at %q: %q [errno: %d]",
+                      fileloc_unparse (g_currentloc),
+                      fileloc_unparseRaw (file, line),
+                      s, errno));
+  
+  /* printCodePoint (); no longer useful */
+
+  llflush ();
+  
+  /*
+  ** This is confusing, and hardly ever useful.
+
+  if (errno != 0)
+    {
+      perror ("Possible system error diagnostic: ");
+    }
+
+  **
+  */
 
   printBugReport ();
+  llflush ();
 
   numbugs++;
 
-  if (numbugs > 5 && fileloc_withinLines (lastbug, g_currentloc, 2))
+  if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
     {
-      llfatalerror (message ("%q: Cannot recover from last bug.",
-                            fileloc_unparse (g_currentloc)));
+      llfatalerror
+       (message ("%q: Cannot recover from last bug. "
+                 "(If you really want Splint to try to continue, use -bugslimit <n>.)",
+                 fileloc_unparse (g_currentloc)));
     }
-
-  fprintf (stderr, "       (attempting to continue, results may be incorrect)\n");
+  
+  fprintf (g_errorstream, "       (attempting to continue, results may be incorrect)\n");
   fileloc_free (lastbug);
   lastbug = fileloc_copy (g_currentloc);
   closeMessage ();
-
-  (void) fflush (stderr);
   inbug = FALSE;
 }
 
-# ifndef NOLCL
 void
 lclbug (/*@only@*/ cstring s)
 {
   prepareMessage ();
-  printError (stderr, message ("*** Internal Bug: %q", s));
+  printError (g_errorstream, message ("*** Internal Bug: %q", s));
   printCodePoint ();
   printBugReport ();
-  fprintf (stderr, "       (attempting to continue, results may be incorrect)\n");
+  fprintf (g_errorstream, "       (attempting to continue, results may be incorrect)\n");
   closeMessage ();
 }
-# endif
 
 void
-llfatalerror (cstring s)
+xllfatalerror (char *srcFile, int srcLine, cstring s)
 {
   prepareMessage ();
-  printError (stderr, s);
-  printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
+  printError (g_errorstream, s);
+  printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
+  showSourceLoc (srcFile, srcLine);
   llexit (LLFAILURE);
 }
 
 void
-llfatalerrorLoc (/*@only@*/ cstring s)
+xllfatalerrorLoc (char *srcFile, int srcLine, /*@only@*/ cstring s)
 {
   prepareMessage ();
-  (void) fflush (g_msgstream);
-  printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
-  printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
+  (void) fflush (g_warningstream);
+  printError (g_errorstream, message ("%q: %q", fileloc_unparse (g_currentloc), s));
+  printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
+  showSourceLoc (srcFile, srcLine);
+  (void) fflush (g_warningstream);
   llexit (LLFAILURE);
 }
 
-/*
-** free's s!
-*/
-
-void
-llgloberror (/*@only@*/ cstring s)
-{
-  if (context_inSuppressRegion ())
-    {
-      cstring_free (s);
-    }
-  else
-    {
-      context_setNeednl ();
-      prepareMessage ();
-      context_hasError ();
-      flagcode_recordError (FLG_SPECIAL);
-      printError (g_msgstream, s);
-      closeMessage ();
-    }
-}
-
-# ifndef NOLCL
 bool
 lclHadError (void)
 {
-  return (lclerrors > 0);
+  return (s_lclerrors > 0);
 }
 
 bool
@@ -1268,9 +1600,9 @@ lclHadNewError (void)
 {
   static int lastcall = 0;
 
-  if (lclerrors > lastcall)
+  if (s_lclerrors > lastcall)
     {
-      lastcall = lclerrors;
+      lastcall = s_lclerrors;
       return TRUE;
     }
   else
@@ -1282,50 +1614,59 @@ lclHadNewError (void)
 int
 lclNumberErrors (void)
 {
-  return (lclerrors);
+  return (s_lclerrors);
 }
 
 void
-lclerror (ltoken t, /*@only@*/ cstring msg)
+xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
 {
-  lclerrors++;
+  s_lclerrors++;
 
   if (ltoken_getCode (t) != NOTTOKEN)
     {
       cstring loc = ltoken_unparseLoc (t);
+      s_lastfileloclen = cstring_length (loc);
 
-      lastfileloclen = cstring_length (loc);
-
-      printError (g_msgstream, message ("%q: %q", loc, msg));
+      printError (g_warningstream, message ("%q: %q", loc, msg));
+      showSourceLoc (srcFile, srcLine);
     }
   else
     {
-      printError (g_msgstream, msg);
+      printError (g_warningstream, msg);
+      showSourceLoc (srcFile, srcLine);
     }
 }
 
 void
 lclplainerror (/*@only@*/ cstring msg)
 {
-  lclerrors++;
-
-  printError (g_msgstream, msg);
+  s_lclerrors++;
+  printError (g_warningstream, msg);
 }
 
 void
 lclfatalerror (ltoken t, /*@only@*/ cstring msg)
 {
-  lclerror (t, msg);
-  (void) fflush (g_msgstream);
-  printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
+  if (ltoken_getCode (t) != NOTTOKEN)
+    {
+      cstring loc = ltoken_unparseLoc (t);
+      s_lastfileloclen = cstring_length (loc);
+      printError (g_errorstream, message ("%q: %q", loc, msg));
+    }
+  else
+    {
+      printError (g_errorstream, msg);
+    }
+
+  printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue"));
   llexit (LLFAILURE);
 }
 
 void
 lclplainfatalerror (/*@only@*/ cstring msg)
 {
-  (void) fflush (g_msgstream);
-  printError (stderr, message ("*** Cannot continue: %q", msg));
+  (void) fflush (g_warningstream);
+  printError (g_errorstream, message ("*** Cannot continue: %q", msg));
   llexit (LLFAILURE);
 }
 
@@ -1349,7 +1690,6 @@ lclRedeclarationError (ltoken id)
       lclerror (id, message ("Identifier redeclared: %s", s));
     }
 }
-# endif
 
 void genppllerror (flagcode code, /*@only@*/ cstring s)
 {
@@ -1361,9 +1701,9 @@ void genppllerror (flagcode code, /*@only@*/ cstring s)
     {
       if (context_getFlag (code))
        {
-         if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
+         if (s_scanOpen)
            {
-             fprintf (g_msgstream, " >\n");
+             displayScanClose ();
            }
 
          llerror (code, s);
@@ -1373,9 +1713,9 @@ void genppllerror (flagcode code, /*@only@*/ cstring s)
              llsuppresshint ('-', code);
            }
 
-         if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
+         if (!context_isInCommandLine ())
            {
-             fprintf (stderr, "< more preprocessing .");
+             displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
            }
        }
       else
@@ -1397,6 +1737,7 @@ void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
     {
       if (context_getFlag (code))
        {
+         generateCSV (code, s, hint, g_currentloc);
          prepareMessage ();
          context_clearPreprocessing ();
          llerror (code, s);
@@ -1419,11 +1760,15 @@ void ppllerror (/*@only@*/ cstring s)
 
 void pplldiagmsg (cstring s)
 {
-  if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
+  if (!context_isInCommandLine ())
     {
-      fprintf (stderr, " >\n");
+      if (s_scanOpen) 
+       {
+         displayScanClose ();
+       }
+
       lldiagmsg (s);
-      fprintf (stderr, "< more preprocessing .");
+      displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
     }
   else
     {
@@ -1433,16 +1778,9 @@ void pplldiagmsg (cstring s)
 
 void loadllmsg (cstring s)
 {
-  if (context_getDebug (FLG_SHOWSCAN))
-    {
-      fprintf (stderr, " >\n");
-      lldiagmsg (s);
-      fprintf (stderr, "< .");
-    }
-  else
-    {
-      lldiagmsg (s);
-    }
+  displayScanClose ();
+  lldiagmsg (s);
+  displayScanOpen (cstring_makeLiteral ("< ."));
 }
 
 static void llreportparseerror (/*@only@*/ cstring s)
@@ -1460,21 +1798,55 @@ static void llreportparseerror (/*@only@*/ cstring s)
     }
 }
 
-bool lloptgenerror (flagcode o, /*@only@*/ cstring s, fileloc loc)
+bool xcppoptgenerror (char *srcFile, int srcLine,
+                     flagcode o,
+                     /*@only@*/ cstring s,
+                     cppReader *pfile)
+{
+  bool res = FALSE;
+  fileloc loc = cppReader_getLoc (pfile);
+
+  if (context_flagOn (o, loc))
+    {
+      if (xlloptgenerror (srcFile, srcLine, o, s, loc))
+       {
+         cppReader_printContainingFiles (pfile);
+         res = TRUE;
+       }
+    }
+  else
+    {
+      cstring_free (s);
+    }
+
+  fileloc_free (loc);
+
+  return res;
+}
+
+bool xlloptgenerror (char *srcFile, int srcLine, 
+                    flagcode o, /*@only@*/ cstring s, fileloc loc)
 {
-  if (llrealerror (s, loc))
+  DPRINTF (("xllopt: %s", s));
+
+  if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
     {
+      DPRINTF (("Here we are!"));
       llsuppresshint ('-', o);
       closeMessage ();
       flagcode_recordError (o);
       return TRUE;
     }
-
-  flagcode_recordSuppressed (o);
-  return FALSE;
+  else
+    {
+      DPRINTF (("Suppressed!"));
+      flagcode_recordSuppressed (o);
+      return FALSE;
+    }
 }
 
-bool optgenerror2 (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
+bool xoptgenerror2 (char *srcFile, int srcLine,
+                   flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
 {
   if (context_suppressFlagMsg (f1, loc))
     {
@@ -1490,21 +1862,25 @@ bool optgenerror2 (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
        }
       else
        {
-         if (llrealerror (s, loc))
+         if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f1), loc))
            {
-             llsuppresshint ('-', f2);
+             llsuppresshint2 ('-', f1, f2);
              flagcode_recordError (f2);
              closeMessage ();
              return TRUE;
            }
-
-         flagcode_recordSuppressed (f2);
+         else
+           {
+             flagcode_recordSuppressed (f2);
+           }
        }
     }
+
   return FALSE;
 }
 
-bool optgenerror2n (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
+bool xoptgenerror2n (char *srcFile, int srcLine,
+                    flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
 {
 
   if (context_suppressFlagMsg (f1, loc))
@@ -1521,7 +1897,7 @@ bool optgenerror2n (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
        }
       else
        {
-         if (llrealerror (s, loc))
+         if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f2), loc))
            {
              llsuppresshint ('+', f2);
              flagcode_recordError (f2);
@@ -1535,9 +1911,10 @@ bool optgenerror2n (flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
   return FALSE;
 }
 
-bool llnoptgenerror (flagcode o, /*@only@*/ cstring s, fileloc loc)
+bool xllnoptgenerror (char *srcFile, int srcLine,
+                     flagcode o, /*@only@*/ cstring s, fileloc loc)
 {
-  if (llrealerror (s, loc))
+  if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
     {
       llsuppresshint ('+', o);
       flagcode_recordError (o);
@@ -1549,7 +1926,7 @@ bool llnoptgenerror (flagcode o, /*@only@*/ cstring s, fileloc loc)
   return FALSE;
 }
 
-void llparseerror (cstring s)
+void xllparseerror (char *srcFile, int srcLine, cstring s)
 {
   if (context_getFlag (FLG_TRYTORECOVER))
     {
@@ -1559,14 +1936,16 @@ void llparseerror (cstring s)
        {
          if (cstring_isDefined (s))
            {
-             llfatalerror (message ("%q: Parse Error: %q.  "
-                                    "Too many errors, giving up.",
-                                    fileloc_unparse (g_currentloc), s));
+             xllfatalerror (srcFile, srcLine,
+                            message ("%q: Parse Error: %q.  "
+                                     "Too many errors, giving up.",
+                                     fileloc_unparse (g_currentloc), s));
            }
          else
            {
-             llfatalerror (message ("%q: Parse Error.  Too many errors, giving up.",
-                                    fileloc_unparse (g_currentloc)));
+             xllfatalerror (srcFile, srcLine,
+                            message ("%q: Parse Error.  Too many errors, giving up.",
+                                     fileloc_unparse (g_currentloc)));
            }
        }
       else
@@ -1575,10 +1954,12 @@ void llparseerror (cstring s)
            {
              llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
                                           s));
+             showSourceLoc (srcFile, srcLine);
            }
          else
            {
              llreportparseerror (message ("Parse Error. Attempting to continue."));
+             showSourceLoc (srcFile, srcLine);
            }
        }
     }
@@ -1595,13 +1976,43 @@ void llparseerror (cstring s)
          msg = message ("Parse Error.");
        }
 
-      llfatalerror
-       (message ("%q: %s (For help on parse errors, "
-                 "see lclint -help parseerrors.)",
+      xllfatalerror
+       (srcFile, srcLine,
+        message ("%q: %s (For help on parse errors, "
+                 "see splint -help parseerrors.)",
                  fileloc_unparse (g_currentloc), msg));
     }
 }
 
+bool xfsgenerror (char *srcFile, int srcLine,
+                 flagSpec fs, /*@only@*/ cstring s, fileloc fl) 
+{
+  if (flagSpec_isOn (fs, fl))
+    {
+      flagcode firston = flagSpec_getFirstOn (fs, fl);
+
+      if (llgenerroraux (firston, srcFile, srcLine, s, 
+                        flagcodeHint (firston),
+                        fl, TRUE, FALSE))
+       {
+         llsuppresshint ('-', firston);
+         flagcode_recordError (firston);
+         return TRUE;
+       }
+      else
+       {
+         flagcode_recordSuppressed (firston);
+         return FALSE;
+       }
+    }
+  else
+    {
+      flagcode_recordSuppressed (flagSpec_getDominant (fs));
+      cstring_free (s);
+      return FALSE;
+    }
+}
+
 bool doCheck (bool x, cstring pred, cstring file, int line)
 {
   if (!x) {
@@ -1647,10 +2058,10 @@ void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
 # if 0
 # ifdef HOMEVERSION
   llflush ();
-  printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
-                              fileloc_unparse (g_currentloc),
-                              fileloc_unparseRaw (file, line),
-                              s, errno));
+  printError (g_errorstream, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
+                                     fileloc_unparse (g_currentloc),
+                                     fileloc_unparseRaw (file, line),
+                                     s, errno));
   printCodePoint ();
   llflush ();
 # endif
@@ -1661,6 +2072,88 @@ void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
 
 void llflush (void)
 {
-  (void) fflush (g_msgstream);
-  (void) fflush (stderr);
+  (void) fflush (g_warningstream);
+  (void) fflush (g_messagestream);
+}
+
+void displayScan (cstring msg)
+{
+  if (s_scanOpen)
+    {
+      displayScanClose ();
+    }
+
+  llassert (!s_scanOpen);
+
+  if (context_getFlag (FLG_SHOWSCAN))
+    {
+      showHerald ();
+      fprintf (g_messagestream, "< %s >\n", cstring_toCharsSafe (msg));
+      (void) fflush (g_messagestream);
+    }
+
+  cstring_free (msg);
+}
+
+void displayScanOpen (cstring msg)
+{
+  if (s_scanOpen)
+    {
+      displayScanClose ();
+    }
+
+  llassert (!s_scanOpen);
+  s_scanOpen = TRUE;
+
+  if (context_getFlag (FLG_SHOWSCAN))
+    {
+      fprintf (g_messagestream, "< %s", cstring_toCharsSafe (msg));
+      (void) fflush (g_messagestream);
+    }
+
+  cstring_free (msg);
+}
+
+void displayScanContinue (/*@temp@*/ cstring msg)
+{
+  if (context_getFlag (FLG_SHOWSCAN))
+    {
+      if (s_scanOpen) 
+       {
+         fprintf (g_messagestream, "%s", cstring_toCharsSafe (msg));
+         (void) fflush (g_messagestream);
+       }
+      else
+       {
+         /*
+         ** Don't call bug recursively
+         */
+
+         fprintf (stderr, "*** Bug: scan continue scan not open\n");
+       }
+    }
 }
+
+void displayScanClose (void)
+{
+  if (s_scanOpen)
+    {
+      if (context_getFlag (FLG_SHOWSCAN))
+       {
+         fprintf (g_messagestream, " >\n");
+         (void) fflush (g_messagestream);
+       }
+    }
+  else
+    {
+      /*
+      ** Don't call bug recursively
+      */
+      
+      fprintf (stderr, "*** Bug: scan close scan not open\n");
+    }
+  
+  s_scanOpen = FALSE;
+}
+
+
This page took 0.153045 seconds and 4 git commands to generate.