]> andersk Git - splint.git/blame - src/llerror.c
Updated README version number. (Testing sourceforge)
[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{
ccf0a4a8 841 if (!context_suppressFlagMsg (FLG_FORMATTYPE, fl))
842 {
843 return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
844 }
845 else
846 {
847 cstring_free (s);
848 return FALSE;
849 }
616915dd 850}
851
852bool
28bf4b0b 853xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
616915dd 854{
28bf4b0b 855 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
616915dd 856 {
857 llnosuppresshint (o);
858 flagcode_recordError (o);
859 closeMessage ();
860 return TRUE;
861 }
862 else
863 {
864 flagcode_recordSuppressed (o);
865 return FALSE;
866 }
867}
868
869bool
28bf4b0b 870xllgenhinterror (char *srcFile, int srcLine,
871 flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
872 fileloc fl)
616915dd 873{
874 if (!context_suppressFlagMsg (o, fl))
875 {
28bf4b0b 876 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
616915dd 877 {
878 flagcode_recordError (o);
879
880 if (context_getFlag (FLG_HINTS))
881 {
882 llgenhint (hint);
883 }
884 else
885 {
886 cstring_free (hint);
887 }
888
889 closeMessage ();
890 return TRUE;
891 }
892
893 cstring_free (hint);
894 }
895 else
896 {
897 cstring_free (hint);
898 cstring_free (s);
899 }
900
901 flagcode_recordSuppressed (o);
902 return FALSE;
903}
904
905static bool
28bf4b0b 906llrealerror (char *srcFile, int srcLine, /*@only@*/ cstring s, fileloc fl)
616915dd 907{
28bf4b0b 908 return (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE));
616915dd 909}
910
911static bool
28bf4b0b 912llgenerroraux (char *srcFile, int srcLine,
913 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
616915dd 914{
616915dd 915 if (context_inSuppressZone (fl))
916 {
917 cstring_free (s);
918 return FALSE;
919 }
ccf0a4a8 920
28bf4b0b 921 if (llgenerrorreal (srcFile, srcLine, s, fl, iserror, indent)) {
922 return TRUE;
923 } else {
924 return FALSE;
925 }
616915dd 926}
927
28bf4b0b 928bool
929xllforceerror (char *srcFile, int srcLine,
930 flagcode code, /*@only@*/ cstring s, fileloc fl)
616915dd 931{
932 flagcode_recordError (code);
28bf4b0b 933
934 if (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)) {
935 closeMessage ();
936 return TRUE;
937 } else {
938 return FALSE;
939 }
616915dd 940}
941
942static bool
28bf4b0b 943llgenerrorreal (char *srcFile, int srcLine,
944 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
616915dd 945{
946 cstring flstring;
947
948 /* duplicate message (rescanning a header file */
949
950 if (!messageLog_add (context_messageLog (), fl, s))
951 {
28bf4b0b 952 DPRINTF (("Duplicate message suppressed! %s / %s",
953 fileloc_unparse (fl), s));
616915dd 954 cstring_free (s);
955 return FALSE;
956 }
957
958 if (iserror) context_hasError ();
959
960 if (context_unlimitedMessages ())
961 {
962 ;
963 }
964 else
965 {
966 /*
967 ** suppress excessive messages:
968 ** check up to ':'
969 **
970 */
971
972 char *sc = cstring_toCharsSafe (s);
973 char *tmpmsg = strchr (sc, ':');
974
975 if (tmpmsg == NULL)
976 {
977 tmpmsg = sc;
978 }
979 else
980 {
981 char *savechar = tmpmsg;
982 *tmpmsg = '\0';
983 tmpmsg = sc;
984 *savechar = ':';
985 }
986
987 if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
988 {
989 mcount++;
990 if (mcount == (context_getLimit () + 1))
991 {
992 limitmessage (s, fl);
993 return FALSE;
994 }
995
996 if (mcount > (context_getLimit ()))
997 {
998 cstring_free (s);
999 return FALSE;
1000 }
1001 }
1002 else
1003 {
1004 cleanupMessages ();
1005 mcount = 0;
1006 cstring_free (lastmsg);
1007 lastmsg = cstring_fromCharsNew (tmpmsg);
1008 }
1009 }
1010
28bf4b0b 1011 DPRINTF (("Here..."));
1012
616915dd 1013 if (context_hasAliasAnnote ())
1014 {
1015 char *sc = cstring_toCharsSafe (s);
1016 char *fcolon = strchr (sc, ':');
1017 cstring a = context_getAliasAnnote ();
1018
1019
1020 if (fcolon == NULL)
1021 {
1022 s = message ("%q (%q)", s, a);
1023 }
1024 else
1025 {
1026 cstring afterColon;
1027
1028 *fcolon = '\0';
1029 afterColon = cstring_fromCharsNew (fcolon + 1);
1030
1031 s = message ("%q (%q):%q", s, a, afterColon);
1032 }
1033 }
1034
1035 if (context_hasMessageAnnote ())
1036 {
1037 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1038
1039
1040 if (fcolon == NULL)
1041 {
1042 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1043 s = message ("%q (%q)", s, context_getMessageAnnote ());
1044 /*@=dependenttrans@*/
1045 }
1046 else
1047 {
1048 cstring afterColon;
1049
1050 *fcolon = '\0';
1051 afterColon = cstring_fromCharsNew (fcolon + 1);
1052
1053 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1054 s = message ("%q (%q):%q", s,
1055 context_getMessageAnnote (), afterColon);
1056 /*@=dependenttrans@*/
1057 }
1058 }
1059
1060 context_setNeednl ();
1061 prepareMessage ();
1062
1063 if (context_showFunction ())
1064 {
1065 cstring fname = fileloc_unparseFilename (g_currentloc);
1066
1067 if (context_inIterDef ())
1068 {
1069 fprintf (g_msgstream, "%s: (in iter %s)\n",
1070 cstring_toCharsSafe (fname),
1071 cstring_toCharsSafe (context_inFunctionName ()));
1072 }
1073 else if (context_inIterEnd ())
1074 {
1075 fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
1076 cstring_toCharsSafe (fname),
1077 cstring_toCharsSafe (context_inFunctionName ()));
1078 }
1079 else if (context_inMacro ())
1080 {
1081 fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
1082 cstring_toCharsSafe (context_inFunctionName ()));
1083 }
1084 else
1085 {
1086 fprintf (g_msgstream, "%s: (in function %s)\n",
1087 cstring_toCharsSafe (fname),
1088 cstring_toCharsSafe (context_inFunctionName ()));
1089 }
1090
1091 cstring_free (fname);
1092 context_setShownFunction ();
1093 }
1094
1095 flstring = fileloc_unparse (fl);
616915dd 1096 lastfileloclen = cstring_length (flstring);
1097
1098 if (indent)
1099 {
1100 printError (g_msgstream, message (" %q: %q", flstring, s));
1101 }
1102 else
1103 {
1104 printError (g_msgstream, message ("%q: %q", flstring, s));
1105 }
1106
28bf4b0b 1107 showSourceLoc (srcFile, srcLine);
616915dd 1108 return TRUE;
1109}
1110
1111/*
1112** printMessage
1113**
1114** message contains no '\n'
1115** message fits in one line: print it
1116** message fits in two lines with 3-space indent after fileloc: print it
1117** split line with 5-space indent from left margin: print it
1118**
1119*/
1120
1121static
1122void printMessage (FILE *stream, /*@only@*/ cstring s)
1123{
1124 printIndentMessage (stream, s, 0);
1125}
1126
1127static
1128void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1129{
28bf4b0b 1130 static bool inbody = FALSE;
616915dd 1131 int maxlen = context_getLineLen ();
1132 char *s = cstring_toCharsSafe (sc);
28bf4b0b 1133 char *olds = NULL;
616915dd 1134
28bf4b0b 1135 llassertprotect (!inbody);
1136 inbody = TRUE;
616915dd 1137
1138 do
1139 {
1140 char *t = NULL;
1141 char *st = s;
1142
28bf4b0b 1143 llassertprotect (st != olds);
1144 olds = st;
616915dd 1145 mstring_split (&st, &t, maxlen, &indent);
1146 fprintf (stream, "%s\n", st);
28bf4b0b 1147 llassertprotect (t != s);
616915dd 1148 s = t;
1149 } while (s != NULL) ;
1150
1151 cstring_free (sc);
28bf4b0b 1152 inbody = FALSE;
616915dd 1153}
1154
1155static
1156void printError (FILE *stream, /*@only@*/ cstring sc)
1157{
1158 int maxlen = context_getLineLen ();
1159 int nspaces = lastfileloclen + 5;
1160 int nextlen = maxlen - nspaces;
1161 int len = cstring_length (sc);
1162 int indent = 0;
1163 char *s = cstring_toCharsSafe (sc);
1164 char *os = s;
1165 char *t = NULL;
1166
28bf4b0b 1167 DPRINTF (("Print error: [%s]", sc));
1168
616915dd 1169 if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
1170 {
1171 mstring_split (&s, &t, maxlen, &indent);
1172
1173 fprintf (stream, "%s\n", s);
1174
1175 if (t != NULL)
1176 {
1177 len = mstring_length (t);
1178
1179 if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1180 && len > (nextlen - 1))
1181 {
1182 fprintf (stream, " %s\n", t);
1183 }
1184 else
1185 {
1186 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1187 int i;
1188
1189 for (i = 0; i < nspaces; i++)
1190 {
1191 spaces[i] = ' ';
1192 }
1193
1194 spaces[nspaces] = '\0';
1195
1196 while (t != NULL)
1197 {
1198 char *st = t;
1199 mstring_split (&st, &t, nextlen, &indent);
1200 fprintf (stream, "%s%s\n", spaces, st);
1201 }
1202
1203 sfree (spaces);
1204 }
1205 }
1206 }
1207 else
1208 {
28bf4b0b 1209 DPRINTF (("Here 1: [%s]", sc));
1210
616915dd 1211 if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1212 {
1213 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1214
1215 if (nspaces < 1) nspaces = 1;
1216
1217 nextlen = maxlen - nspaces;
1218
1219 mstring_split (&s, &t, maxlen, &indent);
1220
1221 fprintf (stream, "%s\n", s);
1222
1223 if (t != NULL)
1224 {
1225 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1226 int i;
1227
1228 for (i = 0; i < nspaces; i++)
1229 {
1230 spaces[i] = ' ';
1231 }
1232
1233 spaces[nspaces] = '\0';
1234
1235 while (t != NULL)
1236 {
1237 char *st = t;
1238
1239 mstring_split (&st, &t, nextlen, &indent);
1240 fprintf (stream, "%s%s\n", spaces, st);
1241 }
1242
1243 sfree (spaces);
1244 }
1245 }
1246 else
1247 {
1248 nspaces = 4;
1249 nextlen = maxlen - nspaces;
1250
28bf4b0b 1251 DPRINTF (("Here 2: [%s]", s));
616915dd 1252 mstring_split (&s, &t, maxlen, &indent);
28bf4b0b 1253 DPRINTF (("Here 3: [%s] [%s]", s, t));
616915dd 1254
1255 fprintf (stream, "%s\n", s);
1256
1257 if (t != NULL)
1258 {
1259 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1260 int i;
1261
1262 for (i = 0; i < nspaces; i++)
1263 {
1264 spaces[i] = ' ';
1265 }
1266
1267 spaces[nspaces] = '\0';
1268
1269 while (t != NULL)
1270 {
1271 char *st = t;
28bf4b0b 1272 DPRINTF (("Loop: [%s]", t));
616915dd 1273 mstring_split (&st, &t, nextlen, &indent);
28bf4b0b 1274 DPRINTF (("Split: [%s] [%s]", st, t));
616915dd 1275 fprintf (stream, "%s%s\n", spaces, st);
28bf4b0b 1276 DPRINTF (("Next..."));
616915dd 1277 }
1278
1279 sfree (spaces);
1280 }
1281 }
1282 }
1283
28bf4b0b 1284 DPRINTF (("Done"));
616915dd 1285 sfree (os);
1286}
1287
1288void
28bf4b0b 1289xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1290{
1291 prepareMessage ();
1292 printError (stderr, message ("%q: *** Fatal bug: %q",
1293 fileloc_unparse (g_currentloc), s));
28bf4b0b 1294 showSourceLoc (srcFile, srcLine);
616915dd 1295 printCodePoint ();
1296 printBugReport ();
1297 llexit (LLFAILURE);
1298}
1299
1300# ifndef NOLCL
1301void
1302lclfatalbug (char *msg)
1303{
1304 prepareMessage ();
1305 printError (stderr,
1306 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1307 printCodePoint ();
1308 printBugReport ();
1309 llexit (LLFAILURE);
1310}
1311# endif
1312
1313void
1314checkParseError (void)
1315{
1316 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1317 {
1318 llfatalerror (message ("%q: Cannot recover from parse error.",
1319 fileloc_unparse (g_currentloc)));
1320 }
1321}
1322
1323void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1324{
1325 /*@unchecked@*/
1326 static int numbugs = 0;
1327 static bool inbug = FALSE;
1328
1329 if (inbug)
1330 {
1331 cstring temps = fileloc_unparseRaw (file, line);
1332
1333 fprintf (stderr, "%s: Recursive bug detected: %s\n",
1334 cstring_toCharsSafe (temps),
1335 cstring_toCharsSafe (s));
1336 cstring_free (temps);
1337
1338 llexit (LLFAILURE);
1339 }
1340
1341 inbug = TRUE;
1342
1343 prepareMessage ();
1344
28bf4b0b 1345 /*@i3232@*/
1346 /*
616915dd 1347 if (fileloc_isRealLib (g_currentloc))
1348 {
28bf4b0b 1349 DPRINTF (("Here we are!"));
1350 llfatalerror (message ("%q: Library file appears to be corrupted. Error: %q: %s",
1351 fileloc_unparse (g_currentloc),
1352 fileloc_unparseRaw (file, line),
1353 s));
616915dd 1354 }
28bf4b0b 1355 */
616915dd 1356
1357 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1358 {
1359 llfatalerror (message ("%q: Cannot recover from parse error.",
1360 fileloc_unparse (g_currentloc)));
1361 }
1362
1363 (void) fflush (g_msgstream);
1364 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1365 fileloc_unparse (g_currentloc),
1366 fileloc_unparseRaw (file, line),
1367 s, errno));
1368 printCodePoint ();
1369
1370 (void) fflush (stderr);
3120b462 1371 if (errno != 0)
1372 {
1373 perror ("Possible system error diagnostic: ");
1374 }
616915dd 1375 (void) fflush (stderr);
1376
1377 printBugReport ();
1378
1379 numbugs++;
1380
28bf4b0b 1381 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
616915dd 1382 {
28bf4b0b 1383 llfatalerror (message ("%q: Cannot recover from last bug. (If you really want LCLint to try to continue, use -bugslimit <n>.)",
616915dd 1384 fileloc_unparse (g_currentloc)));
1385 }
28bf4b0b 1386
616915dd 1387 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1388 fileloc_free (lastbug);
1389 lastbug = fileloc_copy (g_currentloc);
1390 closeMessage ();
1391
1392 (void) fflush (stderr);
1393 inbug = FALSE;
1394}
1395
1396# ifndef NOLCL
1397void
1398lclbug (/*@only@*/ cstring s)
1399{
1400 prepareMessage ();
1401 printError (stderr, message ("*** Internal Bug: %q", s));
1402 printCodePoint ();
1403 printBugReport ();
1404 fprintf (stderr, " (attempting to continue, results may be incorrect)\n");
1405 closeMessage ();
1406}
1407# endif
1408
1409void
1410llfatalerror (cstring s)
1411{
1412 prepareMessage ();
1413 printError (stderr, s);
1414 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1415 llexit (LLFAILURE);
1416}
1417
1418void
1419llfatalerrorLoc (/*@only@*/ cstring s)
1420{
1421 prepareMessage ();
1422 (void) fflush (g_msgstream);
1423 printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1424 printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
28bf4b0b 1425 (void) fflush (g_msgstream);
616915dd 1426 llexit (LLFAILURE);
1427}
1428
616915dd 1429# ifndef NOLCL
1430bool
1431lclHadError (void)
1432{
1433 return (lclerrors > 0);
1434}
1435
1436bool
1437lclHadNewError (void)
1438{
1439 static int lastcall = 0;
1440
1441 if (lclerrors > lastcall)
1442 {
1443 lastcall = lclerrors;
1444 return TRUE;
1445 }
1446 else
1447 {
1448 return FALSE;
1449 }
1450}
1451
1452int
1453lclNumberErrors (void)
1454{
1455 return (lclerrors);
1456}
1457
1458void
28bf4b0b 1459xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
616915dd 1460{
1461 lclerrors++;
1462
1463 if (ltoken_getCode (t) != NOTTOKEN)
1464 {
1465 cstring loc = ltoken_unparseLoc (t);
1466
1467 lastfileloclen = cstring_length (loc);
1468
1469 printError (g_msgstream, message ("%q: %q", loc, msg));
28bf4b0b 1470 showSourceLoc (srcFile, srcLine);
616915dd 1471 }
1472 else
1473 {
1474 printError (g_msgstream, msg);
28bf4b0b 1475 showSourceLoc (srcFile, srcLine);
616915dd 1476 }
1477}
1478
1479void
1480lclplainerror (/*@only@*/ cstring msg)
1481{
1482 lclerrors++;
1483
1484 printError (g_msgstream, msg);
1485}
1486
1487void
1488lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1489{
1490 lclerror (t, msg);
1491 (void) fflush (g_msgstream);
1492 printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1493 llexit (LLFAILURE);
1494}
1495
1496void
1497lclplainfatalerror (/*@only@*/ cstring msg)
1498{
1499 (void) fflush (g_msgstream);
1500 printError (stderr, message ("*** Cannot continue: %q", msg));
1501 llexit (LLFAILURE);
1502}
1503
1504void
1505lclRedeclarationError (ltoken id)
1506{
1507 cstring s = ltoken_getRawString (id);
1508
1509
1510 if (usymtab_existsEither (s))
1511 {
1512 uentry le = usymtab_lookupEither (s);
1513
1514 lclerror (id, message ("Respecification of %s", s));
1515 llgenindentmsg (message ("Previous specification of %q",
1516 uentry_getName (le)),
1517 uentry_whereSpecified (le));
1518 }
1519 else
1520 {
1521 lclerror (id, message ("Identifier redeclared: %s", s));
1522 }
1523}
1524# endif
1525
1526void genppllerror (flagcode code, /*@only@*/ cstring s)
1527{
1528 if (context_inSuppressZone (g_currentloc))
1529 {
1530 cstring_free (s);
1531 }
1532 else
1533 {
1534 if (context_getFlag (code))
1535 {
1536 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1537 {
1538 fprintf (g_msgstream, " >\n");
1539 }
1540
1541 llerror (code, s);
1542
1543 if (code != FLG_PREPROC)
1544 {
1545 llsuppresshint ('-', code);
1546 }
1547
1548 if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1549 {
1550 fprintf (stderr, "< more preprocessing .");
1551 }
1552 }
1553 else
1554 {
1555 cstring_free (s);
1556 }
1557 }
1558}
1559
1560void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1561 /*@only@*/ cstring hint)
1562{
1563 if (context_inSuppressZone (g_currentloc))
1564 {
1565 cstring_free (s);
1566 cstring_free (hint);
1567 }
1568 else
1569 {
1570 if (context_getFlag (code))
1571 {
1572 prepareMessage ();
1573 context_clearPreprocessing ();
1574 llerror (code, s);
1575 llgenhint (hint);
1576 context_setPreprocessing ();
1577 closeMessage ();
1578 }
1579 else
1580 {
1581 cstring_free (s);
1582 cstring_free (hint);
1583 }
1584 }
1585}
1586
1587void ppllerror (/*@only@*/ cstring s)
1588{
1589 genppllerror (FLG_PREPROC, s);
1590}
1591
1592void pplldiagmsg (cstring s)
1593{
1594 if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1595 {
1596 fprintf (stderr, " >\n");
1597 lldiagmsg (s);
1598 fprintf (stderr, "< more preprocessing .");
1599 }
1600 else
1601 {
1602 lldiagmsg (s);
1603 }
1604}
1605
1606void loadllmsg (cstring s)
1607{
1608 if (context_getDebug (FLG_SHOWSCAN))
1609 {
1610 fprintf (stderr, " >\n");
1611 lldiagmsg (s);
1612 fprintf (stderr, "< .");
1613 }
1614 else
1615 {
1616 lldiagmsg (s);
1617 }
1618}
1619
1620static void llreportparseerror (/*@only@*/ cstring s)
1621{
1622 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1623 {
1624 cstring_free (s);
1625 }
1626 else
1627 {
1628 llerror (FLG_SYNTAX, s);
1629
1630 fileloc_free (lastparseerror);
1631 lastparseerror = fileloc_copy (g_currentloc);
1632 }
1633}
1634
b072092f 1635bool xcppoptgenerror (char *srcFile, int srcLine,
1636 flagcode o,
1637 /*@only@*/ cstring s,
1638 cppReader *pfile)
1639{
1640 bool res = FALSE;
1641 fileloc loc = cppReader_getLoc (pfile);
1642
1643 if (context_flagOn (o, loc))
1644 {
1645 if (xlloptgenerror (srcFile, srcLine, o, s, loc))
1646 {
1647 cppReader_printContainingFiles (pfile);
1648 res = TRUE;
1649 }
1650 }
1651 else
1652 {
1653 cstring_free (s);
1654 }
1655
1656 fileloc_free (loc);
1657
1658 return res;
1659}
1660
28bf4b0b 1661bool xlloptgenerror (char *srcFile, int srcLine,
1662 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1663{
28bf4b0b 1664 DPRINTF (("xllopt: %s", s));
1665
1666 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1667 {
28bf4b0b 1668 DPRINTF (("Here we are!"));
616915dd 1669 llsuppresshint ('-', o);
1670 closeMessage ();
1671 flagcode_recordError (o);
1672 return TRUE;
1673 }
28bf4b0b 1674 else
1675 {
1676 DPRINTF (("Suppressed!"));
1677 flagcode_recordSuppressed (o);
1678 return FALSE;
1679 }
616915dd 1680}
1681
28bf4b0b 1682bool xoptgenerror2 (char *srcFile, int srcLine,
1683 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1684{
1685 if (context_suppressFlagMsg (f1, loc))
1686 {
1687 flagcode_recordSuppressed (f1);
1688 cstring_free (s);
1689 }
1690 else
1691 {
1692 if (context_suppressFlagMsg (f2, loc))
1693 {
1694 flagcode_recordSuppressed (f2);
1695 cstring_free (s);
1696 }
1697 else
1698 {
28bf4b0b 1699 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1700 {
28bf4b0b 1701 llsuppresshint2 ('-', f1, f2);
616915dd 1702 flagcode_recordError (f2);
1703 closeMessage ();
1704 return TRUE;
1705 }
28bf4b0b 1706 else
1707 {
1708 flagcode_recordSuppressed (f2);
1709 }
616915dd 1710 }
1711 }
28bf4b0b 1712
616915dd 1713 return FALSE;
1714}
1715
28bf4b0b 1716bool xoptgenerror2n (char *srcFile, int srcLine,
1717 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1718{
1719
1720 if (context_suppressFlagMsg (f1, loc))
1721 {
1722 flagcode_recordSuppressed (f1);
1723 cstring_free (s);
1724 }
1725 else
1726 {
1727 if (context_suppressNotFlagMsg (f2, loc))
1728 {
1729 flagcode_recordSuppressed (f2);
1730 cstring_free (s);
1731 }
1732 else
1733 {
28bf4b0b 1734 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1735 {
1736 llsuppresshint ('+', f2);
1737 flagcode_recordError (f2);
1738 closeMessage ();
1739 return TRUE;
1740 }
1741
1742 flagcode_recordSuppressed (f2);
1743 }
1744 }
1745 return FALSE;
1746}
1747
28bf4b0b 1748bool xllnoptgenerror (char *srcFile, int srcLine,
1749 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1750{
28bf4b0b 1751 if (llrealerror (srcFile, srcLine, s, loc))
616915dd 1752 {
1753 llsuppresshint ('+', o);
1754 flagcode_recordError (o);
1755 closeMessage ();
1756 return TRUE;
1757 }
1758
1759 flagcode_recordSuppressed (o);
1760 return FALSE;
1761}
1762
1763void llparseerror (cstring s)
1764{
1765 if (context_getFlag (FLG_TRYTORECOVER))
1766 {
1767 parseerrorcount++;
1768
1769 if (parseerrorcount > GIVEUPPARSE)
1770 {
1771 if (cstring_isDefined (s))
1772 {
1773 llfatalerror (message ("%q: Parse Error: %q. "
1774 "Too many errors, giving up.",
1775 fileloc_unparse (g_currentloc), s));
1776 }
1777 else
1778 {
1779 llfatalerror (message ("%q: Parse Error. Too many errors, giving up.",
1780 fileloc_unparse (g_currentloc)));
1781 }
1782 }
1783 else
1784 {
1785 if (cstring_isDefined (s))
1786 {
1787 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1788 s));
1789 }
1790 else
1791 {
1792 llreportparseerror (message ("Parse Error. Attempting to continue."));
1793 }
1794 }
1795 }
1796 else
1797 {
1798 cstring msg;
1799
1800 if (cstring_isDefined (s))
1801 {
1802 msg = message ("Parse Error: %q.", s);
1803 }
1804 else
1805 {
1806 msg = message ("Parse Error.");
1807 }
1808
1809 llfatalerror
1810 (message ("%q: %s (For help on parse errors, "
1811 "see lclint -help parseerrors.)",
1812 fileloc_unparse (g_currentloc), msg));
1813 }
1814}
1815
28bf4b0b 1816bool xfsgenerror (char *srcFile, int srcLine,
1817 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
1818{
1819 if (flagSpec_isOn (fs, fl))
1820 {
1821 if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
1822 {
1823 llsuppresshint ('-', flagSpec_getFirstOn (fs, fl));
1824 flagcode_recordError (flagSpec_getFirstOn (fs, fl));
1825 return TRUE;
1826 }
1827 else
1828 {
1829 flagcode_recordSuppressed (flagSpec_getFirstOn (fs, fl));
1830 return FALSE;
1831 }
1832 }
1833 else
1834 {
1835 flagcode_recordSuppressed (flagSpec_getDominant (fs));
1836 cstring_free (s);
1837 return FALSE;
1838 }
1839}
1840
616915dd 1841bool doCheck (bool x, cstring pred, cstring file, int line)
1842{
1843 if (!x) {
1844 llbug (message ("%q: Check Failed: %s",
1845 fileloc_unparseRaw (file, line),
1846 pred));
1847 }
1848
1849 return x;
1850}
1851
1852/*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1853{
1854 char *result;
1855
1856#ifndef VMS
1857#ifndef HAVE_STRERROR
1858 result = NULL;
1859#else
1860 result = strerror (errnum);
1861#endif
1862#else /* VMS */
1863 /* VAXCRTL's strerror() takes an optional second argument, which only
1864 matters when the first argument is EVMSERR. However, it's simplest
1865 just to pass it unconditionally. `vaxc$errno' is declared in
1866 <errno.h>, and maintained by the library in parallel with `errno'.
1867 We assume that caller's `errnum' either matches the last setting of
1868 `errno' by the library or else does not have the value `EVMSERR'. */
1869
1870 result = strerror (errnum, vaxc$errno);
1871#endif
1872
1873 if (result == NULL)
1874 {
1875 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1876 }
1877
1878 return cstring_fromChars (result);
1879}
1880
1881void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1882{
1883# if 0
1884# ifdef HOMEVERSION
1885 llflush ();
1886 printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1887 fileloc_unparse (g_currentloc),
1888 fileloc_unparseRaw (file, line),
1889 s, errno));
1890 printCodePoint ();
1891 llflush ();
1892# endif
1893# else
1894 cstring_free (s);
1895# endif
1896}
1897
1898void llflush (void)
1899{
1900 (void) fflush (g_msgstream);
1901 (void) fflush (stderr);
1902}
This page took 0.317388 seconds and 5 git commands to generate.