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