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