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