2 ** LCLint - 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://lclint.cs.virginia.edu
27 ** error reporting procedures
30 # include "lclintMacros.nf"
37 /* Don't allow possibly-recursive assertion failures. */
39 # define llassert llassertprotect
41 static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
42 /*@modifies *p_stream@*/ ;
45 static int lclerrors = 0;
48 static int lastfileloclen = 10;
49 static /*@only@*/ cstring lastmsg = cstring_undefined;
50 static int mcount = 0;
51 static /*@only@*/ cstring saveOneMessage = cstring_undefined;
52 static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
53 static /*@only@*/ fileloc lastbug = fileloc_undefined;
54 static bool llgenerrorreal (char *p_srcFile, int p_srcLine,
55 /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
56 /*@modifies g_msgstream@*/ ;
57 static bool llgenerroraux (char *p_srcFile, int p_srcLine,
58 /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
59 /*@modifies g_msgstream@*/ ;
61 static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
62 /*@globals lastfileloclen @*/
63 /*@modifies *p_stream@*/ ;
64 static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
65 /*@modifies *p_stream@*/ ;
67 static void llgenhint (/*@only@*/ cstring p_s) /*@modifies g_msgstream@*/ ;
69 static void showSourceLoc (char *srcFile, int srcLine)
70 /*@modifies g_msgstream@*/
72 if (context_getFlag (FLG_SHOWSOURCELOC)) {
73 llgenhint (message ("%s:%d: Source code error generation point.",
74 cstring_fromChars (srcFile), srcLine));
79 static /*@null@*/ char *
80 maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
89 fprintf (stderr, " *** Please report bug to %s ***\n",
92 /* don't exit (EXIT_FAILURE); */
95 static bool s_needsPrepare = TRUE;
97 void prepareMessage (void)
99 DPRINTF (("Prepare message: %s", bool_unparse (context_loadingLibrary ())));
101 if ((context_isPreprocessing () || context_loadingLibrary ())
103 && context_getDebug (FLG_SHOWSCAN))
106 fprintf (stderr, " >\n");
107 s_needsPrepare = FALSE;
113 void closeMessage (void)
115 if (context_isPreprocessing ()
116 && context_getDebug (FLG_SHOWSCAN))
119 fprintf (stderr, "< more preprocessing .");
121 llassertprotect (!s_needsPrepare);
122 s_needsPrepare = TRUE;
131 llmsg (/*@only@*/ cstring s)
133 context_setNeednl ();
135 printMessage (g_msgstream, s);
140 lldiagmsg (/*@only@*/ cstring s)
142 context_setNeednl ();
144 printMessage (stderr, s);
149 llmsgplain (/*@only@*/ cstring s)
151 context_setNeednl ();
153 printMessage (g_msgstream, s);
157 void llerror_flagWarning (cstring s)
159 if (context_getFlag (FLG_WARNFLAGS))
163 if (fileloc_isBuiltin (g_currentloc))
165 llmsg (message ("Warning: %q", s));
169 llgenmsg (message ("Warning: %q", s), g_currentloc);
179 llgenhint (/*@only@*/ cstring s) /*@modifies g_msgstream@*/
181 int indent = context_getIndentSpaces () - 1;
183 if (indent < 0) indent = 0;
185 context_setNeednl ();
186 printIndentMessage (g_msgstream, s, indent);
192 if (context_getFlag (FLG_HINTS) &&
193 !(context_inSuppressRegion () || context_inSuppressZone (g_currentloc)))
204 llshowhint (flagcode f)
206 if (context_getFlag (FLG_HINTS))
208 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
210 cstring desc = flagcodeHint (f);
212 if (cstring_isDefined (desc))
214 llgenhint (cstring_copy (desc));
221 llsuppresshint2 (char c, flagcode f1, flagcode f2)
224 if (context_getFlag (FLG_HINTS))
226 if ((flagcode_numReported (f1) == 0
227 || flagcode_numReported (f2) == 0)
228 || context_getFlag (FLG_FORCEHINTS))
230 cstring desc = flagcodeHint (f1);
231 context_setNeednl ();
234 if (cstring_isUndefined (desc))
236 desc = flagcodeHint (f2);
239 if (flagcode_isNamePrefixFlag (f1))
244 if (flagcode_isNamePrefixFlag (f2))
249 if (cstring_isDefined (desc))
251 llgenhint (message ("%s (Setting either %h%s or %h%s will suppress message)", desc,
253 flagcode_unparse (f1),
255 flagcode_unparse (f2)));
259 llgenhint (message ("(Setting either %h%s or %h%s will suppress message)", c,
260 flagcode_unparse (f1),
261 c, flagcode_unparse (f2)));
268 llsuppresshint (char c, flagcode f)
270 if (context_getFlag (FLG_HINTS))
272 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
274 cstring desc = flagcodeHint (f);
275 context_setNeednl ();
278 if (flagcode_isNamePrefixFlag (f))
283 if (cstring_isDefined (desc))
285 llgenhint (message ("%s (%h%s will suppress message)", desc, c,
286 flagcode_unparse (f)));
290 llgenhint (message ("(%h%s will suppress message)", c,
291 flagcode_unparse (f)));
298 llnosuppresshint (flagcode f)
300 if (context_getFlag (FLG_FORCEHINTS))
302 cstring desc = flagcodeHint (f);
303 context_setNeednl ();
306 if (cstring_isDefined (desc))
308 printError (g_msgstream, message (" %s", desc));
313 /*@constant int MAXSEARCH; @*/
314 # define MAXSEARCH 20
316 /*@constant int MINLINE; @*/
319 typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
322 mstring_split (/*@returned@*/ char **sp,
323 /*@out@*/ nd_charp *tp,
324 int maxline, /*@in@*/ int *indentchars)
333 DPRINTF (("Split: %s / %d", *sp, maxline));
335 if (maxline < MINLINELEN)
337 maxline = MINLINELEN;
340 if (*indentchars > 0)
342 s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
346 nl = strchr (s, '\n');
351 ** if there is a newline in first maxline characters, split there
352 ** if line len is <= maxline, return no split
353 ** if there is a ':' or ';' followed by ' ' in first maxline characters,
354 ** split there unless the ' ' is followed by a '}', then
356 ** of the ';' is inside quotation marks
357 ** if there is a space or tab in last maxsearch characters, split there
358 ** else, split at maxline
360 ** special code: slash [1-9] after a newline means indent the rest <n> chars
364 if ((nl != NULL) && ((nl - s) < maxline))
371 llassertprotect (*tp == NULL || (*tp > osp));
375 if (*t >= '\1' && *t <= '\7')
377 *indentchars += (int) (*t - '\1') + 1;
384 else if (size_toInt (strlen (s)) < maxline)
386 llassertprotect (*tp == NULL || (*tp > osp));
393 char *lcolon, *lsemi, *splitat;
401 lcolon = strrchr (s, ':');
402 lsemi = strrchr (s, ';');
405 splitat = maxcp (lcolon, lsemi);
407 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
408 && *(splitat) != '\0'
409 && *(splitat + 1) == ' '
410 && (*(splitat + 2) != '}' && (*(splitat + 2) != '\0')))
412 *(splitat + 1) = '\0';
415 llassertprotect (*tp == NULL || (*tp > osp));
419 while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
425 if (*t != ' ' && *t != '\t')
427 llassertprotect (maxline > 0);
428 t = mstring_copy (s + maxline);
429 *(s + maxline) = '\0';
434 llassertprotect (*tp == NULL || (*tp > osp));
438 mstring_markFree (t);
440 /* Won't be true since t is a copy: llassertprotect (*tp == NULL || (*tp > osp)); */
449 if (*t == '\0') return;
452 ** returns unqualified as only
458 /* Hack to prevent error case for wierd strings. */
464 llassertprotect (*tp == NULL || (*tp > osp));
475 void limitmessage (/*@only@*/ cstring s, fileloc loc)
477 if (mcount > context_getLimit () + 1)
483 cstring flstring = fileloc_unparse (loc);
485 lastfileloclen = cstring_length (flstring);
486 cstring_free (saveOneMessage);
487 saveOneMessage = message ("%q: %q", flstring, s);
491 static int parseerrorcount = 0;
493 void cleanupMessages ()
497 if (context_unlimitedMessages ())
503 int unprinted = mcount - context_getLimit ();
507 if (unprinted == 1 && cstring_isDefined (saveOneMessage))
510 printError (g_msgstream, saveOneMessage);
512 saveOneMessage = cstring_undefined;
516 if (cstring_isDefined (saveOneMessage))
518 /* cstring_free (saveOneMessage); */
519 saveOneMessage = cstring_undefined;
522 fprintf (g_msgstream, "%s: (%d more similar errors unprinted)\n",
523 cstring_toCharsSafe (fileloc_filename (g_currentloc)),
524 mcount - context_getLimit ());
533 llgenmsg (/*@only@*/ cstring s, fileloc fl)
535 cstring flstring = fileloc_unparse (fl);
536 lastfileloclen = cstring_length (flstring);
539 (void) printError (g_msgstream, message ("%q: %q", flstring, s));
544 llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
546 cstring flstring = fileloc_unparse (fl);
549 (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), context_getIndentSpaces ());
554 llgenindentmsgnoloc (/*@only@*/ cstring s)
557 (void) printIndentMessage (g_msgstream, s, context_getIndentSpaces ());
562 llgentypeerroraux (char *srcFile, int srcLine,
563 flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
564 /*@only@*/ cstring s, fileloc fl)
566 cstring hint = cstring_undefined;
567 flagcode code = ocode;
568 flagcode hcode = INVALID_FLAG;
572 DPRINTF (("Type error [%s]: %s / %s : %s / %s",
573 flagcode_unparse (ocode),
574 exprNode_unparse (e1), exprNode_unparse (e2),
575 ctype_unparse (t1), ctype_unparse (t2)));
577 DPRINTF (("Bool: %s / %s",
578 bool_unparse (ctype_isBool (t1)),
579 bool_unparse (ctype_isBool (t2))));
582 ** Set the flag using the underlying types that didn't match.
585 while (ctype_isPointer (ut1) && ctype_isPointer (ut2)) {
586 ut1 = ctype_baseArrayPtr (ut1);
587 ut2 = ctype_baseArrayPtr (ut2);
590 if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
591 || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
593 hcode = FLG_FLOATDOUBLE;
595 else if ((exprNode_isCharLit (e1) && ctype_isInt (ut2))
596 || (exprNode_isCharLit (e2) && ctype_isInt (ut1)))
598 hcode = FLG_CHARINTLITERAL;
600 else if ((exprNode_isNumLit (e1) && ctype_isReal (ut2))
601 || (exprNode_isNumLit (e2) && ctype_isReal (ut1)))
603 hcode = FLG_NUMLITERAL;
605 else if ((ctype_isManifestBool (ut1) && ctype_isInt (ut2))
606 || (ctype_isInt (ut1) && ctype_isManifestBool (ut2)))
607 /* evs 2000-07-24: was ctype_isDirectBool */
611 else if (((ctype_isChar (ut1) && !ctype_isInt (ut1)) && ctype_isInt (ut2))
612 || ((ctype_isInt (ut1) && (ctype_isChar (ut2) && !ctype_isInt (ut2)))))
616 else if ((ctype_isInt (ut1) && ctype_isInt (ut2))
617 || (ctype_isChar (ut1) && ctype_isChar (ut2))
618 || (ctype_isDouble (ut1) && ctype_isDouble (ut2)))
620 if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
622 hcode = FLG_IGNORESIGNS;
626 hcode = FLG_IGNOREQUALS;
629 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
631 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
633 hcode = FLG_MATCHANYINTEGRAL;
635 else if (ctype_match (ut2, ctype_ulint))
637 hcode = FLG_LONGUNSIGNEDINTEGRAL;
639 else if (ctype_match (ut2, ctype_lint))
641 hcode = FLG_LONGINTEGRAL;
643 else if (ctype_isInt (ut2))
645 hcode = FLG_MATCHANYINTEGRAL;
652 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
654 ctype tr = ctype_realType (ut1);
656 if (ctype_isArbitraryIntegral (tr))
658 hcode = FLG_MATCHANYINTEGRAL;
660 else if (ctype_match (ut1, ctype_ulint))
662 if (ctype_isUnsignedIntegral (tr))
664 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
666 else if (ctype_isSignedIntegral (tr))
672 hcode = FLG_LONGUNSIGNEDINTEGRAL;
675 else if (ctype_match (ut1, ctype_lint))
677 if (ctype_isSignedIntegral (tr))
679 hcode = FLG_LONGSIGNEDINTEGRAL;
681 else if (ctype_isSignedIntegral (tr))
687 hcode = FLG_LONGINTEGRAL;
690 else if (ctype_isInt (ut1))
692 hcode = FLG_MATCHANYINTEGRAL;
704 if (hcode == INVALID_FLAG)
706 DPRINTF (("[%s] %s - %s / %s",
708 bool_unparse (ctype_isEnum (ut1)),
709 bool_unparse (ctype_isEnum (ctype_realType (ut1))),
710 bool_unparse (ctype_isInt (ut2))));
712 if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
714 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
715 ctype ct = uentry_getType (ue1);
717 if (ctype_match (ct, ut2))
720 hint = message ("Underlying types match, but %s is an "
721 "abstract type that is not accessible here.",
725 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
727 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
728 ctype ct = uentry_getType (ue);
730 if (ctype_match (ct, ut1))
733 hint = message ("Underlying types match, but %s is an "
734 "abstract type that is not accessible here.",
740 ; /* Not an abstract mismatch. */
744 if (hcode == INVALID_FLAG)
746 if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
747 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
751 else if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
752 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
756 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
757 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
759 hcode = FLG_CHARUNSIGNEDCHAR;
761 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
763 hcode = FLG_RELAXTYPES;
764 DPRINTF (("Setting relax types!"));
768 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
769 ctype_unparse (ut2)));
774 if (cstring_isDefined (hint))
776 if (!context_suppressFlagMsg (ocode, fl))
778 return llgenhinterror (code, s, hint, fl);
789 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
791 if (hcode != INVALID_FLAG && hcode != ocode)
799 llsuppresshint ('-', code);
802 flagcode_recordError (code);
811 xllgentypeerror (char *srcFile, int srcLine,
812 ctype t1, exprNode e1, ctype t2, exprNode e2,
813 /*@only@*/ cstring s, fileloc fl)
815 return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
819 xllgenformattypeerror (char *srcFile, int srcLine,
820 ctype t1, exprNode e1, ctype t2, exprNode e2,
821 /*@only@*/ cstring s, fileloc fl)
823 return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
827 xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
829 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
831 llnosuppresshint (o);
832 flagcode_recordError (o);
838 flagcode_recordSuppressed (o);
844 xllgenhinterror (char *srcFile, int srcLine,
845 flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
848 if (!context_suppressFlagMsg (o, fl))
850 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
852 flagcode_recordError (o);
854 if (context_getFlag (FLG_HINTS))
875 flagcode_recordSuppressed (o);
880 llrealerror (char *srcFile, int srcLine, /*@only@*/ cstring s, fileloc fl)
882 return (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE));
886 llgenerroraux (char *srcFile, int srcLine,
887 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
889 if (context_inSuppressZone (fl))
899 if (llgenerrorreal (srcFile, srcLine, s, fl, iserror, indent)) {
907 xllforceerror (char *srcFile, int srcLine,
908 flagcode code, /*@only@*/ cstring s, fileloc fl)
910 flagcode_recordError (code);
912 if (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)) {
921 llgenerrorreal (char *srcFile, int srcLine,
922 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
926 /* duplicate message (rescanning a header file */
928 if (!messageLog_add (context_messageLog (), fl, s))
930 DPRINTF (("Duplicate message suppressed! %s / %s",
931 fileloc_unparse (fl), s));
936 if (iserror) context_hasError ();
938 if (context_unlimitedMessages ())
945 ** suppress excessive messages:
950 char *sc = cstring_toCharsSafe (s);
951 char *tmpmsg = strchr (sc, ':');
959 char *savechar = tmpmsg;
965 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
968 if (mcount == (context_getLimit () + 1))
970 limitmessage (s, fl);
974 if (mcount > (context_getLimit ()))
984 cstring_free (lastmsg);
985 lastmsg = cstring_fromCharsNew (tmpmsg);
989 DPRINTF (("Here..."));
991 if (context_hasAliasAnnote ())
993 char *sc = cstring_toCharsSafe (s);
994 char *fcolon = strchr (sc, ':');
995 cstring a = context_getAliasAnnote ();
1000 s = message ("%q (%q)", s, a);
1007 afterColon = cstring_fromCharsNew (fcolon + 1);
1009 s = message ("%q (%q):%q", s, a, afterColon);
1013 if (context_hasMessageAnnote ())
1015 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1020 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1021 s = message ("%q (%q)", s, context_getMessageAnnote ());
1022 /*@=dependenttrans@*/
1029 afterColon = cstring_fromCharsNew (fcolon + 1);
1031 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1032 s = message ("%q (%q):%q", s,
1033 context_getMessageAnnote (), afterColon);
1034 /*@=dependenttrans@*/
1038 context_setNeednl ();
1041 if (context_showFunction ())
1043 cstring fname = fileloc_unparseFilename (g_currentloc);
1045 if (context_inIterDef ())
1047 fprintf (g_msgstream, "%s: (in iter %s)\n",
1048 cstring_toCharsSafe (fname),
1049 cstring_toCharsSafe (context_inFunctionName ()));
1051 else if (context_inIterEnd ())
1053 fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
1054 cstring_toCharsSafe (fname),
1055 cstring_toCharsSafe (context_inFunctionName ()));
1057 else if (context_inMacro ())
1059 fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
1060 cstring_toCharsSafe (context_inFunctionName ()));
1064 fprintf (g_msgstream, "%s: (in function %s)\n",
1065 cstring_toCharsSafe (fname),
1066 cstring_toCharsSafe (context_inFunctionName ()));
1069 cstring_free (fname);
1070 context_setShownFunction ();
1073 flstring = fileloc_unparse (fl);
1074 lastfileloclen = cstring_length (flstring);
1078 printError (g_msgstream, message (" %q: %q", flstring, s));
1082 printError (g_msgstream, message ("%q: %q", flstring, s));
1085 showSourceLoc (srcFile, srcLine);
1092 ** message contains no '\n'
1093 ** message fits in one line: print it
1094 ** message fits in two lines with 3-space indent after fileloc: print it
1095 ** split line with 5-space indent from left margin: print it
1100 void printMessage (FILE *stream, /*@only@*/ cstring s)
1102 printIndentMessage (stream, s, 0);
1106 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1108 static bool inbody = FALSE;
1109 int maxlen = context_getLineLen ();
1110 char *s = cstring_toCharsSafe (sc);
1113 llassertprotect (!inbody);
1121 llassertprotect (st != olds);
1123 mstring_split (&st, &t, maxlen, &indent);
1124 fprintf (stream, "%s\n", st);
1125 llassertprotect (t != s);
1127 } while (s != NULL) ;
1134 void printError (FILE *stream, /*@only@*/ cstring sc)
1136 int maxlen = context_getLineLen ();
1137 int nspaces = lastfileloclen + 5;
1138 int nextlen = maxlen - nspaces;
1139 int len = cstring_length (sc);
1141 char *s = cstring_toCharsSafe (sc);
1145 DPRINTF (("Print error: [%s]", sc));
1147 if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
1149 mstring_split (&s, &t, maxlen, &indent);
1151 fprintf (stream, "%s\n", s);
1155 len = mstring_length (t);
1157 if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1158 && len > (nextlen - 1))
1160 fprintf (stream, " %s\n", t);
1164 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1167 for (i = 0; i < nspaces; i++)
1172 spaces[nspaces] = '\0';
1177 mstring_split (&st, &t, nextlen, &indent);
1178 fprintf (stream, "%s%s\n", spaces, st);
1187 DPRINTF (("Here 1: [%s]", sc));
1189 if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1191 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1193 if (nspaces < 1) nspaces = 1;
1195 nextlen = maxlen - nspaces;
1197 mstring_split (&s, &t, maxlen, &indent);
1199 fprintf (stream, "%s\n", s);
1203 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1206 for (i = 0; i < nspaces; i++)
1211 spaces[nspaces] = '\0';
1217 mstring_split (&st, &t, nextlen, &indent);
1218 fprintf (stream, "%s%s\n", spaces, st);
1227 nextlen = maxlen - nspaces;
1229 DPRINTF (("Here 2: [%s]", s));
1230 mstring_split (&s, &t, maxlen, &indent);
1231 DPRINTF (("Here 3: [%s] [%s]", s, t));
1233 fprintf (stream, "%s\n", s);
1237 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1240 for (i = 0; i < nspaces; i++)
1245 spaces[nspaces] = '\0';
1250 DPRINTF (("Loop: [%s]", t));
1251 mstring_split (&st, &t, nextlen, &indent);
1252 DPRINTF (("Split: [%s] [%s]", st, t));
1253 fprintf (stream, "%s%s\n", spaces, st);
1254 DPRINTF (("Next..."));
1267 xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
1270 printError (stderr, message ("%q: *** Fatal bug: %q",
1271 fileloc_unparse (g_currentloc), s));
1272 showSourceLoc (srcFile, srcLine);
1280 lclfatalbug (char *msg)
1284 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1292 checkParseError (void)
1294 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1296 llfatalerror (message ("%q: Cannot recover from parse error.",
1297 fileloc_unparse (g_currentloc)));
1301 void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1304 static int numbugs = 0;
1305 static bool inbug = FALSE;
1309 cstring temps = fileloc_unparseRaw (file, line);
1311 fprintf (stderr, "%s: Recursive bug detected: %s\n",
1312 cstring_toCharsSafe (temps),
1313 cstring_toCharsSafe (s));
1314 cstring_free (temps);
1325 if (fileloc_isRealLib (g_currentloc))
1327 DPRINTF (("Here we are!"));
1328 llfatalerror (message ("%q: Library file appears to be corrupted. Error: %q: %s",
1329 fileloc_unparse (g_currentloc),
1330 fileloc_unparseRaw (file, line),
1335 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1337 llfatalerror (message ("%q: Cannot recover from parse error.",
1338 fileloc_unparse (g_currentloc)));
1341 (void) fflush (g_msgstream);
1342 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1343 fileloc_unparse (g_currentloc),
1344 fileloc_unparseRaw (file, line),
1348 (void) fflush (stderr);
1349 perror ("Possible system error diagnostic: ");
1350 (void) fflush (stderr);
1356 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
1358 llfatalerror (message ("%q: Cannot recover from last bug. (If you really want LCLint to try to continue, use -bugslimit <n>.)",
1359 fileloc_unparse (g_currentloc)));
1362 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1363 fileloc_free (lastbug);
1364 lastbug = fileloc_copy (g_currentloc);
1367 (void) fflush (stderr);
1373 lclbug (/*@only@*/ cstring s)
1376 printError (stderr, message ("*** Internal Bug: %q", s));
1379 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1385 llfatalerror (cstring s)
1388 printError (stderr, s);
1389 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1394 llfatalerrorLoc (/*@only@*/ cstring s)
1397 (void) fflush (g_msgstream);
1398 printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1399 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1400 (void) fflush (g_msgstream);
1405 xllgloberror (char *srcFile, int srcLine, /*@only@*/ cstring s)
1407 if (context_inSuppressRegion ())
1413 context_setNeednl ();
1415 context_hasError ();
1416 flagcode_recordError (FLG_SPECIAL);
1417 printError (g_msgstream, s);
1418 showSourceLoc (srcFile, srcLine);
1427 return (lclerrors > 0);
1431 lclHadNewError (void)
1433 static int lastcall = 0;
1435 if (lclerrors > lastcall)
1437 lastcall = lclerrors;
1447 lclNumberErrors (void)
1453 xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
1457 if (ltoken_getCode (t) != NOTTOKEN)
1459 cstring loc = ltoken_unparseLoc (t);
1461 lastfileloclen = cstring_length (loc);
1463 printError (g_msgstream, message ("%q: %q", loc, msg));
1464 showSourceLoc (srcFile, srcLine);
1468 printError (g_msgstream, msg);
1469 showSourceLoc (srcFile, srcLine);
1474 lclplainerror (/*@only@*/ cstring msg)
1478 printError (g_msgstream, msg);
1482 lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1485 (void) fflush (g_msgstream);
1486 printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1491 lclplainfatalerror (/*@only@*/ cstring msg)
1493 (void) fflush (g_msgstream);
1494 printError (stderr, message ("*** Cannot continue: %q", msg));
1499 lclRedeclarationError (ltoken id)
1501 cstring s = ltoken_getRawString (id);
1504 if (usymtab_existsEither (s))
1506 uentry le = usymtab_lookupEither (s);
1508 lclerror (id, message ("Respecification of %s", s));
1509 llgenindentmsg (message ("Previous specification of %q",
1510 uentry_getName (le)),
1511 uentry_whereSpecified (le));
1515 lclerror (id, message ("Identifier redeclared: %s", s));
1520 void genppllerror (flagcode code, /*@only@*/ cstring s)
1522 if (context_inSuppressZone (g_currentloc))
1528 if (context_getFlag (code))
1530 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1532 fprintf (g_msgstream, " >\n");
1537 if (code != FLG_PREPROC)
1539 llsuppresshint ('-', code);
1542 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1544 fprintf (stderr, "< more preprocessing .");
1554 void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1555 /*@only@*/ cstring hint)
1557 if (context_inSuppressZone (g_currentloc))
1560 cstring_free (hint);
1564 if (context_getFlag (code))
1567 context_clearPreprocessing ();
1570 context_setPreprocessing ();
1576 cstring_free (hint);
1581 void ppllerror (/*@only@*/ cstring s)
1583 genppllerror (FLG_PREPROC, s);
1586 void pplldiagmsg (cstring s)
1588 if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1590 fprintf (stderr, " >\n");
1592 fprintf (stderr, "< more preprocessing .");
1600 void loadllmsg (cstring s)
1602 if (context_getDebug (FLG_SHOWSCAN))
1604 fprintf (stderr, " >\n");
1606 fprintf (stderr, "< .");
1614 static void llreportparseerror (/*@only@*/ cstring s)
1616 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1622 llerror (FLG_SYNTAX, s);
1624 fileloc_free (lastparseerror);
1625 lastparseerror = fileloc_copy (g_currentloc);
1629 bool xlloptgenerror (char *srcFile, int srcLine,
1630 flagcode o, /*@only@*/ cstring s, fileloc loc)
1632 DPRINTF (("xllopt: %s", s));
1634 if (llrealerror (srcFile, srcLine, s, loc))
1636 DPRINTF (("Here we are!"));
1637 llsuppresshint ('-', o);
1639 flagcode_recordError (o);
1644 DPRINTF (("Suppressed!"));
1645 flagcode_recordSuppressed (o);
1650 bool xoptgenerror2 (char *srcFile, int srcLine,
1651 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1653 if (context_suppressFlagMsg (f1, loc))
1655 flagcode_recordSuppressed (f1);
1660 if (context_suppressFlagMsg (f2, loc))
1662 flagcode_recordSuppressed (f2);
1667 if (llrealerror (srcFile, srcLine, s, loc))
1669 llsuppresshint2 ('-', f1, f2);
1670 flagcode_recordError (f2);
1676 flagcode_recordSuppressed (f2);
1684 bool xoptgenerror2n (char *srcFile, int srcLine,
1685 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1688 if (context_suppressFlagMsg (f1, loc))
1690 flagcode_recordSuppressed (f1);
1695 if (context_suppressNotFlagMsg (f2, loc))
1697 flagcode_recordSuppressed (f2);
1702 if (llrealerror (srcFile, srcLine, s, loc))
1704 llsuppresshint ('+', f2);
1705 flagcode_recordError (f2);
1710 flagcode_recordSuppressed (f2);
1716 bool xllnoptgenerror (char *srcFile, int srcLine,
1717 flagcode o, /*@only@*/ cstring s, fileloc loc)
1719 if (llrealerror (srcFile, srcLine, s, loc))
1721 llsuppresshint ('+', o);
1722 flagcode_recordError (o);
1727 flagcode_recordSuppressed (o);
1731 void llparseerror (cstring s)
1733 if (context_getFlag (FLG_TRYTORECOVER))
1737 if (parseerrorcount > GIVEUPPARSE)
1739 if (cstring_isDefined (s))
1741 llfatalerror (message ("%q: Parse Error: %q. "
1742 "Too many errors, giving up.",
1743 fileloc_unparse (g_currentloc), s));
1747 llfatalerror (message ("%q: Parse Error. Too many errors, giving up.",
1748 fileloc_unparse (g_currentloc)));
1753 if (cstring_isDefined (s))
1755 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1760 llreportparseerror (message ("Parse Error. Attempting to continue."));
1768 if (cstring_isDefined (s))
1770 msg = message ("Parse Error: %q.", s);
1774 msg = message ("Parse Error.");
1778 (message ("%q: %s (For help on parse errors, "
1779 "see lclint -help parseerrors.)",
1780 fileloc_unparse (g_currentloc), msg));
1784 bool xfsgenerror (char *srcFile, int srcLine,
1785 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
1787 if (flagSpec_isOn (fs, fl))
1789 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
1791 llsuppresshint ('-', flagSpec_getFirstOn (fs, fl));
1792 flagcode_recordError (flagSpec_getFirstOn (fs, fl));
1797 flagcode_recordSuppressed (flagSpec_getFirstOn (fs, fl));
1803 flagcode_recordSuppressed (flagSpec_getDominant (fs));
1809 bool doCheck (bool x, cstring pred, cstring file, int line)
1812 llbug (message ("%q: Check Failed: %s",
1813 fileloc_unparseRaw (file, line),
1820 /*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1825 #ifndef HAVE_STRERROR
1828 result = strerror (errnum);
1831 /* VAXCRTL's strerror() takes an optional second argument, which only
1832 matters when the first argument is EVMSERR. However, it's simplest
1833 just to pass it unconditionally. `vaxc$errno' is declared in
1834 <errno.h>, and maintained by the library in parallel with `errno'.
1835 We assume that caller's `errnum' either matches the last setting of
1836 `errno' by the library or else does not have the value `EVMSERR'. */
1838 result = strerror (errnum, vaxc$errno);
1843 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1846 return cstring_fromChars (result);
1849 void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1854 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1855 fileloc_unparse (g_currentloc),
1856 fileloc_unparseRaw (file, line),
1868 (void) fflush (g_msgstream);
1869 (void) fflush (stderr);