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