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