X-Git-Url: http://andersk.mit.edu/gitweb/splint.git/blobdiff_plain/6fcd0b1e01252139211d34a4476d377cf6e5f37a..ed62d3fbeda6bb085991cdd683ceacfc57f7afbe:/src/llerror.c diff --git a/src/llerror.c b/src/llerror.c index 16ab431..4e2fc30 100644 --- a/src/llerror.c +++ b/src/llerror.c @@ -1,6 +1,6 @@ /* ** Splint - annotation-assisted static program checker -** Copyright (C) 1994-2002 University of Virginia, +** Copyright (C) 1994-2003 University of Virginia, ** Massachusetts Institute of Technology ** ** This program is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ # include "splintMacros.nf" # include # include -# include "llbasic.h" +# include "basic.h" # include "llmain.h" # include "cpperror.h" # include "Headers/version.h" /* Visual C++ finds a different version.h on some path! */ @@ -42,22 +42,31 @@ static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent) /*@modifies *p_stream@*/ ; -static int lclerrors = 0; -static size_t 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 (char *p_srcFile, int p_srcLine, - /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent) +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 (char *p_srcFile, int p_srcLine, - /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent) +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@*/ ; @@ -232,7 +241,7 @@ llsuppresshint2 (char c, flagcode f1, flagcode f2) { cstring desc = flagcodeHint (f1); context_setNeednl (); - lastfileloclen = 8; + s_lastfileloclen = 8; if (cstring_isUndefined (desc)) { @@ -293,7 +302,7 @@ llsuppresshint (char c, flagcode f) { cstring desc = flagcodeHint (f); context_setNeednl (); - lastfileloclen = 8; + s_lastfileloclen = 8; if (flagcode_isNamePrefixFlag (f)) { @@ -321,7 +330,7 @@ llnosuppresshint (flagcode f) { cstring desc = flagcodeHint (f); context_setNeednl (); - lastfileloclen = 8; + s_lastfileloclen = 8; if (cstring_isDefined (desc)) { @@ -338,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, @@ -363,8 +383,6 @@ mstring_split (/*@returned@*/ char **sp, osp = s; } - nl = strchr (s, '\n'); - /* ** splitting: ** @@ -381,6 +399,8 @@ mstring_split (/*@returned@*/ char **sp, ** */ + nl = strchr (s, '\n'); + if ((nl != NULL) && ((nl - s) < maxline)) { *nl = '\0'; @@ -403,7 +423,7 @@ mstring_split (/*@returned@*/ char **sp, } else if (size_toInt (strlen (s)) < maxline) { - llassertprotect (*tp == NULL || (*tp > osp)); + llassertprotect (*tp == NULL); return; } else @@ -459,7 +479,11 @@ mstring_split (/*@returned@*/ char **sp, } } - while (*t != ' ' && *t != '\t' && i < MAXSEARCH) + /* + ** Search for any breaking point (at least 4 letters past s) + */ + + while (*t != ' ' && *t != '\t' && i < MAXSEARCH && t > (s + 4)) { t--; i++; @@ -497,16 +521,7 @@ mstring_split (/*@returned@*/ char **sp, *tp = t; -# if 0 - /* Hack to prevent error case for wierd strings. */ - if (t <= osp) - { - *tp = NULL; - return; - } - llassertprotect (*tp == NULL || (*tp > osp)); -# endif - + llassert (*sp != *tp); return; } } @@ -517,7 +532,7 @@ mstring_split (/*@returned@*/ char **sp, static void limitmessage (/*@only@*/ cstring s, fileloc loc) { - if (mcount > context_getLimit () + 1) + if (s_mcount > context_getLimit () + 1) { cstring_free (s); } @@ -525,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); } @@ -543,7 +558,7 @@ void cleanupMessages () } else { - int unprinted = mcount - context_getLimit (); + int unprinted = s_mcount - context_getLimit (); if (unprinted > 0) { @@ -564,19 +579,19 @@ void cleanupMessages () 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_warningstream, message ("%q: %q", flstring, s)); @@ -587,9 +602,12 @@ void llgenindentmsg (/*@only@*/ cstring s, fileloc fl) { cstring flstring = fileloc_unparse (fl); - + int indentspaces = context_getLocIndentSpaces (); prepareMessage (); - (void) printIndentMessage (g_warningstream, message ("%q: %q", flstring, s), context_getIndentSpaces ()); + + (void) printIndentMessage (g_warningstream, message ("%q: %q", flstring, s), + indentspaces); + closeMessage (); } @@ -630,18 +648,22 @@ llgentypeerroraux (char *srcFile, int srcLine, 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; } @@ -785,10 +807,32 @@ llgentypeerroraux (char *srcFile, int srcLine, if (ctype_match (ct, ut1)) { - code = FLG_ABSTRACT; - hint = message ("Underlying types match, but %s is an " - "abstract type that is not accessible here.", - ctype_unparse (t2)); + 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 @@ -831,7 +875,7 @@ llgentypeerroraux (char *srcFile, int srcLine, { if (!context_suppressFlagMsg (ocode, fl)) { - return llgenhinterror (code, s, hint, fl); + return xllgenhinterror (srcFile, srcLine, code, s, hint, fl); } else { @@ -842,12 +886,16 @@ llgentypeerroraux (char *srcFile, int srcLine, } else { - if (llgenerroraux (srcFile, srcLine, 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; - if (context_flagOn (code, fl)) { /* The flag is alreay set, something buggy in the flag code */ @@ -858,7 +906,7 @@ llgentypeerroraux (char *srcFile, int srcLine, { llshowhint (code); } - } + } else { llsuppresshint ('-', code); @@ -887,7 +935,22 @@ xllgenformattypeerror (char *srcFile, int srcLine, { if (!context_suppressFlagMsg (FLG_FORMATTYPE, fl)) { - return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, 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 { @@ -899,7 +962,7 @@ xllgenformattypeerror (char *srcFile, int srcLine, bool xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl) { - if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE)) + if (llgenerroraux (o, srcFile, srcLine, s, flagcodeHint (o), fl, TRUE, FALSE)) { llnosuppresshint (o); flagcode_recordError (o); @@ -920,7 +983,7 @@ xllgenhinterror (char *srcFile, int srcLine, { if (!context_suppressFlagMsg (o, fl)) { - if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE)) + if (llgenerroraux (o, srcFile, srcLine, s, hint, fl, TRUE, FALSE)) { flagcode_recordError (o); @@ -950,14 +1013,17 @@ xllgenhinterror (char *srcFile, int srcLine, } static bool -llrealerror (char *srcFile, int srcLine, /*@only@*/ cstring s, fileloc fl) +llrealerror (flagcode code, char *srcFile, int srcLine, /*@only@*/ cstring s, /*@temp@*/ cstring addtext, fileloc fl) { - return (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)); + return (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, TRUE, FALSE)); } static bool -llgenerroraux (char *srcFile, int srcLine, - /*@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)) { @@ -965,7 +1031,7 @@ llgenerroraux (char *srcFile, int srcLine, return FALSE; } - if (llgenerrorreal (srcFile, srcLine, s, fl, iserror, indent)) { + if (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, iserror, indent)) { return TRUE; } else { return FALSE; @@ -978,7 +1044,7 @@ xllforceerror (char *srcFile, int srcLine, { flagcode_recordError (code); - if (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)) { + if (llgenerrorreal (code, srcFile, srcLine, s, cstring_undefined, fl, TRUE, FALSE)) { closeMessage (); return TRUE; } else { @@ -986,9 +1052,34 @@ xllforceerror (char *srcFile, int srcLine, } } +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 (char *srcFile, int srcLine, - /*@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; @@ -1037,16 +1128,16 @@ llgenerrorreal (char *srcFile, int srcLine, *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; @@ -1055,9 +1146,9 @@ llgenerrorreal (char *srcFile, int srcLine, else { cleanupMessages (); - mcount = 0; - cstring_free (lastmsg); - lastmsg = cstring_fromCharsNew (tmpmsg); + s_mcount = 0; + cstring_free (s_lastmsg); + s_lastmsg = cstring_fromCharsNew (tmpmsg); } } @@ -1146,7 +1237,9 @@ llgenerrorreal (char *srcFile, int srcLine, } flstring = fileloc_unparse (fl); - lastfileloclen = cstring_length (flstring); + s_lastfileloclen = cstring_length (flstring); + + generateCSV (code, s, addtext, fl); if (indent) { @@ -1158,6 +1251,7 @@ llgenerrorreal (char *srcFile, int srcLine, } showSourceLoc (srcFile, srcLine); + return TRUE; } @@ -1209,8 +1303,8 @@ static void printError (FILE *stream, /*@only@*/ cstring sc) { int maxlen = context_getLineLen (); - size_t nspaces = lastfileloclen + 5; - int nextlen = maxlen - nspaces; + 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); @@ -1267,7 +1361,7 @@ void printError (FILE *stream, /*@only@*/ cstring sc) if (nspaces < 1) nspaces = 1; - nextlen = maxlen - nspaces; + nextlen = size_toInt (maxlen - nspaces); mstring_split (&s, &t, maxlen, &indent); @@ -1299,7 +1393,7 @@ 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); @@ -1479,7 +1573,7 @@ xllfatalerrorLoc (char *srcFile, int srcLine, /*@only@*/ cstring s) bool lclHadError (void) { - return (lclerrors > 0); + return (s_lclerrors > 0); } bool @@ -1487,9 +1581,9 @@ lclHadNewError (void) { static int lastcall = 0; - if (lclerrors > lastcall) + if (s_lclerrors > lastcall) { - lastcall = lclerrors; + lastcall = s_lclerrors; return TRUE; } else @@ -1501,18 +1595,18 @@ lclHadNewError (void) int lclNumberErrors (void) { - return (lclerrors); + return (s_lclerrors); } void xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg) { - lclerrors++; + s_lclerrors++; if (ltoken_getCode (t) != NOTTOKEN) { cstring loc = ltoken_unparseLoc (t); - lastfileloclen = cstring_length (loc); + s_lastfileloclen = cstring_length (loc); printError (g_warningstream, message ("%q: %q", loc, msg)); showSourceLoc (srcFile, srcLine); @@ -1527,7 +1621,7 @@ xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg) void lclplainerror (/*@only@*/ cstring msg) { - lclerrors++; + s_lclerrors++; printError (g_warningstream, msg); } @@ -1537,7 +1631,7 @@ lclfatalerror (ltoken t, /*@only@*/ cstring msg) if (ltoken_getCode (t) != NOTTOKEN) { cstring loc = ltoken_unparseLoc (t); - lastfileloclen = cstring_length (loc); + s_lastfileloclen = cstring_length (loc); printError (g_errorstream, message ("%q: %q", loc, msg)); } else @@ -1588,7 +1682,7 @@ void genppllerror (flagcode code, /*@only@*/ cstring s) { if (context_getFlag (code)) { - if (!context_isInCommandLine ()) + if (s_scanOpen) { displayScanClose (); } @@ -1624,6 +1718,7 @@ void genppllerrorhint (flagcode code, /*@only@*/ cstring s, { if (context_getFlag (code)) { + generateCSV (code, s, hint, g_currentloc); prepareMessage (); context_clearPreprocessing (); llerror (code, s); @@ -1648,7 +1743,11 @@ void pplldiagmsg (cstring s) { if (!context_isInCommandLine ()) { - displayScanClose (); + if (s_scanOpen) + { + displayScanClose (); + } + lldiagmsg (s); displayScanOpen (cstring_makeLiteral ("< more preprocessing .")); } @@ -1711,7 +1810,7 @@ bool xlloptgenerror (char *srcFile, int srcLine, { DPRINTF (("xllopt: %s", s)); - if (llrealerror (srcFile, srcLine, s, loc)) + if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc)) { DPRINTF (("Here we are!")); llsuppresshint ('-', o); @@ -1744,7 +1843,7 @@ bool xoptgenerror2 (char *srcFile, int srcLine, } else { - if (llrealerror (srcFile, srcLine, s, loc)) + if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f1), loc)) { llsuppresshint2 ('-', f1, f2); flagcode_recordError (f2); @@ -1779,7 +1878,7 @@ bool xoptgenerror2n (char *srcFile, int srcLine, } else { - if (llrealerror (srcFile, srcLine, s, loc)) + if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f2), loc)) { llsuppresshint ('+', f2); flagcode_recordError (f2); @@ -1796,7 +1895,7 @@ bool xoptgenerror2n (char *srcFile, int srcLine, bool xllnoptgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc loc) { - if (llrealerror (srcFile, srcLine, s, loc)) + if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc)) { llsuppresshint ('+', o); flagcode_recordError (o); @@ -1867,19 +1966,23 @@ void xllparseerror (char *srcFile, int srcLine, cstring s) } bool xfsgenerror (char *srcFile, int srcLine, - flagSpec fs, /*@only@*/ cstring s, fileloc fl) + flagSpec fs, /*@only@*/ cstring s, fileloc fl) { if (flagSpec_isOn (fs, fl)) { - if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE)) + flagcode firston = flagSpec_getFirstOn (fs, fl); + + if (llgenerroraux (firston, srcFile, srcLine, s, + flagcodeHint (firston), + fl, TRUE, FALSE)) { - llsuppresshint ('-', flagSpec_getFirstOn (fs, fl)); - flagcode_recordError (flagSpec_getFirstOn (fs, fl)); + llsuppresshint ('-', firston); + flagcode_recordError (firston); return TRUE; } else { - flagcode_recordSuppressed (flagSpec_getFirstOn (fs, fl)); + flagcode_recordSuppressed (firston); return FALSE; } } @@ -1954,8 +2057,6 @@ void llflush (void) (void) fflush (g_messagestream); } -static bool s_scanOpen = FALSE; - void displayScan (cstring msg) { if (s_scanOpen)