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