2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
4 ** Massachusetts Institute of Technology
6 ** This program is free software; you can redistribute it and/or modify it
7 ** under the terms of the GNU General Public License as published by the
8 ** Free Software Foundation; either version 2 of the License, or (at your
9 ** option) any later version.
11 ** This program is distributed in the hope that it will be useful, but
12 ** WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** General Public License for more details.
16 ** The GNU General Public License is available from http://www.gnu.org/ or
17 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
18 ** MA 02111-1307, USA.
20 ** For information on lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://www.splint.org
27 ** error reporting procedures
30 # include "lclintMacros.nf"
35 # include "cpperror.h"
38 /* Don't allow possibly-recursive assertion failures. */
40 # define llassert llassertprotect
42 static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
43 /*@modifies *p_stream@*/ ;
46 static int lclerrors = 0;
49 static int lastfileloclen = 10;
50 static /*@only@*/ cstring lastmsg = cstring_undefined;
51 static int mcount = 0;
52 static /*@only@*/ cstring saveOneMessage = cstring_undefined;
53 static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
54 static /*@only@*/ fileloc lastbug = fileloc_undefined;
55 static bool llgenerrorreal (char *p_srcFile, int p_srcLine,
56 /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
57 /*@modifies g_msgstream@*/ ;
58 static bool llgenerroraux (char *p_srcFile, int p_srcLine,
59 /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
60 /*@modifies g_msgstream@*/ ;
62 static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
63 /*@globals lastfileloclen @*/
64 /*@modifies *p_stream@*/ ;
65 static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
66 /*@modifies *p_stream@*/ ;
68 static void llgenhint (/*@only@*/ cstring p_s) /*@modifies g_msgstream@*/ ;
70 static void showSourceLoc (char *srcFile, int srcLine)
71 /*@modifies g_msgstream@*/
73 if (context_getFlag (FLG_SHOWSOURCELOC)) {
74 llgenhint (message ("%s:%d: Source code error generation point.",
75 cstring_fromChars (srcFile), srcLine));
80 static /*@null@*/ char *
81 maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
90 fprintf (stderr, " *** Please report bug to %s ***\n",
93 /* don't exit (EXIT_FAILURE); */
96 static bool s_needsPrepare = TRUE;
98 void prepareMessage (void)
100 DPRINTF (("Prepare message: %s", bool_unparse (context_loadingLibrary ())));
103 if ((context_isPreprocessing () || context_loadingLibrary ())
105 && context_getDebug (FLG_SHOWSCAN))
108 fprintf (stderr, " >\n");
109 s_needsPrepare = FALSE;
115 void closeMessage (void)
117 if (context_isPreprocessing ()
118 && context_getDebug (FLG_SHOWSCAN))
121 fprintf (stderr, "< more preprocessing .");
123 llassertprotect (!s_needsPrepare);
124 s_needsPrepare = TRUE;
133 llmsg (/*@only@*/ cstring s)
135 context_setNeednl ();
137 printMessage (g_msgstream, s);
142 lldiagmsg (/*@only@*/ cstring s)
144 context_setNeednl ();
146 printMessage (stderr, s);
151 llmsgplain (/*@only@*/ cstring s)
153 context_setNeednl ();
155 printMessage (g_msgstream, s);
159 void llerror_flagWarning (cstring s)
161 if (context_getFlag (FLG_WARNFLAGS))
165 if (fileloc_isBuiltin (g_currentloc))
167 llmsg (message ("Warning: %q", s));
171 llgenmsg (message ("Warning: %q", s), g_currentloc);
181 llgenhint (/*@only@*/ cstring s) /*@modifies g_msgstream@*/
183 int indent = context_getIndentSpaces () - 1;
185 if (indent < 0) indent = 0;
187 context_setNeednl ();
188 printIndentMessage (g_msgstream, s, indent);
194 if (context_getFlag (FLG_HINTS) &&
195 !(context_inSuppressRegion () || context_inSuppressZone (g_currentloc)))
206 llshowhint (flagcode f)
208 if (context_getFlag (FLG_HINTS))
210 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
212 cstring desc = flagcodeHint (f);
214 if (cstring_isDefined (desc))
216 llgenhint (cstring_copy (desc));
223 llsuppresshint2 (char c, flagcode f1, flagcode f2)
226 if (context_getFlag (FLG_HINTS))
228 if ((flagcode_numReported (f1) == 0
229 || flagcode_numReported (f2) == 0)
230 || context_getFlag (FLG_FORCEHINTS))
232 cstring desc = flagcodeHint (f1);
233 context_setNeednl ();
236 if (cstring_isUndefined (desc))
238 desc = flagcodeHint (f2);
241 if (flagcode_isNamePrefixFlag (f1))
246 if (flagcode_isNamePrefixFlag (f2))
253 if (cstring_isDefined (desc))
255 llgenhint (message ("%s (Setting %h%s will suppress message)", desc,
257 flagcode_unparse (f1)));
261 llgenhint (message ("(Setting %h%s will suppress message)",
262 c, flagcode_unparse (f1)));
267 if (cstring_isDefined (desc))
269 llgenhint (message ("%s (Setting either %h%s or %h%s will suppress message)", desc,
271 flagcode_unparse (f1),
273 flagcode_unparse (f2)));
277 llgenhint (message ("(Setting either %h%s or %h%s will suppress message)", c,
278 flagcode_unparse (f1),
279 c, flagcode_unparse (f2)));
287 llsuppresshint (char c, flagcode f)
289 if (context_getFlag (FLG_HINTS))
291 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
293 cstring desc = flagcodeHint (f);
294 context_setNeednl ();
297 if (flagcode_isNamePrefixFlag (f))
302 if (cstring_isDefined (desc))
304 llgenhint (message ("%s (%h%s will suppress message)", desc, c,
305 flagcode_unparse (f)));
309 llgenhint (message ("(%h%s will suppress message)", c,
310 flagcode_unparse (f)));
317 llnosuppresshint (flagcode f)
319 if (context_getFlag (FLG_FORCEHINTS))
321 cstring desc = flagcodeHint (f);
322 context_setNeednl ();
325 if (cstring_isDefined (desc))
327 printError (g_msgstream, message (" %s", desc));
332 /*@constant int MAXSEARCH; @*/
333 # define MAXSEARCH 20
335 /*@constant int MINLINE; @*/
338 typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
341 mstring_split (/*@returned@*/ char **sp,
342 /*@out@*/ nd_charp *tp,
343 int maxline, /*@in@*/ int *indentchars)
352 DPRINTF (("Split: %s / %d", *sp, maxline));
354 if (maxline < MINLINELEN)
356 maxline = MINLINELEN;
359 if (*indentchars > 0)
361 s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
365 nl = strchr (s, '\n');
370 ** if there is a newline in first maxline characters, split there
371 ** if line len is <= maxline, return no split
372 ** if there is a ':' or ';' followed by ' ' in first maxline characters,
373 ** split there unless the ' ' is followed by a '}', then
375 ** of the ';' is inside quotation marks
376 ** if there is a space or tab in last maxsearch characters, split there
377 ** else, split at maxline
379 ** special code: slash [1-9] after a newline means indent the rest <n> chars
383 if ((nl != NULL) && ((nl - s) < maxline))
390 llassertprotect (*tp == NULL || (*tp > osp));
394 if (*t >= '\1' && *t <= '\7')
396 *indentchars += (int) (*t - '\1') + 1;
403 else if (size_toInt (strlen (s)) < maxline)
405 llassertprotect (*tp == NULL || (*tp > osp));
412 char *lcolon, *lsemi, *splitat;
420 lcolon = strrchr (s, ':');
421 lsemi = strrchr (s, ';');
424 splitat = maxcp (lcolon, lsemi);
426 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
427 && *(splitat) != '\0'
428 && *(splitat + 1) == ' '
429 && (*(splitat + 2) != '}' && (*(splitat + 2) != '\0')))
431 *(splitat + 1) = '\0';
434 llassertprotect (*tp == NULL || (*tp > osp));
438 while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
444 if (*t != ' ' && *t != '\t')
446 llassertprotect (maxline > 0);
447 t = mstring_copy (s + maxline);
448 *(s + maxline) = '\0';
453 llassertprotect (*tp == NULL || (*tp > osp));
457 mstring_markFree (t);
459 /* Won't be true since t is a copy: llassertprotect (*tp == NULL || (*tp > osp)); */
468 if (*t == '\0') return;
471 ** returns unqualified as only
477 /* Hack to prevent error case for wierd strings. */
483 llassertprotect (*tp == NULL || (*tp > osp));
494 void limitmessage (/*@only@*/ cstring s, fileloc loc)
496 if (mcount > context_getLimit () + 1)
502 cstring flstring = fileloc_unparse (loc);
504 lastfileloclen = cstring_length (flstring);
505 cstring_free (saveOneMessage);
506 saveOneMessage = message ("%q: %q", flstring, s);
510 static int parseerrorcount = 0;
512 void cleanupMessages ()
516 if (context_unlimitedMessages ())
522 int unprinted = mcount - context_getLimit ();
526 if (unprinted == 1 && cstring_isDefined (saveOneMessage))
529 printError (g_msgstream, saveOneMessage);
531 saveOneMessage = cstring_undefined;
535 if (cstring_isDefined (saveOneMessage))
537 /* cstring_free (saveOneMessage); */
538 saveOneMessage = cstring_undefined;
541 fprintf (g_msgstream, "%s: (%d more similar errors unprinted)\n",
542 cstring_toCharsSafe (fileloc_filename (g_currentloc)),
543 mcount - context_getLimit ());
552 llgenmsg (/*@only@*/ cstring s, fileloc fl)
554 cstring flstring = fileloc_unparse (fl);
555 lastfileloclen = cstring_length (flstring);
558 (void) printError (g_msgstream, message ("%q: %q", flstring, s));
563 llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
565 cstring flstring = fileloc_unparse (fl);
568 (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), context_getIndentSpaces ());
573 llgenindentmsgnoloc (/*@only@*/ cstring s)
576 (void) printIndentMessage (g_msgstream, s, context_getIndentSpaces ());
581 llgentypeerroraux (char *srcFile, int srcLine,
582 flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
583 /*@only@*/ cstring s, fileloc fl)
585 cstring hint = cstring_undefined;
586 flagcode code = ocode;
587 flagcode hcode = INVALID_FLAG;
591 DPRINTF (("Type error [%s]: %s / %s : %s / %s",
592 flagcode_unparse (ocode),
593 exprNode_unparse (e1), exprNode_unparse (e2),
594 ctype_unparse (t1), ctype_unparse (t2)));
596 DPRINTF (("Bool: %s / %s",
597 bool_unparse (ctype_isBool (t1)),
598 bool_unparse (ctype_isBool (t2))));
601 ** Set the flag using the underlying types that didn't match.
604 while (ctype_isPointer (ut1) && ctype_isPointer (ut2)) {
605 ut1 = ctype_baseArrayPtr (ut1);
606 ut2 = ctype_baseArrayPtr (ut2);
609 if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
610 || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
612 hcode = FLG_FLOATDOUBLE;
614 else if ((exprNode_isCharLit (e1) && ctype_isInt (ut2))
615 || (exprNode_isCharLit (e2) && ctype_isInt (ut1)))
617 hcode = FLG_CHARINTLITERAL;
619 else if ((exprNode_isNumLit (e1) && ctype_isReal (ut2))
620 || (exprNode_isNumLit (e2) && ctype_isReal (ut1)))
622 hcode = FLG_NUMLITERAL;
624 else if ((ctype_isManifestBool (ut1) && ctype_isInt (ut2))
625 || (ctype_isInt (ut1) && ctype_isManifestBool (ut2)))
626 /* evs 2000-07-24: was ctype_isDirectBool */
630 else if (((ctype_isChar (ut1) && !ctype_isInt (ut1)) && ctype_isInt (ut2))
631 || ((ctype_isInt (ut1) && (ctype_isChar (ut2) && !ctype_isInt (ut2)))))
635 else if ((ctype_isInt (ut1) && ctype_isInt (ut2))
636 || (ctype_isChar (ut1) && ctype_isChar (ut2))
637 || (ctype_isDouble (ut1) && ctype_isDouble (ut2)))
639 if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
641 hcode = FLG_IGNORESIGNS;
645 hcode = FLG_IGNOREQUALS;
648 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
650 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
652 hcode = FLG_MATCHANYINTEGRAL;
654 else if (ctype_match (ut2, ctype_ulint))
656 hcode = FLG_LONGUNSIGNEDINTEGRAL;
658 else if (ctype_match (ut2, ctype_lint))
660 hcode = FLG_LONGINTEGRAL;
662 else if (ctype_isInt (ut2))
664 hcode = FLG_MATCHANYINTEGRAL;
671 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
673 ctype tr = ctype_realType (ut1);
675 if (ctype_isArbitraryIntegral (tr))
677 hcode = FLG_MATCHANYINTEGRAL;
679 else if (ctype_match (ut1, ctype_ulint))
681 if (ctype_isUnsignedIntegral (tr))
683 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
685 else if (ctype_isSignedIntegral (tr))
691 hcode = FLG_LONGUNSIGNEDINTEGRAL;
694 else if (ctype_match (ut1, ctype_lint))
696 if (ctype_isSignedIntegral (tr))
698 hcode = FLG_LONGSIGNEDINTEGRAL;
700 else if (ctype_isSignedIntegral (tr))
706 hcode = FLG_LONGINTEGRAL;
709 else if (ctype_isInt (ut1))
711 hcode = FLG_MATCHANYINTEGRAL;
723 if (hcode == INVALID_FLAG)
725 DPRINTF (("[%s] %s - %s / %s",
727 bool_unparse (ctype_isEnum (ut1)),
728 bool_unparse (ctype_isEnum (ctype_realType (ut1))),
729 bool_unparse (ctype_isInt (ut2))));
731 if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
733 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
734 ctype ct = uentry_getType (ue1);
736 if (ctype_match (ct, ut2))
739 hint = message ("Underlying types match, but %s is an "
740 "abstract type that is not accessible here.",
744 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
746 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
747 ctype ct = uentry_getType (ue);
749 if (ctype_match (ct, ut1))
752 hint = message ("Underlying types match, but %s is an "
753 "abstract type that is not accessible here.",
759 ; /* Not an abstract mismatch. */
763 if (hcode == INVALID_FLAG)
765 if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
766 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
770 else if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
771 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
775 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
776 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
778 hcode = FLG_CHARUNSIGNEDCHAR;
780 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
782 hcode = FLG_RELAXTYPES;
783 DPRINTF (("Setting relax types!"));
787 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
788 ctype_unparse (ut2)));
793 if (cstring_isDefined (hint))
795 if (!context_suppressFlagMsg (ocode, fl))
797 return llgenhinterror (code, s, hint, fl);
808 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
810 if (hcode != INVALID_FLAG && hcode != ocode)
818 llsuppresshint ('-', code);
821 flagcode_recordError (code);
830 xllgentypeerror (char *srcFile, int srcLine,
831 ctype t1, exprNode e1, ctype t2, exprNode e2,
832 /*@only@*/ cstring s, fileloc fl)
834 return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
838 xllgenformattypeerror (char *srcFile, int srcLine,
839 ctype t1, exprNode e1, ctype t2, exprNode e2,
840 /*@only@*/ cstring s, fileloc fl)
842 if (!context_suppressFlagMsg (FLG_FORMATTYPE, fl))
844 return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
854 xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
856 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
858 llnosuppresshint (o);
859 flagcode_recordError (o);
865 flagcode_recordSuppressed (o);
871 xllgenhinterror (char *srcFile, int srcLine,
872 flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
875 if (!context_suppressFlagMsg (o, fl))
877 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
879 flagcode_recordError (o);
881 if (context_getFlag (FLG_HINTS))
902 flagcode_recordSuppressed (o);
907 llrealerror (char *srcFile, int srcLine, /*@only@*/ cstring s, fileloc fl)
909 return (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE));
913 llgenerroraux (char *srcFile, int srcLine,
914 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
916 if (context_inSuppressZone (fl))
922 if (llgenerrorreal (srcFile, srcLine, s, fl, iserror, indent)) {
930 xllforceerror (char *srcFile, int srcLine,
931 flagcode code, /*@only@*/ cstring s, fileloc fl)
933 flagcode_recordError (code);
935 if (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)) {
944 llgenerrorreal (char *srcFile, int srcLine,
945 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
949 /* duplicate message (rescanning a header file */
951 if (!messageLog_add (context_messageLog (), fl, s))
953 DPRINTF (("Duplicate message suppressed! %s / %s",
954 fileloc_unparse (fl), s));
960 ** If herald has not been displayed, display it before the first message.
965 if (iserror) context_hasError ();
967 if (context_unlimitedMessages ())
974 ** suppress excessive messages:
979 char *sc = cstring_toCharsSafe (s);
980 char *tmpmsg = strchr (sc, ':');
988 char *savechar = tmpmsg;
994 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
997 if (mcount == (context_getLimit () + 1))
999 limitmessage (s, fl);
1003 if (mcount > (context_getLimit ()))
1013 cstring_free (lastmsg);
1014 lastmsg = cstring_fromCharsNew (tmpmsg);
1018 DPRINTF (("Here..."));
1020 if (context_hasAliasAnnote ())
1022 char *sc = cstring_toCharsSafe (s);
1023 char *fcolon = strchr (sc, ':');
1024 cstring a = context_getAliasAnnote ();
1029 s = message ("%q (%q)", s, a);
1036 afterColon = cstring_fromCharsNew (fcolon + 1);
1038 s = message ("%q (%q):%q", s, a, afterColon);
1042 if (context_hasMessageAnnote ())
1044 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1049 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1050 s = message ("%q (%q)", s, context_getMessageAnnote ());
1051 /*@=dependenttrans@*/
1058 afterColon = cstring_fromCharsNew (fcolon + 1);
1060 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1061 s = message ("%q (%q):%q", s,
1062 context_getMessageAnnote (), afterColon);
1063 /*@=dependenttrans@*/
1067 context_setNeednl ();
1070 if (context_showFunction ())
1072 cstring fname = fileloc_unparseFilename (g_currentloc);
1074 if (context_inIterDef ())
1076 fprintf (g_msgstream, "%s: (in iter %s)\n",
1077 cstring_toCharsSafe (fname),
1078 cstring_toCharsSafe (context_inFunctionName ()));
1080 else if (context_inIterEnd ())
1082 fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
1083 cstring_toCharsSafe (fname),
1084 cstring_toCharsSafe (context_inFunctionName ()));
1086 else if (context_inMacro ())
1088 fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
1089 cstring_toCharsSafe (context_inFunctionName ()));
1093 fprintf (g_msgstream, "%s: (in function %s)\n",
1094 cstring_toCharsSafe (fname),
1095 cstring_toCharsSafe (context_inFunctionName ()));
1098 cstring_free (fname);
1099 context_setShownFunction ();
1102 flstring = fileloc_unparse (fl);
1103 lastfileloclen = cstring_length (flstring);
1107 printError (g_msgstream, message (" %q: %q", flstring, s));
1111 printError (g_msgstream, message ("%q: %q", flstring, s));
1114 showSourceLoc (srcFile, srcLine);
1121 ** message contains no '\n'
1122 ** message fits in one line: print it
1123 ** message fits in two lines with 3-space indent after fileloc: print it
1124 ** split line with 5-space indent from left margin: print it
1129 void printMessage (FILE *stream, /*@only@*/ cstring s)
1131 printIndentMessage (stream, s, 0);
1135 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1137 static bool inbody = FALSE;
1138 int maxlen = context_getLineLen ();
1139 char *s = cstring_toCharsSafe (sc);
1142 llassertprotect (!inbody);
1150 llassertprotect (st != olds);
1152 mstring_split (&st, &t, maxlen, &indent);
1153 fprintf (stream, "%s\n", st);
1154 llassertprotect (t != s);
1156 } while (s != NULL) ;
1163 void printError (FILE *stream, /*@only@*/ cstring sc)
1165 int maxlen = context_getLineLen ();
1166 int nspaces = lastfileloclen + 5;
1167 int nextlen = maxlen - nspaces;
1168 int len = cstring_length (sc);
1170 char *s = cstring_toCharsSafe (sc);
1174 DPRINTF (("Print error: [%s]", sc));
1176 if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
1178 mstring_split (&s, &t, maxlen, &indent);
1180 fprintf (stream, "%s\n", s);
1184 len = mstring_length (t);
1186 if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1187 && len > (nextlen - 1))
1189 fprintf (stream, " %s\n", t);
1193 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1196 for (i = 0; i < nspaces; i++)
1201 spaces[nspaces] = '\0';
1206 mstring_split (&st, &t, nextlen, &indent);
1207 fprintf (stream, "%s%s\n", spaces, st);
1216 DPRINTF (("Here 1: [%s]", sc));
1218 if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1220 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1222 if (nspaces < 1) nspaces = 1;
1224 nextlen = maxlen - nspaces;
1226 mstring_split (&s, &t, maxlen, &indent);
1228 fprintf (stream, "%s\n", s);
1232 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1235 for (i = 0; i < nspaces; i++)
1240 spaces[nspaces] = '\0';
1246 mstring_split (&st, &t, nextlen, &indent);
1247 fprintf (stream, "%s%s\n", spaces, st);
1256 nextlen = maxlen - nspaces;
1258 DPRINTF (("Here 2: [%s]", s));
1259 mstring_split (&s, &t, maxlen, &indent);
1260 DPRINTF (("Here 3: [%s] [%s]", s, t));
1262 fprintf (stream, "%s\n", s);
1266 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1269 for (i = 0; i < nspaces; i++)
1274 spaces[nspaces] = '\0';
1279 DPRINTF (("Loop: [%s]", t));
1280 mstring_split (&st, &t, nextlen, &indent);
1281 DPRINTF (("Split: [%s] [%s]", st, t));
1282 fprintf (stream, "%s%s\n", spaces, st);
1283 DPRINTF (("Next..."));
1296 xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
1299 printError (stderr, message ("%q: *** Fatal bug: %q",
1300 fileloc_unparse (g_currentloc), s));
1301 showSourceLoc (srcFile, srcLine);
1309 lclfatalbug (char *msg)
1313 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1321 checkParseError (void)
1323 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1325 llfatalerror (message ("%q: Cannot recover from parse error.",
1326 fileloc_unparse (g_currentloc)));
1330 void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1333 static int numbugs = 0;
1334 static bool inbug = FALSE;
1338 cstring temps = fileloc_unparseRaw (file, line);
1340 fprintf (stderr, "%s: Recursive bug detected: %s\n",
1341 cstring_toCharsSafe (temps),
1342 cstring_toCharsSafe (s));
1343 cstring_free (temps);
1354 if (fileloc_isRealLib (g_currentloc))
1356 DPRINTF (("Here we are!"));
1357 llfatalerror (message ("%q: Library file appears to be corrupted. Error: %q: %s",
1358 fileloc_unparse (g_currentloc),
1359 fileloc_unparseRaw (file, line),
1364 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1366 llfatalerror (message ("%q: Cannot recover from parse error.",
1367 fileloc_unparse (g_currentloc)));
1370 (void) fflush (g_msgstream);
1371 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1372 fileloc_unparse (g_currentloc),
1373 fileloc_unparseRaw (file, line),
1377 (void) fflush (stderr);
1380 perror ("Possible system error diagnostic: ");
1382 (void) fflush (stderr);
1388 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
1390 llfatalerror (message ("%q: Cannot recover from last bug. (If you really want Splint to try to continue, use -bugslimit <n>.)",
1391 fileloc_unparse (g_currentloc)));
1394 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1395 fileloc_free (lastbug);
1396 lastbug = fileloc_copy (g_currentloc);
1399 (void) fflush (stderr);
1405 lclbug (/*@only@*/ cstring s)
1408 printError (stderr, message ("*** Internal Bug: %q", s));
1411 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1417 llfatalerror (cstring s)
1420 printError (stderr, s);
1421 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1426 llfatalerrorLoc (/*@only@*/ cstring s)
1429 (void) fflush (g_msgstream);
1430 printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1431 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1432 (void) fflush (g_msgstream);
1440 return (lclerrors > 0);
1444 lclHadNewError (void)
1446 static int lastcall = 0;
1448 if (lclerrors > lastcall)
1450 lastcall = lclerrors;
1460 lclNumberErrors (void)
1466 xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
1470 if (ltoken_getCode (t) != NOTTOKEN)
1472 cstring loc = ltoken_unparseLoc (t);
1474 lastfileloclen = cstring_length (loc);
1476 printError (g_msgstream, message ("%q: %q", loc, msg));
1477 showSourceLoc (srcFile, srcLine);
1481 printError (g_msgstream, msg);
1482 showSourceLoc (srcFile, srcLine);
1487 lclplainerror (/*@only@*/ cstring msg)
1491 printError (g_msgstream, msg);
1495 lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1498 (void) fflush (g_msgstream);
1499 printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1504 lclplainfatalerror (/*@only@*/ cstring msg)
1506 (void) fflush (g_msgstream);
1507 printError (stderr, message ("*** Cannot continue: %q", msg));
1512 lclRedeclarationError (ltoken id)
1514 cstring s = ltoken_getRawString (id);
1517 if (usymtab_existsEither (s))
1519 uentry le = usymtab_lookupEither (s);
1521 lclerror (id, message ("Respecification of %s", s));
1522 llgenindentmsg (message ("Previous specification of %q",
1523 uentry_getName (le)),
1524 uentry_whereSpecified (le));
1528 lclerror (id, message ("Identifier redeclared: %s", s));
1533 void genppllerror (flagcode code, /*@only@*/ cstring s)
1535 if (context_inSuppressZone (g_currentloc))
1541 if (context_getFlag (code))
1543 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1545 fprintf (g_msgstream, " >\n");
1550 if (code != FLG_PREPROC)
1552 llsuppresshint ('-', code);
1555 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1557 fprintf (stderr, "< more preprocessing .");
1567 void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1568 /*@only@*/ cstring hint)
1570 if (context_inSuppressZone (g_currentloc))
1573 cstring_free (hint);
1577 if (context_getFlag (code))
1580 context_clearPreprocessing ();
1583 context_setPreprocessing ();
1589 cstring_free (hint);
1594 void ppllerror (/*@only@*/ cstring s)
1596 genppllerror (FLG_PREPROC, s);
1599 void pplldiagmsg (cstring s)
1601 if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1603 fprintf (stderr, " >\n");
1605 fprintf (stderr, "< more preprocessing .");
1613 void loadllmsg (cstring s)
1615 if (context_getDebug (FLG_SHOWSCAN))
1617 fprintf (stderr, " >\n");
1619 fprintf (stderr, "< .");
1627 static void llreportparseerror (/*@only@*/ cstring s)
1629 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1635 llerror (FLG_SYNTAX, s);
1637 fileloc_free (lastparseerror);
1638 lastparseerror = fileloc_copy (g_currentloc);
1642 bool xcppoptgenerror (char *srcFile, int srcLine,
1644 /*@only@*/ cstring s,
1648 fileloc loc = cppReader_getLoc (pfile);
1650 if (context_flagOn (o, loc))
1652 if (xlloptgenerror (srcFile, srcLine, o, s, loc))
1654 cppReader_printContainingFiles (pfile);
1668 bool xlloptgenerror (char *srcFile, int srcLine,
1669 flagcode o, /*@only@*/ cstring s, fileloc loc)
1671 DPRINTF (("xllopt: %s", s));
1673 if (llrealerror (srcFile, srcLine, s, loc))
1675 DPRINTF (("Here we are!"));
1676 llsuppresshint ('-', o);
1678 flagcode_recordError (o);
1683 DPRINTF (("Suppressed!"));
1684 flagcode_recordSuppressed (o);
1689 bool xoptgenerror2 (char *srcFile, int srcLine,
1690 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1692 if (context_suppressFlagMsg (f1, loc))
1694 flagcode_recordSuppressed (f1);
1699 if (context_suppressFlagMsg (f2, loc))
1701 flagcode_recordSuppressed (f2);
1706 if (llrealerror (srcFile, srcLine, s, loc))
1708 llsuppresshint2 ('-', f1, f2);
1709 flagcode_recordError (f2);
1715 flagcode_recordSuppressed (f2);
1723 bool xoptgenerror2n (char *srcFile, int srcLine,
1724 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1727 if (context_suppressFlagMsg (f1, loc))
1729 flagcode_recordSuppressed (f1);
1734 if (context_suppressNotFlagMsg (f2, loc))
1736 flagcode_recordSuppressed (f2);
1741 if (llrealerror (srcFile, srcLine, s, loc))
1743 llsuppresshint ('+', f2);
1744 flagcode_recordError (f2);
1749 flagcode_recordSuppressed (f2);
1755 bool xllnoptgenerror (char *srcFile, int srcLine,
1756 flagcode o, /*@only@*/ cstring s, fileloc loc)
1758 if (llrealerror (srcFile, srcLine, s, loc))
1760 llsuppresshint ('+', o);
1761 flagcode_recordError (o);
1766 flagcode_recordSuppressed (o);
1770 void llparseerror (cstring s)
1772 if (context_getFlag (FLG_TRYTORECOVER))
1776 if (parseerrorcount > GIVEUPPARSE)
1778 if (cstring_isDefined (s))
1780 llfatalerror (message ("%q: Parse Error: %q. "
1781 "Too many errors, giving up.",
1782 fileloc_unparse (g_currentloc), s));
1786 llfatalerror (message ("%q: Parse Error. Too many errors, giving up.",
1787 fileloc_unparse (g_currentloc)));
1792 if (cstring_isDefined (s))
1794 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1799 llreportparseerror (message ("Parse Error. Attempting to continue."));
1807 if (cstring_isDefined (s))
1809 msg = message ("Parse Error: %q.", s);
1813 msg = message ("Parse Error.");
1817 (message ("%q: %s (For help on parse errors, "
1818 "see lclint -help parseerrors.)",
1819 fileloc_unparse (g_currentloc), msg));
1823 bool xfsgenerror (char *srcFile, int srcLine,
1824 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
1826 if (flagSpec_isOn (fs, fl))
1828 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
1830 llsuppresshint ('-', flagSpec_getFirstOn (fs, fl));
1831 flagcode_recordError (flagSpec_getFirstOn (fs, fl));
1836 flagcode_recordSuppressed (flagSpec_getFirstOn (fs, fl));
1842 flagcode_recordSuppressed (flagSpec_getDominant (fs));
1848 bool doCheck (bool x, cstring pred, cstring file, int line)
1851 llbug (message ("%q: Check Failed: %s",
1852 fileloc_unparseRaw (file, line),
1859 /*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1864 #ifndef HAVE_STRERROR
1867 result = strerror (errnum);
1870 /* VAXCRTL's strerror() takes an optional second argument, which only
1871 matters when the first argument is EVMSERR. However, it's simplest
1872 just to pass it unconditionally. `vaxc$errno' is declared in
1873 <errno.h>, and maintained by the library in parallel with `errno'.
1874 We assume that caller's `errnum' either matches the last setting of
1875 `errno' by the library or else does not have the value `EVMSERR'. */
1877 result = strerror (errnum, vaxc$errno);
1882 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1885 return cstring_fromChars (result);
1888 void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1893 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1894 fileloc_unparse (g_currentloc),
1895 fileloc_unparseRaw (file, line),
1907 (void) fflush (g_msgstream);
1908 (void) fflush (stderr);