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))
251 if (cstring_isDefined (desc))
253 llgenhint (message ("%s (Setting %h%s will suppress message)", desc,
255 flagcode_unparse (f1)));
259 llgenhint (message ("(Setting %h%s will suppress message)",
260 c, flagcode_unparse (f1)));
265 if (cstring_isDefined (desc))
267 llgenhint (message ("%s (Setting either %h%s or %h%s will suppress message)", desc,
269 flagcode_unparse (f1),
271 flagcode_unparse (f2)));
275 llgenhint (message ("(Setting either %h%s or %h%s will suppress message)", c,
276 flagcode_unparse (f1),
277 c, flagcode_unparse (f2)));
285 llsuppresshint (char c, flagcode f)
287 if (context_getFlag (FLG_HINTS))
289 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
291 cstring desc = flagcodeHint (f);
292 context_setNeednl ();
295 if (flagcode_isNamePrefixFlag (f))
300 if (cstring_isDefined (desc))
302 llgenhint (message ("%s (%h%s will suppress message)", desc, c,
303 flagcode_unparse (f)));
307 llgenhint (message ("(%h%s will suppress message)", c,
308 flagcode_unparse (f)));
315 llnosuppresshint (flagcode f)
317 if (context_getFlag (FLG_FORCEHINTS))
319 cstring desc = flagcodeHint (f);
320 context_setNeednl ();
323 if (cstring_isDefined (desc))
325 printError (g_msgstream, message (" %s", desc));
330 /*@constant int MAXSEARCH; @*/
331 # define MAXSEARCH 20
333 /*@constant int MINLINE; @*/
336 typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
339 mstring_split (/*@returned@*/ char **sp,
340 /*@out@*/ nd_charp *tp,
341 int maxline, /*@in@*/ int *indentchars)
350 DPRINTF (("Split: %s / %d", *sp, maxline));
352 if (maxline < MINLINELEN)
354 maxline = MINLINELEN;
357 if (*indentchars > 0)
359 s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
363 nl = strchr (s, '\n');
368 ** if there is a newline in first maxline characters, split there
369 ** if line len is <= maxline, return no split
370 ** if there is a ':' or ';' followed by ' ' in first maxline characters,
371 ** split there unless the ' ' is followed by a '}', then
373 ** of the ';' is inside quotation marks
374 ** if there is a space or tab in last maxsearch characters, split there
375 ** else, split at maxline
377 ** special code: slash [1-9] after a newline means indent the rest <n> chars
381 if ((nl != NULL) && ((nl - s) < maxline))
388 llassertprotect (*tp == NULL || (*tp > osp));
392 if (*t >= '\1' && *t <= '\7')
394 *indentchars += (int) (*t - '\1') + 1;
401 else if (size_toInt (strlen (s)) < maxline)
403 llassertprotect (*tp == NULL || (*tp > osp));
410 char *lcolon, *lsemi, *splitat;
418 lcolon = strrchr (s, ':');
419 lsemi = strrchr (s, ';');
422 splitat = maxcp (lcolon, lsemi);
424 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
425 && *(splitat) != '\0'
426 && *(splitat + 1) == ' '
427 && (*(splitat + 2) != '}' && (*(splitat + 2) != '\0')))
429 *(splitat + 1) = '\0';
432 llassertprotect (*tp == NULL || (*tp > osp));
436 while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
442 if (*t != ' ' && *t != '\t')
444 llassertprotect (maxline > 0);
445 t = mstring_copy (s + maxline);
446 *(s + maxline) = '\0';
451 llassertprotect (*tp == NULL || (*tp > osp));
455 mstring_markFree (t);
457 /* Won't be true since t is a copy: llassertprotect (*tp == NULL || (*tp > osp)); */
466 if (*t == '\0') return;
469 ** returns unqualified as only
475 /* Hack to prevent error case for wierd strings. */
481 llassertprotect (*tp == NULL || (*tp > osp));
492 void limitmessage (/*@only@*/ cstring s, fileloc loc)
494 if (mcount > context_getLimit () + 1)
500 cstring flstring = fileloc_unparse (loc);
502 lastfileloclen = cstring_length (flstring);
503 cstring_free (saveOneMessage);
504 saveOneMessage = message ("%q: %q", flstring, s);
508 static int parseerrorcount = 0;
510 void cleanupMessages ()
514 if (context_unlimitedMessages ())
520 int unprinted = mcount - context_getLimit ();
524 if (unprinted == 1 && cstring_isDefined (saveOneMessage))
527 printError (g_msgstream, saveOneMessage);
529 saveOneMessage = cstring_undefined;
533 if (cstring_isDefined (saveOneMessage))
535 /* cstring_free (saveOneMessage); */
536 saveOneMessage = cstring_undefined;
539 fprintf (g_msgstream, "%s: (%d more similar errors unprinted)\n",
540 cstring_toCharsSafe (fileloc_filename (g_currentloc)),
541 mcount - context_getLimit ());
550 llgenmsg (/*@only@*/ cstring s, fileloc fl)
552 cstring flstring = fileloc_unparse (fl);
553 lastfileloclen = cstring_length (flstring);
556 (void) printError (g_msgstream, message ("%q: %q", flstring, s));
561 llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
563 cstring flstring = fileloc_unparse (fl);
566 (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), context_getIndentSpaces ());
571 llgenindentmsgnoloc (/*@only@*/ cstring s)
574 (void) printIndentMessage (g_msgstream, s, context_getIndentSpaces ());
579 llgentypeerroraux (char *srcFile, int srcLine,
580 flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
581 /*@only@*/ cstring s, fileloc fl)
583 cstring hint = cstring_undefined;
584 flagcode code = ocode;
585 flagcode hcode = INVALID_FLAG;
589 DPRINTF (("Type error [%s]: %s / %s : %s / %s",
590 flagcode_unparse (ocode),
591 exprNode_unparse (e1), exprNode_unparse (e2),
592 ctype_unparse (t1), ctype_unparse (t2)));
594 DPRINTF (("Bool: %s / %s",
595 bool_unparse (ctype_isBool (t1)),
596 bool_unparse (ctype_isBool (t2))));
599 ** Set the flag using the underlying types that didn't match.
602 while (ctype_isPointer (ut1) && ctype_isPointer (ut2)) {
603 ut1 = ctype_baseArrayPtr (ut1);
604 ut2 = ctype_baseArrayPtr (ut2);
607 if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
608 || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
610 hcode = FLG_FLOATDOUBLE;
612 else if ((exprNode_isCharLit (e1) && ctype_isInt (ut2))
613 || (exprNode_isCharLit (e2) && ctype_isInt (ut1)))
615 hcode = FLG_CHARINTLITERAL;
617 else if ((exprNode_isNumLit (e1) && ctype_isReal (ut2))
618 || (exprNode_isNumLit (e2) && ctype_isReal (ut1)))
620 hcode = FLG_NUMLITERAL;
622 else if ((ctype_isManifestBool (ut1) && ctype_isInt (ut2))
623 || (ctype_isInt (ut1) && ctype_isManifestBool (ut2)))
624 /* evs 2000-07-24: was ctype_isDirectBool */
628 else if (((ctype_isChar (ut1) && !ctype_isInt (ut1)) && ctype_isInt (ut2))
629 || ((ctype_isInt (ut1) && (ctype_isChar (ut2) && !ctype_isInt (ut2)))))
633 else if ((ctype_isInt (ut1) && ctype_isInt (ut2))
634 || (ctype_isChar (ut1) && ctype_isChar (ut2))
635 || (ctype_isDouble (ut1) && ctype_isDouble (ut2)))
637 if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
639 hcode = FLG_IGNORESIGNS;
643 hcode = FLG_IGNOREQUALS;
646 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
648 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
650 hcode = FLG_MATCHANYINTEGRAL;
652 else if (ctype_match (ut2, ctype_ulint))
654 hcode = FLG_LONGUNSIGNEDINTEGRAL;
656 else if (ctype_match (ut2, ctype_lint))
658 hcode = FLG_LONGINTEGRAL;
660 else if (ctype_isInt (ut2))
662 hcode = FLG_MATCHANYINTEGRAL;
669 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
671 ctype tr = ctype_realType (ut1);
673 if (ctype_isArbitraryIntegral (tr))
675 hcode = FLG_MATCHANYINTEGRAL;
677 else if (ctype_match (ut1, ctype_ulint))
679 if (ctype_isUnsignedIntegral (tr))
681 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
683 else if (ctype_isSignedIntegral (tr))
689 hcode = FLG_LONGUNSIGNEDINTEGRAL;
692 else if (ctype_match (ut1, ctype_lint))
694 if (ctype_isSignedIntegral (tr))
696 hcode = FLG_LONGSIGNEDINTEGRAL;
698 else if (ctype_isSignedIntegral (tr))
704 hcode = FLG_LONGINTEGRAL;
707 else if (ctype_isInt (ut1))
709 hcode = FLG_MATCHANYINTEGRAL;
721 if (hcode == INVALID_FLAG)
723 DPRINTF (("[%s] %s - %s / %s",
725 bool_unparse (ctype_isEnum (ut1)),
726 bool_unparse (ctype_isEnum (ctype_realType (ut1))),
727 bool_unparse (ctype_isInt (ut2))));
729 if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
731 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
732 ctype ct = uentry_getType (ue1);
734 if (ctype_match (ct, ut2))
737 hint = message ("Underlying types match, but %s is an "
738 "abstract type that is not accessible here.",
742 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
744 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
745 ctype ct = uentry_getType (ue);
747 if (ctype_match (ct, ut1))
750 hint = message ("Underlying types match, but %s is an "
751 "abstract type that is not accessible here.",
757 ; /* Not an abstract mismatch. */
761 if (hcode == INVALID_FLAG)
763 if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
764 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
768 else if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
769 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
773 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
774 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
776 hcode = FLG_CHARUNSIGNEDCHAR;
778 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
780 hcode = FLG_RELAXTYPES;
781 DPRINTF (("Setting relax types!"));
785 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
786 ctype_unparse (ut2)));
791 if (cstring_isDefined (hint))
793 if (!context_suppressFlagMsg (ocode, fl))
795 return llgenhinterror (code, s, hint, fl);
806 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
808 if (hcode != INVALID_FLAG && hcode != ocode)
816 llsuppresshint ('-', code);
819 flagcode_recordError (code);
828 xllgentypeerror (char *srcFile, int srcLine,
829 ctype t1, exprNode e1, ctype t2, exprNode e2,
830 /*@only@*/ cstring s, fileloc fl)
832 return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
836 xllgenformattypeerror (char *srcFile, int srcLine,
837 ctype t1, exprNode e1, ctype t2, exprNode e2,
838 /*@only@*/ cstring s, fileloc fl)
840 return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
844 xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
846 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
848 llnosuppresshint (o);
849 flagcode_recordError (o);
855 flagcode_recordSuppressed (o);
861 xllgenhinterror (char *srcFile, int srcLine,
862 flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
865 if (!context_suppressFlagMsg (o, fl))
867 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
869 flagcode_recordError (o);
871 if (context_getFlag (FLG_HINTS))
892 flagcode_recordSuppressed (o);
897 llrealerror (char *srcFile, int srcLine, /*@only@*/ cstring s, fileloc fl)
899 return (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE));
903 llgenerroraux (char *srcFile, int srcLine,
904 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
906 if (context_inSuppressZone (fl))
916 if (llgenerrorreal (srcFile, srcLine, s, fl, iserror, indent)) {
924 xllforceerror (char *srcFile, int srcLine,
925 flagcode code, /*@only@*/ cstring s, fileloc fl)
927 flagcode_recordError (code);
929 if (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)) {
938 llgenerrorreal (char *srcFile, int srcLine,
939 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
943 /* duplicate message (rescanning a header file */
945 if (!messageLog_add (context_messageLog (), fl, s))
947 DPRINTF (("Duplicate message suppressed! %s / %s",
948 fileloc_unparse (fl), s));
953 if (iserror) context_hasError ();
955 if (context_unlimitedMessages ())
962 ** suppress excessive messages:
967 char *sc = cstring_toCharsSafe (s);
968 char *tmpmsg = strchr (sc, ':');
976 char *savechar = tmpmsg;
982 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
985 if (mcount == (context_getLimit () + 1))
987 limitmessage (s, fl);
991 if (mcount > (context_getLimit ()))
1001 cstring_free (lastmsg);
1002 lastmsg = cstring_fromCharsNew (tmpmsg);
1006 DPRINTF (("Here..."));
1008 if (context_hasAliasAnnote ())
1010 char *sc = cstring_toCharsSafe (s);
1011 char *fcolon = strchr (sc, ':');
1012 cstring a = context_getAliasAnnote ();
1017 s = message ("%q (%q)", s, a);
1024 afterColon = cstring_fromCharsNew (fcolon + 1);
1026 s = message ("%q (%q):%q", s, a, afterColon);
1030 if (context_hasMessageAnnote ())
1032 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1037 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1038 s = message ("%q (%q)", s, context_getMessageAnnote ());
1039 /*@=dependenttrans@*/
1046 afterColon = cstring_fromCharsNew (fcolon + 1);
1048 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1049 s = message ("%q (%q):%q", s,
1050 context_getMessageAnnote (), afterColon);
1051 /*@=dependenttrans@*/
1055 context_setNeednl ();
1058 if (context_showFunction ())
1060 cstring fname = fileloc_unparseFilename (g_currentloc);
1062 if (context_inIterDef ())
1064 fprintf (g_msgstream, "%s: (in iter %s)\n",
1065 cstring_toCharsSafe (fname),
1066 cstring_toCharsSafe (context_inFunctionName ()));
1068 else if (context_inIterEnd ())
1070 fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
1071 cstring_toCharsSafe (fname),
1072 cstring_toCharsSafe (context_inFunctionName ()));
1074 else if (context_inMacro ())
1076 fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
1077 cstring_toCharsSafe (context_inFunctionName ()));
1081 fprintf (g_msgstream, "%s: (in function %s)\n",
1082 cstring_toCharsSafe (fname),
1083 cstring_toCharsSafe (context_inFunctionName ()));
1086 cstring_free (fname);
1087 context_setShownFunction ();
1090 flstring = fileloc_unparse (fl);
1091 lastfileloclen = cstring_length (flstring);
1095 printError (g_msgstream, message (" %q: %q", flstring, s));
1099 printError (g_msgstream, message ("%q: %q", flstring, s));
1102 showSourceLoc (srcFile, srcLine);
1109 ** message contains no '\n'
1110 ** message fits in one line: print it
1111 ** message fits in two lines with 3-space indent after fileloc: print it
1112 ** split line with 5-space indent from left margin: print it
1117 void printMessage (FILE *stream, /*@only@*/ cstring s)
1119 printIndentMessage (stream, s, 0);
1123 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1125 static bool inbody = FALSE;
1126 int maxlen = context_getLineLen ();
1127 char *s = cstring_toCharsSafe (sc);
1130 llassertprotect (!inbody);
1138 llassertprotect (st != olds);
1140 mstring_split (&st, &t, maxlen, &indent);
1141 fprintf (stream, "%s\n", st);
1142 llassertprotect (t != s);
1144 } while (s != NULL) ;
1151 void printError (FILE *stream, /*@only@*/ cstring sc)
1153 int maxlen = context_getLineLen ();
1154 int nspaces = lastfileloclen + 5;
1155 int nextlen = maxlen - nspaces;
1156 int len = cstring_length (sc);
1158 char *s = cstring_toCharsSafe (sc);
1162 DPRINTF (("Print error: [%s]", sc));
1164 if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
1166 mstring_split (&s, &t, maxlen, &indent);
1168 fprintf (stream, "%s\n", s);
1172 len = mstring_length (t);
1174 if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1175 && len > (nextlen - 1))
1177 fprintf (stream, " %s\n", t);
1181 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1184 for (i = 0; i < nspaces; i++)
1189 spaces[nspaces] = '\0';
1194 mstring_split (&st, &t, nextlen, &indent);
1195 fprintf (stream, "%s%s\n", spaces, st);
1204 DPRINTF (("Here 1: [%s]", sc));
1206 if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1208 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1210 if (nspaces < 1) nspaces = 1;
1212 nextlen = maxlen - nspaces;
1214 mstring_split (&s, &t, maxlen, &indent);
1216 fprintf (stream, "%s\n", s);
1220 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1223 for (i = 0; i < nspaces; i++)
1228 spaces[nspaces] = '\0';
1234 mstring_split (&st, &t, nextlen, &indent);
1235 fprintf (stream, "%s%s\n", spaces, st);
1244 nextlen = maxlen - nspaces;
1246 DPRINTF (("Here 2: [%s]", s));
1247 mstring_split (&s, &t, maxlen, &indent);
1248 DPRINTF (("Here 3: [%s] [%s]", s, t));
1250 fprintf (stream, "%s\n", s);
1254 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1257 for (i = 0; i < nspaces; i++)
1262 spaces[nspaces] = '\0';
1267 DPRINTF (("Loop: [%s]", t));
1268 mstring_split (&st, &t, nextlen, &indent);
1269 DPRINTF (("Split: [%s] [%s]", st, t));
1270 fprintf (stream, "%s%s\n", spaces, st);
1271 DPRINTF (("Next..."));
1284 xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
1287 printError (stderr, message ("%q: *** Fatal bug: %q",
1288 fileloc_unparse (g_currentloc), s));
1289 showSourceLoc (srcFile, srcLine);
1297 lclfatalbug (char *msg)
1301 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1309 checkParseError (void)
1311 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1313 llfatalerror (message ("%q: Cannot recover from parse error.",
1314 fileloc_unparse (g_currentloc)));
1318 void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1321 static int numbugs = 0;
1322 static bool inbug = FALSE;
1326 cstring temps = fileloc_unparseRaw (file, line);
1328 fprintf (stderr, "%s: Recursive bug detected: %s\n",
1329 cstring_toCharsSafe (temps),
1330 cstring_toCharsSafe (s));
1331 cstring_free (temps);
1342 if (fileloc_isRealLib (g_currentloc))
1344 DPRINTF (("Here we are!"));
1345 llfatalerror (message ("%q: Library file appears to be corrupted. Error: %q: %s",
1346 fileloc_unparse (g_currentloc),
1347 fileloc_unparseRaw (file, line),
1352 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1354 llfatalerror (message ("%q: Cannot recover from parse error.",
1355 fileloc_unparse (g_currentloc)));
1358 (void) fflush (g_msgstream);
1359 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1360 fileloc_unparse (g_currentloc),
1361 fileloc_unparseRaw (file, line),
1365 (void) fflush (stderr);
1368 perror ("Possible system error diagnostic: ");
1370 (void) fflush (stderr);
1376 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
1378 llfatalerror (message ("%q: Cannot recover from last bug. (If you really want LCLint to try to continue, use -bugslimit <n>.)",
1379 fileloc_unparse (g_currentloc)));
1382 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1383 fileloc_free (lastbug);
1384 lastbug = fileloc_copy (g_currentloc);
1387 (void) fflush (stderr);
1393 lclbug (/*@only@*/ cstring s)
1396 printError (stderr, message ("*** Internal Bug: %q", s));
1399 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1405 llfatalerror (cstring s)
1408 printError (stderr, s);
1409 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1414 llfatalerrorLoc (/*@only@*/ cstring s)
1417 (void) fflush (g_msgstream);
1418 printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1419 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1420 (void) fflush (g_msgstream);
1425 xllgloberror (char *srcFile, int srcLine, /*@only@*/ cstring s)
1427 if (context_inSuppressRegion ())
1433 context_setNeednl ();
1435 context_hasError ();
1436 flagcode_recordError (FLG_SPECIAL);
1437 printError (g_msgstream, s);
1438 showSourceLoc (srcFile, srcLine);
1447 return (lclerrors > 0);
1451 lclHadNewError (void)
1453 static int lastcall = 0;
1455 if (lclerrors > lastcall)
1457 lastcall = lclerrors;
1467 lclNumberErrors (void)
1473 xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
1477 if (ltoken_getCode (t) != NOTTOKEN)
1479 cstring loc = ltoken_unparseLoc (t);
1481 lastfileloclen = cstring_length (loc);
1483 printError (g_msgstream, message ("%q: %q", loc, msg));
1484 showSourceLoc (srcFile, srcLine);
1488 printError (g_msgstream, msg);
1489 showSourceLoc (srcFile, srcLine);
1494 lclplainerror (/*@only@*/ cstring msg)
1498 printError (g_msgstream, msg);
1502 lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1505 (void) fflush (g_msgstream);
1506 printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1511 lclplainfatalerror (/*@only@*/ cstring msg)
1513 (void) fflush (g_msgstream);
1514 printError (stderr, message ("*** Cannot continue: %q", msg));
1519 lclRedeclarationError (ltoken id)
1521 cstring s = ltoken_getRawString (id);
1524 if (usymtab_existsEither (s))
1526 uentry le = usymtab_lookupEither (s);
1528 lclerror (id, message ("Respecification of %s", s));
1529 llgenindentmsg (message ("Previous specification of %q",
1530 uentry_getName (le)),
1531 uentry_whereSpecified (le));
1535 lclerror (id, message ("Identifier redeclared: %s", s));
1540 void genppllerror (flagcode code, /*@only@*/ cstring s)
1542 if (context_inSuppressZone (g_currentloc))
1548 if (context_getFlag (code))
1550 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1552 fprintf (g_msgstream, " >\n");
1557 if (code != FLG_PREPROC)
1559 llsuppresshint ('-', code);
1562 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1564 fprintf (stderr, "< more preprocessing .");
1574 void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1575 /*@only@*/ cstring hint)
1577 if (context_inSuppressZone (g_currentloc))
1580 cstring_free (hint);
1584 if (context_getFlag (code))
1587 context_clearPreprocessing ();
1590 context_setPreprocessing ();
1596 cstring_free (hint);
1601 void ppllerror (/*@only@*/ cstring s)
1603 genppllerror (FLG_PREPROC, s);
1606 void pplldiagmsg (cstring s)
1608 if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1610 fprintf (stderr, " >\n");
1612 fprintf (stderr, "< more preprocessing .");
1620 void loadllmsg (cstring s)
1622 if (context_getDebug (FLG_SHOWSCAN))
1624 fprintf (stderr, " >\n");
1626 fprintf (stderr, "< .");
1634 static void llreportparseerror (/*@only@*/ cstring s)
1636 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1642 llerror (FLG_SYNTAX, s);
1644 fileloc_free (lastparseerror);
1645 lastparseerror = fileloc_copy (g_currentloc);
1649 bool xlloptgenerror (char *srcFile, int srcLine,
1650 flagcode o, /*@only@*/ cstring s, fileloc loc)
1652 DPRINTF (("xllopt: %s", s));
1654 if (llrealerror (srcFile, srcLine, s, loc))
1656 DPRINTF (("Here we are!"));
1657 llsuppresshint ('-', o);
1659 flagcode_recordError (o);
1664 DPRINTF (("Suppressed!"));
1665 flagcode_recordSuppressed (o);
1670 bool xoptgenerror2 (char *srcFile, int srcLine,
1671 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1673 if (context_suppressFlagMsg (f1, loc))
1675 flagcode_recordSuppressed (f1);
1680 if (context_suppressFlagMsg (f2, loc))
1682 flagcode_recordSuppressed (f2);
1687 if (llrealerror (srcFile, srcLine, s, loc))
1689 llsuppresshint2 ('-', f1, f2);
1690 flagcode_recordError (f2);
1696 flagcode_recordSuppressed (f2);
1704 bool xoptgenerror2n (char *srcFile, int srcLine,
1705 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1708 if (context_suppressFlagMsg (f1, loc))
1710 flagcode_recordSuppressed (f1);
1715 if (context_suppressNotFlagMsg (f2, loc))
1717 flagcode_recordSuppressed (f2);
1722 if (llrealerror (srcFile, srcLine, s, loc))
1724 llsuppresshint ('+', f2);
1725 flagcode_recordError (f2);
1730 flagcode_recordSuppressed (f2);
1736 bool xllnoptgenerror (char *srcFile, int srcLine,
1737 flagcode o, /*@only@*/ cstring s, fileloc loc)
1739 if (llrealerror (srcFile, srcLine, s, loc))
1741 llsuppresshint ('+', o);
1742 flagcode_recordError (o);
1747 flagcode_recordSuppressed (o);
1751 void llparseerror (cstring s)
1753 if (context_getFlag (FLG_TRYTORECOVER))
1757 if (parseerrorcount > GIVEUPPARSE)
1759 if (cstring_isDefined (s))
1761 llfatalerror (message ("%q: Parse Error: %q. "
1762 "Too many errors, giving up.",
1763 fileloc_unparse (g_currentloc), s));
1767 llfatalerror (message ("%q: Parse Error. Too many errors, giving up.",
1768 fileloc_unparse (g_currentloc)));
1773 if (cstring_isDefined (s))
1775 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1780 llreportparseerror (message ("Parse Error. Attempting to continue."));
1788 if (cstring_isDefined (s))
1790 msg = message ("Parse Error: %q.", s);
1794 msg = message ("Parse Error.");
1798 (message ("%q: %s (For help on parse errors, "
1799 "see lclint -help parseerrors.)",
1800 fileloc_unparse (g_currentloc), msg));
1804 bool xfsgenerror (char *srcFile, int srcLine,
1805 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
1807 if (flagSpec_isOn (fs, fl))
1809 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
1811 llsuppresshint ('-', flagSpec_getFirstOn (fs, fl));
1812 flagcode_recordError (flagSpec_getFirstOn (fs, fl));
1817 flagcode_recordSuppressed (flagSpec_getFirstOn (fs, fl));
1823 flagcode_recordSuppressed (flagSpec_getDominant (fs));
1829 bool doCheck (bool x, cstring pred, cstring file, int line)
1832 llbug (message ("%q: Check Failed: %s",
1833 fileloc_unparseRaw (file, line),
1840 /*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1845 #ifndef HAVE_STRERROR
1848 result = strerror (errnum);
1851 /* VAXCRTL's strerror() takes an optional second argument, which only
1852 matters when the first argument is EVMSERR. However, it's simplest
1853 just to pass it unconditionally. `vaxc$errno' is declared in
1854 <errno.h>, and maintained by the library in parallel with `errno'.
1855 We assume that caller's `errnum' either matches the last setting of
1856 `errno' by the library or else does not have the value `EVMSERR'. */
1858 result = strerror (errnum, vaxc$errno);
1863 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1866 return cstring_fromChars (result);
1869 void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1874 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1875 fileloc_unparse (g_currentloc),
1876 fileloc_unparseRaw (file, line),
1888 (void) fflush (g_msgstream);
1889 (void) fflush (stderr);