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