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