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