]> andersk Git - splint.git/blame - src/llerror.c
*** empty log message ***
[splint.git] / src / llerror.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
28bf4b0b 3** Copyright (C) 1994-2001 University of Virginia,
616915dd 4** Massachusetts Institute of Technology
5**
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.
10**
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.
15**
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.
19**
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
23*/
24/*
25** llerror.c
26**
27** error reporting procedures
28*/
29
30# include "lclintMacros.nf"
31# include <string.h>
32# include <errno.h>
33# include "llbasic.h"
34# include "llmain.h"
35# include "version.h"
36
28bf4b0b 37/* Don't allow possibly-recursive assertion failures. */
38# undef llassert
39# define llassert llassertprotect
40
616915dd 41static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
42 /*@modifies *p_stream@*/ ;
43
44# ifndef NOLCL
45static int lclerrors = 0;
46# endif
47
48static int lastfileloclen = 10;
49static /*@only@*/ cstring lastmsg = cstring_undefined;
50static int mcount = 0;
51static /*@only@*/ cstring saveOneMessage = cstring_undefined;
52static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
53static /*@only@*/ fileloc lastbug = fileloc_undefined;
28bf4b0b 54static bool llgenerrorreal (char *p_srcFile, int p_srcLine,
55 /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
616915dd 56 /*@modifies g_msgstream@*/ ;
28bf4b0b 57static bool llgenerroraux (char *p_srcFile, int p_srcLine,
58 /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
616915dd 59 /*@modifies g_msgstream@*/ ;
28bf4b0b 60
616915dd 61static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
62 /*@globals lastfileloclen @*/
63 /*@modifies *p_stream@*/ ;
64static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
65 /*@modifies *p_stream@*/ ;
66
28bf4b0b 67static void llgenhint (/*@only@*/ cstring p_s) /*@modifies g_msgstream@*/ ;
68
69static void showSourceLoc (char *srcFile, int srcLine)
70 /*@modifies g_msgstream@*/
71{
72 if (context_getFlag (FLG_SHOWSOURCELOC)) {
73 llgenhint (message ("%s:%d: Source code error generation point.",
74 cstring_fromChars (srcFile), srcLine));
75 }
76
77}
78
616915dd 79static /*@null@*/ char *
80maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
81{
82 if (a > b) return a;
83 else return b;
84}
85
86static void
87printBugReport (void)
88{
89 fprintf (stderr, " *** Please report bug to %s ***\n",
90 LCLINT_MAINTAINER);
91 llflush ();
92 /* don't exit (EXIT_FAILURE); */
93}
94
95static bool s_needsPrepare = TRUE;
96
97void prepareMessage (void)
98{
990ec868 99 DPRINTF (("Prepare message: %s", bool_unparse (context_loadingLibrary ())));
100
101 if ((context_isPreprocessing () || context_loadingLibrary ())
616915dd 102 && s_needsPrepare
103 && context_getDebug (FLG_SHOWSCAN))
104 {
105 llflush ();
106 fprintf (stderr, " >\n");
107 s_needsPrepare = FALSE;
108 }
109
110 llflush ();
111}
112
113void closeMessage (void)
114{
115 if (context_isPreprocessing ()
116 && context_getDebug (FLG_SHOWSCAN))
117 {
118 llflush ();
119 fprintf (stderr, "< more preprocessing .");
120
28bf4b0b 121 llassertprotect (!s_needsPrepare);
616915dd 122 s_needsPrepare = TRUE;
123 }
124 else
125 {
126 llflush ();
127 }
128}
129
130void
131llmsg (/*@only@*/ cstring s)
132{
133 context_setNeednl ();
134 prepareMessage ();
135 printMessage (g_msgstream, s);
136 closeMessage ();
137}
138
139void
140lldiagmsg (/*@only@*/ cstring s)
141{
142 context_setNeednl ();
143 prepareMessage ();
144 printMessage (stderr, s);
145 closeMessage ();
146}
147
148void
149llmsgplain (/*@only@*/ cstring s)
150{
151 context_setNeednl ();
152 prepareMessage ();
153 printMessage (g_msgstream, s);
154 closeMessage ();
155}
156
f3f2d5ea 157void llerror_flagWarning (cstring s)
616915dd 158{
159 if (context_getFlag (FLG_WARNFLAGS))
160 {
161 showHerald ();
162
163 if (fileloc_isBuiltin (g_currentloc))
164 {
f3f2d5ea 165 llmsg (message ("Warning: %q", s));
616915dd 166 }
167 else
168 {
f3f2d5ea 169 llgenmsg (message ("Warning: %q", s), g_currentloc);
616915dd 170 }
171 }
f3f2d5ea 172 else
173 {
174 cstring_free (s);
175 }
616915dd 176}
177
178static void
179llgenhint (/*@only@*/ cstring s) /*@modifies g_msgstream@*/
180{
28bf4b0b 181 int indent = context_getIndentSpaces () - 1;
182
183 if (indent < 0) indent = 0;
184
616915dd 185 context_setNeednl ();
28bf4b0b 186 printIndentMessage (g_msgstream, s, indent);
616915dd 187}
188
189void
190llhint (cstring s)
191{
192 if (context_getFlag (FLG_HINTS) &&
193 !(context_inSuppressRegion () || context_inSuppressZone (g_currentloc)))
194 {
195 llgenhint (s);
196 }
197 else
198 {
199 cstring_free (s);
200 }
201}
202
203static void
204llshowhint (flagcode f)
205{
206 if (context_getFlag (FLG_HINTS))
207 {
208 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
209 {
210 cstring desc = flagcodeHint (f);
211
212 if (cstring_isDefined (desc))
213 {
214 llgenhint (cstring_copy (desc));
215 }
216 }
217 }
218}
219
28bf4b0b 220static void
221llsuppresshint2 (char c, flagcode f1, flagcode f2)
222{
223
224 if (context_getFlag (FLG_HINTS))
225 {
226 if ((flagcode_numReported (f1) == 0
227 || flagcode_numReported (f2) == 0)
228 || context_getFlag (FLG_FORCEHINTS))
229 {
230 cstring desc = flagcodeHint (f1);
231 context_setNeednl ();
232 lastfileloclen = 8;
233
234 if (cstring_isUndefined (desc))
235 {
236 desc = flagcodeHint (f2);
237 }
238
239 if (flagcode_isNamePrefixFlag (f1))
240 {
241 f1 = FLG_NAMECHECKS;
242 }
243
244 if (flagcode_isNamePrefixFlag (f2))
245 {
246 f2 = FLG_NAMECHECKS;
247 }
248
abb1cb43 249 if (f1 == f2)
28bf4b0b 250 {
abb1cb43 251 if (cstring_isDefined (desc))
252 {
253 llgenhint (message ("%s (Setting %h%s will suppress message)", desc,
254 c,
255 flagcode_unparse (f1)));
256 }
257 else
258 {
259 llgenhint (message ("(Setting %h%s will suppress message)",
260 c, flagcode_unparse (f1)));
261 }
28bf4b0b 262 }
263 else
264 {
abb1cb43 265 if (cstring_isDefined (desc))
266 {
267 llgenhint (message ("%s (Setting either %h%s or %h%s will suppress message)", desc,
268 c,
269 flagcode_unparse (f1),
270 c,
271 flagcode_unparse (f2)));
272 }
273 else
274 {
275 llgenhint (message ("(Setting either %h%s or %h%s will suppress message)", c,
276 flagcode_unparse (f1),
277 c, flagcode_unparse (f2)));
278 }
28bf4b0b 279 }
280 }
281 }
282}
616915dd 283
284static void
285llsuppresshint (char c, flagcode f)
286{
616915dd 287 if (context_getFlag (FLG_HINTS))
288 {
289 if ((flagcode_numReported (f) == 0) || context_getFlag (FLG_FORCEHINTS))
290 {
291 cstring desc = flagcodeHint (f);
292 context_setNeednl ();
293 lastfileloclen = 8;
294
295 if (flagcode_isNamePrefixFlag (f))
296 {
297 f = FLG_NAMECHECKS;
298 }
299
300 if (cstring_isDefined (desc))
301 {
302 llgenhint (message ("%s (%h%s will suppress message)", desc, c,
28bf4b0b 303 flagcode_unparse (f)));
616915dd 304 }
305 else
306 {
307 llgenhint (message ("(%h%s will suppress message)", c,
28bf4b0b 308 flagcode_unparse (f)));
616915dd 309 }
310 }
311 }
312}
313
314static void
315llnosuppresshint (flagcode f)
316{
616915dd 317 if (context_getFlag (FLG_FORCEHINTS))
318 {
319 cstring desc = flagcodeHint (f);
320 context_setNeednl ();
321 lastfileloclen = 8;
322
323 if (cstring_isDefined (desc))
324 {
325 printError (g_msgstream, message (" %s", desc));
326 }
327 }
328}
329
330/*@constant int MAXSEARCH; @*/
331# define MAXSEARCH 20
332
333/*@constant int MINLINE; @*/
334# define MINLINE 35
335
336typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
337
338static void
339mstring_split (/*@returned@*/ char **sp,
340 /*@out@*/ nd_charp *tp,
341 int maxline, /*@in@*/ int *indentchars)
342{
343 char *nl;
344 char *t;
345 char *s = *sp;
28bf4b0b 346 char *osp = *sp;
616915dd 347
348 *tp = NULL;
349
28bf4b0b 350 DPRINTF (("Split: %s / %d", *sp, maxline));
351
616915dd 352 if (maxline < MINLINELEN)
353 {
354 maxline = MINLINELEN;
355 }
356
357 if (*indentchars > 0)
358 {
359 s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
28bf4b0b 360 osp = s;
616915dd 361 }
362
363 nl = strchr (s, '\n');
364
365 /*
366 ** splitting:
367 **
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
372 ** split after '}'
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
376 **
377 ** special code: slash [1-9] after a newline means indent the rest <n> chars
378 **
379 */
380
381 if ((nl != NULL) && ((nl - s) < maxline))
382 {
383 *nl = '\0';
384 t = nl + 1;
385
386 if (*t == '\0')
387 {
28bf4b0b 388 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 389 return;
390 }
391
392 if (*t >= '\1' && *t <= '\7')
393 {
394 *indentchars += (int) (*t - '\1') + 1;
395 t++;
28bf4b0b 396 }
397
616915dd 398 *tp = t;
399 return;
400 }
401 else if (size_toInt (strlen (s)) < maxline)
402 {
28bf4b0b 403 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 404 return;
405 }
406 else
407 {
408 int i = 0;
409 char savechar;
410 char *lcolon, *lsemi, *splitat;
411
412 splitat = NULL;
413
414 t = s + maxline - 1;
415 savechar = *t;
416
417 *t = '\0';
418 lcolon = strrchr (s, ':');
419 lsemi = strrchr (s, ';');
420 *t = savechar;
421
422 splitat = maxcp (lcolon, lsemi);
423
424 if (splitat != NULL && ((int)(splitat - s) > MINLINE)
28bf4b0b 425 && *(splitat) != '\0'
426 && *(splitat + 1) == ' '
427 && (*(splitat + 2) != '}' && (*(splitat + 2) != '\0')))
616915dd 428 {
429 *(splitat + 1) = '\0';
430 t = splitat + 2;
431 *tp = t;
28bf4b0b 432 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 433 return;
434 }
435
436 while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
437 {
438 t--;
439 i++;
440 }
441
442 if (*t != ' ' && *t != '\t')
443 {
28bf4b0b 444 llassertprotect (maxline > 0);
616915dd 445 t = mstring_copy (s + maxline);
446 *(s + maxline) = '\0';
447
448 if (*t == '\0')
449 {
450 sfree (t);
28bf4b0b 451 llassertprotect (*tp == NULL || (*tp > osp));
616915dd 452 return;
453 }
454
455 mstring_markFree (t);
456 *tp = t;
28bf4b0b 457 /* Won't be true since t is a copy: llassertprotect (*tp == NULL || (*tp > osp)); */
616915dd 458 return;
459 }
460 else
461 {
28bf4b0b 462
616915dd 463 *t = '\0';
464 t++;
28bf4b0b 465
616915dd 466 if (*t == '\0') return;
467
468 /*
469 ** returns unqualified as only
470 */
471
472 *tp = t;
28bf4b0b 473
474# if 0
475 /* Hack to prevent error case for wierd strings. */
476 if (t <= osp)
477 {
478 *tp = NULL;
479 return;
480 }
481 llassertprotect (*tp == NULL || (*tp > osp));
482# endif
483
616915dd 484 return;
485 }
486 }
28bf4b0b 487
488 BADBRANCH;
616915dd 489}
490
491static
492void limitmessage (/*@only@*/ cstring s, fileloc loc)
493{
494 if (mcount > context_getLimit () + 1)
495 {
496 cstring_free (s);
497 }
498 else
499 {
500 cstring flstring = fileloc_unparse (loc);
501
502 lastfileloclen = cstring_length (flstring);
503 cstring_free (saveOneMessage);
504 saveOneMessage = message ("%q: %q", flstring, s);
505 }
506}
507
508static int parseerrorcount = 0;
509
510void cleanupMessages ()
511{
512 parseerrorcount = 0;
513
514 if (context_unlimitedMessages ())
515 {
516 ;
517 }
518 else
519 {
520 int unprinted = mcount - context_getLimit ();
521
522 if (unprinted > 0)
523 {
524 if (unprinted == 1 && cstring_isDefined (saveOneMessage))
525 {
526 prepareMessage ();
527 printError (g_msgstream, saveOneMessage);
528 closeMessage ();
529 saveOneMessage = cstring_undefined;
530 }
531 else
532 {
533 if (cstring_isDefined (saveOneMessage))
534 {
535 /* cstring_free (saveOneMessage); */
536 saveOneMessage = cstring_undefined;
537 }
538
539 fprintf (g_msgstream, "%s: (%d more similar errors unprinted)\n",
540 cstring_toCharsSafe (fileloc_filename (g_currentloc)),
541 mcount - context_getLimit ());
542 }
543 }
544 }
545
546 mcount = 0;
547}
548
549void
550llgenmsg (/*@only@*/ cstring s, fileloc fl)
551{
552 cstring flstring = fileloc_unparse (fl);
553 lastfileloclen = cstring_length (flstring);
554
555 prepareMessage ();
556 (void) printError (g_msgstream, message ("%q: %q", flstring, s));
557 closeMessage ();
558}
559
560void
561llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
562{
563 cstring flstring = fileloc_unparse (fl);
564
565 prepareMessage ();
28bf4b0b 566 (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), context_getIndentSpaces ());
616915dd 567 closeMessage ();
568}
569
570void
571llgenindentmsgnoloc (/*@only@*/ cstring s)
572{
573 prepareMessage ();
28bf4b0b 574 (void) printIndentMessage (g_msgstream, s, context_getIndentSpaces ());
616915dd 575 closeMessage ();
576}
577
578static bool
28bf4b0b 579llgentypeerroraux (char *srcFile, int srcLine,
580 flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
581 /*@only@*/ cstring s, fileloc fl)
616915dd 582{
583 cstring hint = cstring_undefined;
584 flagcode code = ocode;
585 flagcode hcode = INVALID_FLAG;
586 ctype ut1 = t1;
587 ctype ut2 = t2;
588
990ec868 589 DPRINTF (("Type error [%s]: %s / %s : %s / %s",
590 flagcode_unparse (ocode),
616915dd 591 exprNode_unparse (e1), exprNode_unparse (e2),
592 ctype_unparse (t1), ctype_unparse (t2)));
593
594 DPRINTF (("Bool: %s / %s",
595 bool_unparse (ctype_isBool (t1)),
596 bool_unparse (ctype_isBool (t2))));
597
598 /*
599 ** Set the flag using the underlying types that didn't match.
600 */
601
602 while (ctype_isPointer (ut1) && ctype_isPointer (ut2)) {
603 ut1 = ctype_baseArrayPtr (ut1);
604 ut2 = ctype_baseArrayPtr (ut2);
605 }
606
607 if ((ctype_isFloat (ut1) && ctype_isDouble (ut2))
608 || (ctype_isFloat (ut1) && ctype_isDouble (ut2)))
609 {
610 hcode = FLG_FLOATDOUBLE;
611 }
612 else if ((exprNode_isCharLit (e1) && ctype_isInt (ut2))
613 || (exprNode_isCharLit (e2) && ctype_isInt (ut1)))
614 {
615 hcode = FLG_CHARINTLITERAL;
616 }
617 else if ((exprNode_isNumLit (e1) && ctype_isReal (ut2))
618 || (exprNode_isNumLit (e2) && ctype_isReal (ut1)))
619 {
620 hcode = FLG_NUMLITERAL;
621 }
622 else if ((ctype_isManifestBool (ut1) && ctype_isInt (ut2))
623 || (ctype_isInt (ut1) && ctype_isManifestBool (ut2)))
624 /* evs 2000-07-24: was ctype_isDirectBool */
625 {
626 hcode = FLG_BOOLINT;
627 }
628 else if (((ctype_isChar (ut1) && !ctype_isInt (ut1)) && ctype_isInt (ut2))
629 || ((ctype_isInt (ut1) && (ctype_isChar (ut2) && !ctype_isInt (ut2)))))
630 {
631 hcode = FLG_CHARINT;
632 }
633 else if ((ctype_isInt (ut1) && ctype_isInt (ut2))
634 || (ctype_isChar (ut1) && ctype_isChar (ut2))
635 || (ctype_isDouble (ut1) && ctype_isDouble (ut2)))
636 {
637 if (!bool_equal (ctype_isSigned (ut1), ctype_isSigned (ut2)))
638 {
639 hcode = FLG_IGNORESIGNS;
640 }
641 else
642 {
643 hcode = FLG_IGNOREQUALS;
644 }
645 }
646 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
647 {
648 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
649 {
650 hcode = FLG_MATCHANYINTEGRAL;
651 }
652 else if (ctype_match (ut2, ctype_ulint))
653 {
654 hcode = FLG_LONGUNSIGNEDINTEGRAL;
655 }
656 else if (ctype_match (ut2, ctype_lint))
657 {
658 hcode = FLG_LONGINTEGRAL;
659 }
660 else if (ctype_isInt (ut2))
661 {
662 hcode = FLG_MATCHANYINTEGRAL;
663 }
664 else
665 {
666 ;
667 }
668 }
669 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
670 {
671 ctype tr = ctype_realType (ut1);
672
673 if (ctype_isArbitraryIntegral (tr))
674 {
675 hcode = FLG_MATCHANYINTEGRAL;
676 }
677 else if (ctype_match (ut1, ctype_ulint))
678 {
679 if (ctype_isUnsignedIntegral (tr))
680 {
681 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
682 }
683 else if (ctype_isSignedIntegral (tr))
684 {
685 ;
686 }
687 else
688 {
689 hcode = FLG_LONGUNSIGNEDINTEGRAL;
690 }
691 }
692 else if (ctype_match (ut1, ctype_lint))
693 {
694 if (ctype_isSignedIntegral (tr))
695 {
696 hcode = FLG_LONGSIGNEDINTEGRAL;
697 }
698 else if (ctype_isSignedIntegral (tr))
699 {
700 ;
701 }
702 else
703 {
704 hcode = FLG_LONGINTEGRAL;
705 }
706 }
707 else if (ctype_isInt (ut1))
708 {
709 hcode = FLG_MATCHANYINTEGRAL;
710 }
711 else
712 {
713 ;
714 }
715 }
990ec868 716 else
717 {
718 ;
719 }
720
721 if (hcode == INVALID_FLAG)
616915dd 722 {
990ec868 723 DPRINTF (("[%s] %s - %s / %s",
724 ctype_unparse (ut1),
725 bool_unparse (ctype_isEnum (ut1)),
726 bool_unparse (ctype_isEnum (ctype_realType (ut1))),
727 bool_unparse (ctype_isInt (ut2))));
616915dd 728
990ec868 729 if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
616915dd 730 {
990ec868 731 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
732 ctype ct = uentry_getType (ue1);
733
734 if (ctype_match (ct, ut2))
735 {
736 code = FLG_ABSTRACT;
737 hint = message ("Underlying types match, but %s is an "
738 "abstract type that is not accessible here.",
739 ctype_unparse (t1));
740 }
616915dd 741 }
990ec868 742 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
743 {
744 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
745 ctype ct = uentry_getType (ue);
746
747 if (ctype_match (ct, ut1))
748 {
749 code = FLG_ABSTRACT;
750 hint = message ("Underlying types match, but %s is an "
751 "abstract type that is not accessible here.",
752 ctype_unparse (t2));
753 }
754 }
755 else
756 {
757 ; /* Not an abstract mismatch. */
758 }
759
616915dd 760
990ec868 761 if (hcode == INVALID_FLAG)
616915dd 762 {
990ec868 763 if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
764 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
765 {
766 hcode = FLG_ENUMINT;
767 }
768 else if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
769 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
770 {
771 hcode = FLG_ENUMINT;
772 }
773 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
774 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
775 {
776 hcode = FLG_CHARUNSIGNEDCHAR;
777 }
778 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
779 {
780 hcode = FLG_RELAXTYPES;
781 DPRINTF (("Setting relax types!"));
782 }
783 else
784 {
785 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
786 ctype_unparse (ut2)));
787 }
616915dd 788 }
789 }
616915dd 790
791 if (cstring_isDefined (hint))
792 {
793 if (!context_suppressFlagMsg (ocode, fl))
794 {
795 return llgenhinterror (code, s, hint, fl);
796 }
797 else
798 {
799 cstring_free (s);
800 cstring_free (hint);
801 return FALSE;
802 }
803 }
804 else
805 {
28bf4b0b 806 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
616915dd 807 {
808 if (hcode != INVALID_FLAG && hcode != ocode)
809 {
810 code = hcode;
811 llshowhint (code);
812
813 }
814 else
815 {
816 llsuppresshint ('-', code);
817 }
818
819 flagcode_recordError (code);
820 return TRUE;
821 }
822
823 return FALSE;
824 }
825}
826
827bool
28bf4b0b 828xllgentypeerror (char *srcFile, int srcLine,
829 ctype t1, exprNode e1, ctype t2, exprNode e2,
830 /*@only@*/ cstring s, fileloc fl)
616915dd 831{
28bf4b0b 832 return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
616915dd 833}
834
835bool
28bf4b0b 836xllgenformattypeerror (char *srcFile, int srcLine,
837 ctype t1, exprNode e1, ctype t2, exprNode e2,
838 /*@only@*/ cstring s, fileloc fl)
616915dd 839{
28bf4b0b 840 return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
616915dd 841}
842
843bool
28bf4b0b 844xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
616915dd 845{
28bf4b0b 846 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
616915dd 847 {
848 llnosuppresshint (o);
849 flagcode_recordError (o);
850 closeMessage ();
851 return TRUE;
852 }
853 else
854 {
855 flagcode_recordSuppressed (o);
856 return FALSE;
857 }
858}
859
860bool
28bf4b0b 861xllgenhinterror (char *srcFile, int srcLine,
862 flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
863 fileloc fl)
616915dd 864{
865 if (!context_suppressFlagMsg (o, fl))
866 {
28bf4b0b 867 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
616915dd 868 {
869 flagcode_recordError (o);
870
871 if (context_getFlag (FLG_HINTS))
872 {
873 llgenhint (hint);
874 }
875 else
876 {
877 cstring_free (hint);
878 }
879
880 closeMessage ();
881 return TRUE;
882 }
883
884 cstring_free (hint);
885 }
886 else
887 {
888 cstring_free (hint);
889 cstring_free (s);
890 }
891
892 flagcode_recordSuppressed (o);
893 return FALSE;
894}
895
896static bool
28bf4b0b 897llrealerror (char *srcFile, int srcLine, /*@only@*/ cstring s, fileloc fl)
616915dd 898{
28bf4b0b 899 return (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE));
616915dd 900}
901
902static bool
28bf4b0b 903llgenerroraux (char *srcFile, int srcLine,
904 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
616915dd 905{
616915dd 906 if (context_inSuppressZone (fl))
907 {
908 cstring_free (s);
909 return FALSE;
910 }
911 else
912 {
913 ;
914 }
915
28bf4b0b 916 if (llgenerrorreal (srcFile, srcLine, s, fl, iserror, indent)) {
917 return TRUE;
918 } else {
919 return FALSE;
920 }
616915dd 921}
922
28bf4b0b 923bool
924xllforceerror (char *srcFile, int srcLine,
925 flagcode code, /*@only@*/ cstring s, fileloc fl)
616915dd 926{
927 flagcode_recordError (code);
28bf4b0b 928
929 if (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)) {
930 closeMessage ();
931 return TRUE;
932 } else {
933 return FALSE;
934 }
616915dd 935}
936
937static bool
28bf4b0b 938llgenerrorreal (char *srcFile, int srcLine,
939 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
616915dd 940{
941 cstring flstring;
942
943 /* duplicate message (rescanning a header file */
944
945 if (!messageLog_add (context_messageLog (), fl, s))
946 {
28bf4b0b 947 DPRINTF (("Duplicate message suppressed! %s / %s",
948 fileloc_unparse (fl), s));
616915dd 949 cstring_free (s);
950 return FALSE;
951 }
952
953 if (iserror) context_hasError ();
954
955 if (context_unlimitedMessages ())
956 {
957 ;
958 }
959 else
960 {
961 /*
962 ** suppress excessive messages:
963 ** check up to ':'
964 **
965 */
966
967 char *sc = cstring_toCharsSafe (s);
968 char *tmpmsg = strchr (sc, ':');
969
970 if (tmpmsg == NULL)
971 {
972 tmpmsg = sc;
973 }
974 else
975 {
976 char *savechar = tmpmsg;
977 *tmpmsg = '\0';
978 tmpmsg = sc;
979 *savechar = ':';
980 }
981
982 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
983 {
984 mcount++;
985 if (mcount == (context_getLimit () + 1))
986 {
987 limitmessage (s, fl);
988 return FALSE;
989 }
990
991 if (mcount > (context_getLimit ()))
992 {
993 cstring_free (s);
994 return FALSE;
995 }
996 }
997 else
998 {
999 cleanupMessages ();
1000 mcount = 0;
1001 cstring_free (lastmsg);
1002 lastmsg = cstring_fromCharsNew (tmpmsg);
1003 }
1004 }
1005
28bf4b0b 1006 DPRINTF (("Here..."));
1007
616915dd 1008 if (context_hasAliasAnnote ())
1009 {
1010 char *sc = cstring_toCharsSafe (s);
1011 char *fcolon = strchr (sc, ':');
1012 cstring a = context_getAliasAnnote ();
1013
1014
1015 if (fcolon == NULL)
1016 {
1017 s = message ("%q (%q)", s, a);
1018 }
1019 else
1020 {
1021 cstring afterColon;
1022
1023 *fcolon = '\0';
1024 afterColon = cstring_fromCharsNew (fcolon + 1);
1025
1026 s = message ("%q (%q):%q", s, a, afterColon);
1027 }
1028 }
1029
1030 if (context_hasMessageAnnote ())
1031 {
1032 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1033
1034
1035 if (fcolon == NULL)
1036 {
1037 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1038 s = message ("%q (%q)", s, context_getMessageAnnote ());
1039 /*@=dependenttrans@*/
1040 }
1041 else
1042 {
1043 cstring afterColon;
1044
1045 *fcolon = '\0';
1046 afterColon = cstring_fromCharsNew (fcolon + 1);
1047
1048 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1049 s = message ("%q (%q):%q", s,
1050 context_getMessageAnnote (), afterColon);
1051 /*@=dependenttrans@*/
1052 }
1053 }
1054
1055 context_setNeednl ();
1056 prepareMessage ();
1057
1058 if (context_showFunction ())
1059 {
1060 cstring fname = fileloc_unparseFilename (g_currentloc);
1061
1062 if (context_inIterDef ())
1063 {
1064 fprintf (g_msgstream, "%s: (in iter %s)\n",
1065 cstring_toCharsSafe (fname),
1066 cstring_toCharsSafe (context_inFunctionName ()));
1067 }
1068 else if (context_inIterEnd ())
1069 {
1070 fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
1071 cstring_toCharsSafe (fname),
1072 cstring_toCharsSafe (context_inFunctionName ()));
1073 }
1074 else if (context_inMacro ())
1075 {
1076 fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
1077 cstring_toCharsSafe (context_inFunctionName ()));
1078 }
1079 else
1080 {
1081 fprintf (g_msgstream, "%s: (in function %s)\n",
1082 cstring_toCharsSafe (fname),
1083 cstring_toCharsSafe (context_inFunctionName ()));
1084 }
1085
1086 cstring_free (fname);
1087 context_setShownFunction ();
1088 }
1089
1090 flstring = fileloc_unparse (fl);
616915dd 1091 lastfileloclen = cstring_length (flstring);
1092
1093 if (indent)
1094 {
1095 printError (g_msgstream, message (" %q: %q", flstring, s));
1096 }
1097 else
1098 {
1099 printError (g_msgstream, message ("%q: %q", flstring, s));
1100 }
1101
28bf4b0b 1102 showSourceLoc (srcFile, srcLine);
616915dd 1103 return TRUE;
1104}
1105
1106/*
1107** printMessage
1108**
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
1113**
1114*/
1115
1116static
1117void printMessage (FILE *stream, /*@only@*/ cstring s)
1118{
1119 printIndentMessage (stream, s, 0);
1120}
1121
1122static
1123void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1124{
28bf4b0b 1125 static bool inbody = FALSE;
616915dd 1126 int maxlen = context_getLineLen ();
1127 char *s = cstring_toCharsSafe (sc);
28bf4b0b 1128 char *olds = NULL;
616915dd 1129
28bf4b0b 1130 llassertprotect (!inbody);
1131 inbody = TRUE;
616915dd 1132
1133 do
1134 {
1135 char *t = NULL;
1136 char *st = s;
1137
28bf4b0b 1138 llassertprotect (st != olds);
1139 olds = st;
616915dd 1140 mstring_split (&st, &t, maxlen, &indent);
1141 fprintf (stream, "%s\n", st);
28bf4b0b 1142 llassertprotect (t != s);
616915dd 1143 s = t;
1144 } while (s != NULL) ;
1145
1146 cstring_free (sc);
28bf4b0b 1147 inbody = FALSE;
616915dd 1148}
1149
1150static
1151void printError (FILE *stream, /*@only@*/ cstring sc)
1152{
1153 int maxlen = context_getLineLen ();
1154 int nspaces = lastfileloclen + 5;
1155 int nextlen = maxlen - nspaces;
1156 int len = cstring_length (sc);
1157 int indent = 0;
1158 char *s = cstring_toCharsSafe (sc);
1159 char *os = s;
1160 char *t = NULL;
1161
28bf4b0b 1162 DPRINTF (("Print error: [%s]", sc));
1163
616915dd 1164 if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
1165 {
1166 mstring_split (&s, &t, maxlen, &indent);
1167
1168 fprintf (stream, "%s\n", s);
1169
1170 if (t != NULL)
1171 {
1172 len = mstring_length (t);
1173
1174 if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1175 && len > (nextlen - 1))
1176 {
1177 fprintf (stream, " %s\n", t);
1178 }
1179 else
1180 {
1181 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1182 int i;
1183
1184 for (i = 0; i < nspaces; i++)
1185 {
1186 spaces[i] = ' ';
1187 }
1188
1189 spaces[nspaces] = '\0';
1190
1191 while (t != NULL)
1192 {
1193 char *st = t;
1194 mstring_split (&st, &t, nextlen, &indent);
1195 fprintf (stream, "%s%s\n", spaces, st);
1196 }
1197
1198 sfree (spaces);
1199 }
1200 }
1201 }
1202 else
1203 {
28bf4b0b 1204 DPRINTF (("Here 1: [%s]", sc));
1205
616915dd 1206 if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1207 {
1208 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1209
1210 if (nspaces < 1) nspaces = 1;
1211
1212 nextlen = maxlen - nspaces;
1213
1214 mstring_split (&s, &t, maxlen, &indent);
1215
1216 fprintf (stream, "%s\n", s);
1217
1218 if (t != NULL)
1219 {
1220 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1221 int i;
1222
1223 for (i = 0; i < nspaces; i++)
1224 {
1225 spaces[i] = ' ';
1226 }
1227
1228 spaces[nspaces] = '\0';
1229
1230 while (t != NULL)
1231 {
1232 char *st = t;
1233
1234 mstring_split (&st, &t, nextlen, &indent);
1235 fprintf (stream, "%s%s\n", spaces, st);
1236 }
1237
1238 sfree (spaces);
1239 }
1240 }
1241 else
1242 {
1243 nspaces = 4;
1244 nextlen = maxlen - nspaces;
1245
28bf4b0b 1246 DPRINTF (("Here 2: [%s]", s));
616915dd 1247 mstring_split (&s, &t, maxlen, &indent);
28bf4b0b 1248 DPRINTF (("Here 3: [%s] [%s]", s, t));
616915dd 1249
1250 fprintf (stream, "%s\n", s);
1251
1252 if (t != NULL)
1253 {
1254 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1255 int i;
1256
1257 for (i = 0; i < nspaces; i++)
1258 {
1259 spaces[i] = ' ';
1260 }
1261
1262 spaces[nspaces] = '\0';
1263
1264 while (t != NULL)
1265 {
1266 char *st = t;
28bf4b0b 1267 DPRINTF (("Loop: [%s]", t));
616915dd 1268 mstring_split (&st, &t, nextlen, &indent);
28bf4b0b 1269 DPRINTF (("Split: [%s] [%s]", st, t));
616915dd 1270 fprintf (stream, "%s%s\n", spaces, st);
28bf4b0b 1271 DPRINTF (("Next..."));
616915dd 1272 }
1273
1274 sfree (spaces);
1275 }
1276 }
1277 }
1278
28bf4b0b 1279 DPRINTF (("Done"));
616915dd 1280 sfree (os);
1281}
1282
1283void
28bf4b0b 1284xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1285{
1286 prepareMessage ();
1287 printError (stderr, message ("%q: *** Fatal bug: %q",
1288 fileloc_unparse (g_currentloc), s));
28bf4b0b 1289 showSourceLoc (srcFile, srcLine);
616915dd 1290 printCodePoint ();
1291 printBugReport ();
1292 llexit (LLFAILURE);
1293}
1294
1295# ifndef NOLCL
1296void
1297lclfatalbug (char *msg)
1298{
1299 prepareMessage ();
1300 printError (stderr,
1301 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1302 printCodePoint ();
1303 printBugReport ();
1304 llexit (LLFAILURE);
1305}
1306# endif
1307
1308void
1309checkParseError (void)
1310{
1311 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1312 {
1313 llfatalerror (message ("%q: Cannot recover from parse error.",
1314 fileloc_unparse (g_currentloc)));
1315 }
1316}
1317
1318void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1319{
1320 /*@unchecked@*/
1321 static int numbugs = 0;
1322 static bool inbug = FALSE;
1323
1324 if (inbug)
1325 {
1326 cstring temps = fileloc_unparseRaw (file, line);
1327
1328 fprintf (stderr, "%s: Recursive bug detected: %s\n",
1329 cstring_toCharsSafe (temps),
1330 cstring_toCharsSafe (s));
1331 cstring_free (temps);
1332
1333 llexit (LLFAILURE);
1334 }
1335
1336 inbug = TRUE;
1337
1338 prepareMessage ();
1339
28bf4b0b 1340 /*@i3232@*/
1341 /*
616915dd 1342 if (fileloc_isRealLib (g_currentloc))
1343 {
28bf4b0b 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),
1348 s));
616915dd 1349 }
28bf4b0b 1350 */
616915dd 1351
1352 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1353 {
1354 llfatalerror (message ("%q: Cannot recover from parse error.",
1355 fileloc_unparse (g_currentloc)));
1356 }
1357
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),
1362 s, errno));
1363 printCodePoint ();
1364
1365 (void) fflush (stderr);
3120b462 1366 if (errno != 0)
1367 {
1368 perror ("Possible system error diagnostic: ");
1369 }
616915dd 1370 (void) fflush (stderr);
1371
1372 printBugReport ();
1373
1374 numbugs++;
1375
28bf4b0b 1376 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
616915dd 1377 {
28bf4b0b 1378 llfatalerror (message ("%q: Cannot recover from last bug. (If you really want LCLint to try to continue, use -bugslimit <n>.)",
616915dd 1379 fileloc_unparse (g_currentloc)));
1380 }
28bf4b0b 1381
616915dd 1382 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1383 fileloc_free (lastbug);
1384 lastbug = fileloc_copy (g_currentloc);
1385 closeMessage ();
1386
1387 (void) fflush (stderr);
1388 inbug = FALSE;
1389}
1390
1391# ifndef NOLCL
1392void
1393lclbug (/*@only@*/ cstring s)
1394{
1395 prepareMessage ();
1396 printError (stderr, message ("*** Internal Bug: %q", s));
1397 printCodePoint ();
1398 printBugReport ();
1399 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1400 closeMessage ();
1401}
1402# endif
1403
1404void
1405llfatalerror (cstring s)
1406{
1407 prepareMessage ();
1408 printError (stderr, s);
1409 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1410 llexit (LLFAILURE);
1411}
1412
1413void
1414llfatalerrorLoc (/*@only@*/ cstring s)
1415{
1416 prepareMessage ();
1417 (void) fflush (g_msgstream);
1418 printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1419 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
28bf4b0b 1420 (void) fflush (g_msgstream);
616915dd 1421 llexit (LLFAILURE);
1422}
1423
616915dd 1424void
28bf4b0b 1425xllgloberror (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1426{
1427 if (context_inSuppressRegion ())
1428 {
1429 cstring_free (s);
1430 }
1431 else
1432 {
1433 context_setNeednl ();
1434 prepareMessage ();
1435 context_hasError ();
1436 flagcode_recordError (FLG_SPECIAL);
1437 printError (g_msgstream, s);
28bf4b0b 1438 showSourceLoc (srcFile, srcLine);
616915dd 1439 closeMessage ();
1440 }
1441}
1442
1443# ifndef NOLCL
1444bool
1445lclHadError (void)
1446{
1447 return (lclerrors > 0);
1448}
1449
1450bool
1451lclHadNewError (void)
1452{
1453 static int lastcall = 0;
1454
1455 if (lclerrors > lastcall)
1456 {
1457 lastcall = lclerrors;
1458 return TRUE;
1459 }
1460 else
1461 {
1462 return FALSE;
1463 }
1464}
1465
1466int
1467lclNumberErrors (void)
1468{
1469 return (lclerrors);
1470}
1471
1472void
28bf4b0b 1473xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
616915dd 1474{
1475 lclerrors++;
1476
1477 if (ltoken_getCode (t) != NOTTOKEN)
1478 {
1479 cstring loc = ltoken_unparseLoc (t);
1480
1481 lastfileloclen = cstring_length (loc);
1482
1483 printError (g_msgstream, message ("%q: %q", loc, msg));
28bf4b0b 1484 showSourceLoc (srcFile, srcLine);
616915dd 1485 }
1486 else
1487 {
1488 printError (g_msgstream, msg);
28bf4b0b 1489 showSourceLoc (srcFile, srcLine);
616915dd 1490 }
1491}
1492
1493void
1494lclplainerror (/*@only@*/ cstring msg)
1495{
1496 lclerrors++;
1497
1498 printError (g_msgstream, msg);
1499}
1500
1501void
1502lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1503{
1504 lclerror (t, msg);
1505 (void) fflush (g_msgstream);
1506 printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1507 llexit (LLFAILURE);
1508}
1509
1510void
1511lclplainfatalerror (/*@only@*/ cstring msg)
1512{
1513 (void) fflush (g_msgstream);
1514 printError (stderr, message ("*** Cannot continue: %q", msg));
1515 llexit (LLFAILURE);
1516}
1517
1518void
1519lclRedeclarationError (ltoken id)
1520{
1521 cstring s = ltoken_getRawString (id);
1522
1523
1524 if (usymtab_existsEither (s))
1525 {
1526 uentry le = usymtab_lookupEither (s);
1527
1528 lclerror (id, message ("Respecification of %s", s));
1529 llgenindentmsg (message ("Previous specification of %q",
1530 uentry_getName (le)),
1531 uentry_whereSpecified (le));
1532 }
1533 else
1534 {
1535 lclerror (id, message ("Identifier redeclared: %s", s));
1536 }
1537}
1538# endif
1539
1540void genppllerror (flagcode code, /*@only@*/ cstring s)
1541{
1542 if (context_inSuppressZone (g_currentloc))
1543 {
1544 cstring_free (s);
1545 }
1546 else
1547 {
1548 if (context_getFlag (code))
1549 {
1550 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1551 {
1552 fprintf (g_msgstream, " >\n");
1553 }
1554
1555 llerror (code, s);
1556
1557 if (code != FLG_PREPROC)
1558 {
1559 llsuppresshint ('-', code);
1560 }
1561
1562 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1563 {
1564 fprintf (stderr, "< more preprocessing .");
1565 }
1566 }
1567 else
1568 {
1569 cstring_free (s);
1570 }
1571 }
1572}
1573
1574void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1575 /*@only@*/ cstring hint)
1576{
1577 if (context_inSuppressZone (g_currentloc))
1578 {
1579 cstring_free (s);
1580 cstring_free (hint);
1581 }
1582 else
1583 {
1584 if (context_getFlag (code))
1585 {
1586 prepareMessage ();
1587 context_clearPreprocessing ();
1588 llerror (code, s);
1589 llgenhint (hint);
1590 context_setPreprocessing ();
1591 closeMessage ();
1592 }
1593 else
1594 {
1595 cstring_free (s);
1596 cstring_free (hint);
1597 }
1598 }
1599}
1600
1601void ppllerror (/*@only@*/ cstring s)
1602{
1603 genppllerror (FLG_PREPROC, s);
1604}
1605
1606void pplldiagmsg (cstring s)
1607{
1608 if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1609 {
1610 fprintf (stderr, " >\n");
1611 lldiagmsg (s);
1612 fprintf (stderr, "< more preprocessing .");
1613 }
1614 else
1615 {
1616 lldiagmsg (s);
1617 }
1618}
1619
1620void loadllmsg (cstring s)
1621{
1622 if (context_getDebug (FLG_SHOWSCAN))
1623 {
1624 fprintf (stderr, " >\n");
1625 lldiagmsg (s);
1626 fprintf (stderr, "< .");
1627 }
1628 else
1629 {
1630 lldiagmsg (s);
1631 }
1632}
1633
1634static void llreportparseerror (/*@only@*/ cstring s)
1635{
1636 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1637 {
1638 cstring_free (s);
1639 }
1640 else
1641 {
1642 llerror (FLG_SYNTAX, s);
1643
1644 fileloc_free (lastparseerror);
1645 lastparseerror = fileloc_copy (g_currentloc);
1646 }
1647}
1648
28bf4b0b 1649bool xlloptgenerror (char *srcFile, int srcLine,
1650 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1651{
28bf4b0b 1652 DPRINTF (("xllopt: %s", s));
1653
1654 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1655 {
28bf4b0b 1656 DPRINTF (("Here we are!"));
616915dd 1657 llsuppresshint ('-', o);
1658 closeMessage ();
1659 flagcode_recordError (o);
1660 return TRUE;
1661 }
28bf4b0b 1662 else
1663 {
1664 DPRINTF (("Suppressed!"));
1665 flagcode_recordSuppressed (o);
1666 return FALSE;
1667 }
616915dd 1668}
1669
28bf4b0b 1670bool xoptgenerror2 (char *srcFile, int srcLine,
1671 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1672{
1673 if (context_suppressFlagMsg (f1, loc))
1674 {
1675 flagcode_recordSuppressed (f1);
1676 cstring_free (s);
1677 }
1678 else
1679 {
1680 if (context_suppressFlagMsg (f2, loc))
1681 {
1682 flagcode_recordSuppressed (f2);
1683 cstring_free (s);
1684 }
1685 else
1686 {
28bf4b0b 1687 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1688 {
28bf4b0b 1689 llsuppresshint2 ('-', f1, f2);
616915dd 1690 flagcode_recordError (f2);
1691 closeMessage ();
1692 return TRUE;
1693 }
28bf4b0b 1694 else
1695 {
1696 flagcode_recordSuppressed (f2);
1697 }
616915dd 1698 }
1699 }
28bf4b0b 1700
616915dd 1701 return FALSE;
1702}
1703
28bf4b0b 1704bool xoptgenerror2n (char *srcFile, int srcLine,
1705 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1706{
1707
1708 if (context_suppressFlagMsg (f1, loc))
1709 {
1710 flagcode_recordSuppressed (f1);
1711 cstring_free (s);
1712 }
1713 else
1714 {
1715 if (context_suppressNotFlagMsg (f2, loc))
1716 {
1717 flagcode_recordSuppressed (f2);
1718 cstring_free (s);
1719 }
1720 else
1721 {
28bf4b0b 1722 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1723 {
1724 llsuppresshint ('+', f2);
1725 flagcode_recordError (f2);
1726 closeMessage ();
1727 return TRUE;
1728 }
1729
1730 flagcode_recordSuppressed (f2);
1731 }
1732 }
1733 return FALSE;
1734}
1735
28bf4b0b 1736bool xllnoptgenerror (char *srcFile, int srcLine,
1737 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1738{
28bf4b0b 1739 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1740 {
1741 llsuppresshint ('+', o);
1742 flagcode_recordError (o);
1743 closeMessage ();
1744 return TRUE;
1745 }
1746
1747 flagcode_recordSuppressed (o);
1748 return FALSE;
1749}
1750
1751void llparseerror (cstring s)
1752{
1753 if (context_getFlag (FLG_TRYTORECOVER))
1754 {
1755 parseerrorcount++;
1756
1757 if (parseerrorcount > GIVEUPPARSE)
1758 {
1759 if (cstring_isDefined (s))
1760 {
1761 llfatalerror (message ("%q: Parse Error: %q. "
1762 "Too many errors, giving up.",
1763 fileloc_unparse (g_currentloc), s));
1764 }
1765 else
1766 {
1767 llfatalerror (message ("%q: Parse Error. Too many errors, giving up.",
1768 fileloc_unparse (g_currentloc)));
1769 }
1770 }
1771 else
1772 {
1773 if (cstring_isDefined (s))
1774 {
1775 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1776 s));
1777 }
1778 else
1779 {
1780 llreportparseerror (message ("Parse Error. Attempting to continue."));
1781 }
1782 }
1783 }
1784 else
1785 {
1786 cstring msg;
1787
1788 if (cstring_isDefined (s))
1789 {
1790 msg = message ("Parse Error: %q.", s);
1791 }
1792 else
1793 {
1794 msg = message ("Parse Error.");
1795 }
1796
1797 llfatalerror
1798 (message ("%q: %s (For help on parse errors, "
1799 "see lclint -help parseerrors.)",
1800 fileloc_unparse (g_currentloc), msg));
1801 }
1802}
1803
28bf4b0b 1804bool xfsgenerror (char *srcFile, int srcLine,
1805 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
1806{
1807 if (flagSpec_isOn (fs, fl))
1808 {
1809 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
1810 {
1811 llsuppresshint ('-', flagSpec_getFirstOn (fs, fl));
1812 flagcode_recordError (flagSpec_getFirstOn (fs, fl));
1813 return TRUE;
1814 }
1815 else
1816 {
1817 flagcode_recordSuppressed (flagSpec_getFirstOn (fs, fl));
1818 return FALSE;
1819 }
1820 }
1821 else
1822 {
1823 flagcode_recordSuppressed (flagSpec_getDominant (fs));
1824 cstring_free (s);
1825 return FALSE;
1826 }
1827}
1828
616915dd 1829bool doCheck (bool x, cstring pred, cstring file, int line)
1830{
1831 if (!x) {
1832 llbug (message ("%q: Check Failed: %s",
1833 fileloc_unparseRaw (file, line),
1834 pred));
1835 }
1836
1837 return x;
1838}
1839
1840/*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1841{
1842 char *result;
1843
1844#ifndef VMS
1845#ifndef HAVE_STRERROR
1846 result = NULL;
1847#else
1848 result = strerror (errnum);
1849#endif
1850#else /* VMS */
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'. */
1857
1858 result = strerror (errnum, vaxc$errno);
1859#endif
1860
1861 if (result == NULL)
1862 {
1863 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1864 }
1865
1866 return cstring_fromChars (result);
1867}
1868
1869void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1870{
1871# if 0
1872# ifdef HOMEVERSION
1873 llflush ();
1874 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1875 fileloc_unparse (g_currentloc),
1876 fileloc_unparseRaw (file, line),
1877 s, errno));
1878 printCodePoint ();
1879 llflush ();
1880# endif
1881# else
1882 cstring_free (s);
1883# endif
1884}
1885
1886void llflush (void)
1887{
1888 (void) fflush (g_msgstream);
1889 (void) fflush (stderr);
1890}
This page took 0.326674 seconds and 5 git commands to generate.