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