/*
** 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
# include "splintMacros.nf"
# include <string.h>
# include <errno.h>
-# 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! */
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@*/ ;
{
cstring desc = flagcodeHint (f1);
context_setNeednl ();
- lastfileloclen = 8;
+ s_lastfileloclen = 8;
if (cstring_isUndefined (desc))
{
{
cstring desc = flagcodeHint (f);
context_setNeednl ();
- lastfileloclen = 8;
+ s_lastfileloclen = 8;
if (flagcode_isNamePrefixFlag (f))
{
{
cstring desc = flagcodeHint (f);
context_setNeednl ();
- lastfileloclen = 8;
+ s_lastfileloclen = 8;
if (cstring_isDefined (desc))
{
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,
osp = s;
}
- nl = strchr (s, '\n');
-
/*
** splitting:
**
**
*/
+ nl = strchr (s, '\n');
+
if ((nl != NULL) && ((nl - s) < maxline))
{
*nl = '\0';
}
else if (size_toInt (strlen (s)) < maxline)
{
- llassertprotect (*tp == NULL || (*tp > osp));
+ llassertprotect (*tp == NULL);
return;
}
else
}
}
- 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++;
*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;
}
}
static
void limitmessage (/*@only@*/ cstring s, fileloc loc)
{
- if (mcount > context_getLimit () + 1)
+ if (s_mcount > context_getLimit () + 1)
{
cstring_free (s);
}
{
cstring flstring = fileloc_unparse (loc);
- lastfileloclen = cstring_length (flstring);
+ s_lastfileloclen = cstring_length (flstring);
cstring_free (saveOneMessage);
saveOneMessage = message ("%q: %q", flstring, s);
}
}
else
{
- int unprinted = mcount - context_getLimit ();
+ int unprinted = s_mcount - context_getLimit ();
if (unprinted > 0)
{
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));
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 ();
}
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;
}
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
{
if (!context_suppressFlagMsg (ocode, fl))
{
- return llgenhinterror (code, s, hint, fl);
+ return xllgenhinterror (srcFile, srcLine, code, s, hint, fl);
}
else
{
}
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 */
{
llshowhint (code);
}
- }
+ }
else
{
llsuppresshint ('-', code);
{
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
{
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);
{
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);
}
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))
{
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;
{
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 {
}
}
+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;
*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;
else
{
cleanupMessages ();
- mcount = 0;
- cstring_free (lastmsg);
- lastmsg = cstring_fromCharsNew (tmpmsg);
+ s_mcount = 0;
+ cstring_free (s_lastmsg);
+ s_lastmsg = cstring_fromCharsNew (tmpmsg);
}
}
}
flstring = fileloc_unparse (fl);
- lastfileloclen = cstring_length (flstring);
+ s_lastfileloclen = cstring_length (flstring);
+
+ generateCSV (code, s, addtext, fl);
if (indent)
{
}
showSourceLoc (srcFile, srcLine);
+
return TRUE;
}
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);
if (nspaces < 1) nspaces = 1;
- nextlen = maxlen - nspaces;
+ nextlen = size_toInt (maxlen - nspaces);
mstring_split (&s, &t, maxlen, &indent);
else
{
nspaces = 4;
- nextlen = maxlen - nspaces;
+ nextlen = size_toInt (maxlen - nspaces);
DPRINTF (("Here 2: [%s]", s));
mstring_split (&s, &t, maxlen, &indent);
bool
lclHadError (void)
{
- return (lclerrors > 0);
+ return (s_lclerrors > 0);
}
bool
{
static int lastcall = 0;
- if (lclerrors > lastcall)
+ if (s_lclerrors > lastcall)
{
- lastcall = lclerrors;
+ lastcall = s_lclerrors;
return TRUE;
}
else
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);
void
lclplainerror (/*@only@*/ cstring msg)
{
- lclerrors++;
+ s_lclerrors++;
printError (g_warningstream, 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
{
if (context_getFlag (code))
{
- if (!context_isInCommandLine ())
+ if (s_scanOpen)
{
displayScanClose ();
}
{
if (context_getFlag (code))
{
+ generateCSV (code, s, hint, g_currentloc);
prepareMessage ();
context_clearPreprocessing ();
llerror (code, s);
{
if (!context_isInCommandLine ())
{
- displayScanClose ();
+ if (s_scanOpen)
+ {
+ displayScanClose ();
+ }
+
lldiagmsg (s);
displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
}
{
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);
}
else
{
- if (llrealerror (srcFile, srcLine, s, loc))
+ if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f1), loc))
{
llsuppresshint2 ('-', f1, f2);
flagcode_recordError (f2);
}
else
{
- if (llrealerror (srcFile, srcLine, s, loc))
+ if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f2), loc))
{
llsuppresshint ('+', f2);
flagcode_recordError (f2);
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);
}
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;
}
}
(void) fflush (g_messagestream);
}
-static bool s_scanOpen = FALSE;
-
void displayScan (cstring msg)
{
if (s_scanOpen)