]> andersk Git - splint.git/blob - src/llerror.c
Fixed branch state bug with definitely null values (reported by Jon Wilson).
[splint.git] / src / llerror.c
1 /*
2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 University of Virginia,
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://www.splint.org
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 "cpperror.h"
36 # include "version.h"
37
38 /* Don't allow possibly-recursive assertion failures. */
39 # undef llassert
40 # define llassert llassertprotect
41
42 static void printIndentMessage (FILE *p_stream, /*@only@*/ cstring p_sc, int p_indent)
43    /*@modifies *p_stream@*/ ;
44
45 # ifndef NOLCL
46 static int lclerrors = 0;
47 # endif
48
49 static int lastfileloclen = 10;
50 static /*@only@*/ cstring lastmsg = cstring_undefined;
51 static int mcount = 0;
52 static /*@only@*/ cstring saveOneMessage = cstring_undefined;
53 static /*@only@*/ fileloc lastparseerror = fileloc_undefined;
54 static /*@only@*/ fileloc lastbug = fileloc_undefined;
55 static bool llgenerrorreal (char *p_srcFile, int p_srcLine, 
56                             /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
57                  /*@modifies g_msgstream@*/ ;
58 static bool llgenerroraux (char *p_srcFile, int p_srcLine, 
59                            /*@only@*/ cstring p_s, fileloc p_fl, bool p_iserror, bool p_indent)
60                  /*@modifies g_msgstream@*/ ;
61
62 static void printError (FILE *p_stream, /*@only@*/ cstring p_sc)
63    /*@globals lastfileloclen @*/
64    /*@modifies *p_stream@*/ ;
65 static void printMessage (FILE *p_stream, /*@only@*/ cstring p_s)
66    /*@modifies *p_stream@*/ ;
67
68 static void llgenhint (/*@only@*/ cstring p_s) /*@modifies g_msgstream@*/ ;
69
70 static 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
80 static /*@null@*/ char *
81 maxcp (/*@null@*/ /*@returned@*/ char *a, /*@null@*/ /*@returned@*/ char *b)
82 {
83   if (a > b) return a;
84   else return b;
85 }
86
87 static void
88 printBugReport (void)
89 {
90   fprintf (stderr, "     *** Please report bug to %s ***\n",
91            LCLINT_MAINTAINER);
92   llflush ();
93   /* don't exit (EXIT_FAILURE); */
94 }
95
96 static bool s_needsPrepare = TRUE;
97
98 void prepareMessage (void)
99 {
100   DPRINTF (("Prepare message: %s", bool_unparse (context_loadingLibrary ())));
101
102   if ((context_isPreprocessing () || context_loadingLibrary ())
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
114 void closeMessage (void)
115 {
116   if (context_isPreprocessing ()
117       && context_getDebug (FLG_SHOWSCAN))
118     {
119       llflush ();
120       fprintf (stderr, "< more preprocessing .");
121
122       llassertprotect (!s_needsPrepare);
123       s_needsPrepare = TRUE;
124     }
125   else
126     {
127       llflush ();
128     }
129 }
130
131 void
132 llmsg (/*@only@*/ cstring s)
133 {
134   context_setNeednl ();
135   prepareMessage ();
136   printMessage (g_msgstream, s);
137   closeMessage ();
138 }
139
140 void
141 lldiagmsg (/*@only@*/ cstring s)
142 {
143   context_setNeednl ();
144   prepareMessage ();
145   printMessage (stderr, s);
146   closeMessage ();
147 }
148
149 void
150 llmsgplain (/*@only@*/ cstring s)
151 {
152   context_setNeednl ();
153   prepareMessage ();
154   printMessage (g_msgstream, s);
155   closeMessage ();
156 }
157
158 void llerror_flagWarning (cstring s)
159 {
160   if (context_getFlag (FLG_WARNFLAGS))
161     {
162       showHerald ();
163
164       if (fileloc_isBuiltin (g_currentloc))
165         {
166           llmsg (message ("Warning: %q", s));
167         }
168       else
169         {
170           llgenmsg (message ("Warning: %q", s), g_currentloc);
171         }
172     }
173   else
174     {
175       cstring_free (s);
176     }
177 }
178
179 static void
180 llgenhint (/*@only@*/ cstring s) /*@modifies g_msgstream@*/
181 {
182   int indent = context_getIndentSpaces () - 1;
183
184   if (indent < 0) indent = 0;
185
186   context_setNeednl ();
187   printIndentMessage (g_msgstream, s, indent);
188 }
189
190 void
191 llhint (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
204 static void
205 llshowhint (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
221 static void
222 llsuppresshint2 (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
250           if (f1 == f2)
251             {
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                 }
263             }
264           else
265             {
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                 }
280             }
281         }
282     }
283 }
284
285 static void
286 llsuppresshint (char c, flagcode f)
287 {
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,
304                                   flagcode_unparse (f)));
305             }
306           else
307             {
308               llgenhint (message ("(%h%s will suppress message)", c,
309                                   flagcode_unparse (f)));
310             }
311         }
312     }
313 }
314
315 static void
316 llnosuppresshint (flagcode f)
317 {
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
337 typedef /*@null@*/ /*@dependent@*/ char *nd_charp;
338
339 static void
340 mstring_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;
347   char *osp = *sp;
348
349   *tp = NULL;
350
351   DPRINTF (("Split: %s / %d", *sp, maxline));
352
353   if (maxline < MINLINELEN)
354     {
355       maxline = MINLINELEN;
356     }
357
358   if (*indentchars > 0)
359     {
360       s = *sp = mstring_concatFree1 (mstring_spaces (*indentchars), s);
361       osp = s;
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         {
389           llassertprotect (*tp == NULL || (*tp > osp));
390           return;
391         }
392
393       if (*t >= '\1' && *t <= '\7')
394         {
395           *indentchars += (int) (*t - '\1') + 1;
396           t++;
397         }
398       
399       *tp = t;
400       return;
401     }
402   else if (size_toInt (strlen (s)) < maxline)
403     {
404       llassertprotect (*tp == NULL || (*tp > osp));
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)
426           && *(splitat) != '\0'
427           && *(splitat + 1) == ' ' 
428           && (*(splitat + 2) != '}' && (*(splitat + 2) != '\0'))) 
429         {
430           *(splitat + 1) = '\0';
431           t = splitat + 2;
432           *tp = t;
433           llassertprotect (*tp == NULL || (*tp > osp));
434           return;
435         }
436
437       while (*t != ' ' && *t != '\t' && i < MAXSEARCH)
438         {
439           t--;
440           i++;
441         }
442
443       if (*t != ' ' && *t != '\t')
444         {
445           llassertprotect (maxline > 0);
446           t = mstring_copy (s + maxline);
447           *(s + maxline) = '\0';
448
449           if (*t == '\0')
450             {
451               sfree (t);
452               llassertprotect (*tp == NULL || (*tp > osp));
453               return;
454             }
455
456           mstring_markFree (t);
457           *tp = t;
458           /* Won't be true since t is a copy: llassertprotect (*tp == NULL || (*tp > osp)); */
459           return;
460         }
461       else
462         {
463
464           *t = '\0';
465           t++;
466           
467           if (*t == '\0') return;
468
469           /*
470           ** returns unqualified as only
471           */
472
473           *tp = t;
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
485           return;
486         }
487     }
488
489   BADBRANCH;
490 }
491
492 static
493 void 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
509 static int parseerrorcount = 0;
510
511 void 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
550 void
551 llgenmsg (/*@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
561 void
562 llgenindentmsg (/*@only@*/ cstring s, fileloc fl)
563 {
564   cstring flstring = fileloc_unparse (fl);
565
566   prepareMessage ();
567   (void) printIndentMessage (g_msgstream, message ("%q: %q", flstring, s), context_getIndentSpaces ());
568   closeMessage ();
569 }
570
571 void
572 llgenindentmsgnoloc (/*@only@*/ cstring s)
573 {
574   prepareMessage ();
575   (void) printIndentMessage (g_msgstream, s, context_getIndentSpaces ());
576   closeMessage ();
577 }
578
579 static bool
580 llgentypeerroraux (char *srcFile, int srcLine,
581                    flagcode ocode, ctype t1, exprNode e1, ctype t2, exprNode e2,
582                    /*@only@*/ cstring s, fileloc fl)
583 {
584   cstring hint = cstring_undefined;
585   flagcode code = ocode;
586   flagcode hcode = INVALID_FLAG;
587   ctype ut1 = t1;
588   ctype ut2 = t2;
589
590   DPRINTF (("Type error [%s]: %s / %s : %s / %s",
591             flagcode_unparse (ocode),
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     }
717   else
718     {
719       ;
720     }
721
722   if (hcode == INVALID_FLAG)
723     {
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))));
729
730       if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
731         {
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             }
742         }
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                                        
761
762       if (hcode == INVALID_FLAG)
763         {
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             }
789         }
790     }
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     {
807       if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
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
828 bool
829 xllgentypeerror (char *srcFile, int srcLine,
830                  ctype t1, exprNode e1, ctype t2, exprNode e2,
831                  /*@only@*/ cstring s, fileloc fl)
832 {
833   return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
834 }
835
836 bool
837 xllgenformattypeerror (char *srcFile, int srcLine,
838                        ctype t1, exprNode e1, ctype t2, exprNode e2,
839                        /*@only@*/ cstring s, fileloc fl)
840 {
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     }
850 }
851
852 bool
853 xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
854 {
855   if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
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
869 bool
870 xllgenhinterror (char *srcFile, int srcLine,
871                  flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
872                  fileloc fl)
873 {
874   if (!context_suppressFlagMsg (o, fl))
875     {
876       if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
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
905 static bool
906 llrealerror (char *srcFile, int srcLine, /*@only@*/ cstring s, fileloc fl)
907 {
908   return (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE));
909 }
910
911 static bool
912 llgenerroraux (char *srcFile, int srcLine,
913                /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
914 {
915   if (context_inSuppressZone (fl))
916     {
917       cstring_free (s);
918       return FALSE;
919     }
920   
921   if (llgenerrorreal (srcFile, srcLine, s, fl, iserror, indent)) {
922     return TRUE;
923   } else {
924     return FALSE;
925   }
926 }
927
928 bool
929 xllforceerror (char *srcFile, int srcLine, 
930                flagcode code, /*@only@*/ cstring s, fileloc fl)
931 {
932   flagcode_recordError (code);
933
934   if (llgenerrorreal (srcFile, srcLine, s, fl, TRUE, FALSE)) {
935     closeMessage ();
936     return TRUE;
937   } else {
938     return FALSE;
939   }
940 }
941
942 static bool
943 llgenerrorreal (char *srcFile, int srcLine, 
944                 /*@only@*/ cstring s, fileloc fl, bool iserror, bool indent)
945 {
946   cstring flstring;
947
948   /* duplicate message (rescanning a header file */
949
950   if (!messageLog_add (context_messageLog (), fl, s))
951     {
952       DPRINTF (("Duplicate message suppressed! %s / %s",
953                 fileloc_unparse (fl), s));
954       cstring_free (s);
955       return FALSE;
956     }
957
958   /*
959   ** If herald has not been displayed, display it before the first message.
960   */
961
962   showHerald ();
963
964   if (iserror) context_hasError ();
965
966   if (context_unlimitedMessages ())
967     {
968       ;
969     }
970   else
971     {
972       /*
973       ** suppress excessive messages:
974       **    check up to ':'
975       **
976       */
977
978       char *sc = cstring_toCharsSafe (s);
979       char *tmpmsg = strchr (sc, ':');
980
981       if (tmpmsg == NULL)
982         {
983           tmpmsg = sc;
984         }
985       else
986         {
987           char *savechar = tmpmsg;
988           *tmpmsg = '\0';
989           tmpmsg = sc;
990           *savechar = ':';
991         }
992
993       if (cstring_equal (lastmsg, cstring_fromChars (tmpmsg)))
994         {
995           mcount++;
996           if (mcount == (context_getLimit () + 1))
997             {
998               limitmessage (s, fl);
999               return FALSE;
1000             }
1001
1002           if (mcount > (context_getLimit ()))
1003             {
1004               cstring_free (s);
1005               return FALSE;
1006             }
1007         }
1008       else
1009         {
1010           cleanupMessages ();
1011           mcount = 0;
1012           cstring_free (lastmsg);
1013           lastmsg = cstring_fromCharsNew (tmpmsg);
1014         }
1015     }
1016
1017   DPRINTF (("Here..."));
1018
1019   if (context_hasAliasAnnote ())
1020     {
1021       char *sc = cstring_toCharsSafe (s);
1022       char *fcolon = strchr (sc, ':');
1023       cstring a = context_getAliasAnnote ();
1024
1025
1026       if (fcolon == NULL)
1027         {
1028           s = message ("%q (%q)", s, a);
1029         }
1030       else
1031         {
1032           cstring afterColon;
1033
1034           *fcolon = '\0';
1035           afterColon = cstring_fromCharsNew (fcolon + 1);
1036
1037           s = message ("%q (%q):%q", s, a, afterColon);
1038         }
1039           }
1040
1041   if (context_hasMessageAnnote ())
1042     {
1043       char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1044
1045
1046       if (fcolon == NULL)
1047         {
1048           /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1049           s = message ("%q (%q)", s, context_getMessageAnnote ());
1050           /*@=dependenttrans@*/
1051         }
1052       else
1053         {
1054           cstring afterColon;
1055
1056           *fcolon = '\0';
1057           afterColon = cstring_fromCharsNew (fcolon + 1);
1058
1059           /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1060           s = message ("%q (%q):%q", s,
1061                        context_getMessageAnnote (), afterColon);
1062           /*@=dependenttrans@*/
1063         }
1064      }
1065
1066   context_setNeednl ();
1067   prepareMessage ();
1068
1069   if (context_showFunction ())
1070     {
1071       cstring fname = fileloc_unparseFilename (g_currentloc);
1072
1073       if (context_inIterDef ())
1074         {
1075           fprintf (g_msgstream, "%s: (in iter %s)\n",
1076                    cstring_toCharsSafe (fname),
1077                    cstring_toCharsSafe (context_inFunctionName ()));
1078         }
1079       else if (context_inIterEnd ())
1080         {
1081           fprintf (g_msgstream, "%s: (in iter finalizer %s)\n",
1082                    cstring_toCharsSafe (fname),
1083                    cstring_toCharsSafe (context_inFunctionName ()));
1084         }
1085       else if (context_inMacro ())
1086         {
1087           fprintf (g_msgstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
1088                    cstring_toCharsSafe (context_inFunctionName ()));
1089         }
1090       else
1091         {
1092           fprintf (g_msgstream, "%s: (in function %s)\n",
1093                    cstring_toCharsSafe (fname),
1094                    cstring_toCharsSafe (context_inFunctionName ()));
1095         }
1096
1097       cstring_free (fname);
1098       context_setShownFunction ();
1099     }
1100
1101   flstring = fileloc_unparse (fl);
1102   lastfileloclen = cstring_length (flstring);
1103
1104   if (indent)
1105     {
1106       printError (g_msgstream, message ("   %q: %q", flstring, s));
1107     }
1108   else
1109     {
1110       printError (g_msgstream, message ("%q: %q", flstring, s));
1111     }
1112
1113   showSourceLoc (srcFile, srcLine);
1114   return TRUE;
1115 }
1116
1117 /*
1118 ** printMessage
1119 **
1120 ** message contains no '\n'
1121 **    message fits in one line: print it
1122 **    message fits in two lines with 3-space indent after fileloc: print it
1123 **    split line with 5-space indent from left margin: print it
1124 **
1125 */
1126
1127 static
1128 void printMessage (FILE *stream, /*@only@*/ cstring s)
1129 {
1130   printIndentMessage (stream, s, 0);
1131 }
1132
1133 static
1134 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1135 {
1136   static bool inbody = FALSE;
1137   int maxlen = context_getLineLen ();
1138   char *s = cstring_toCharsSafe (sc);
1139   char *olds = NULL;
1140
1141   llassertprotect (!inbody);
1142   inbody = TRUE;
1143
1144   do
1145     {
1146       char *t = NULL;
1147       char *st = s;
1148
1149       llassertprotect (st != olds);
1150       olds = st;
1151       mstring_split (&st, &t, maxlen, &indent);
1152       fprintf (stream, "%s\n", st);
1153       llassertprotect (t != s);
1154       s = t;
1155     } while (s != NULL) ;
1156
1157   cstring_free (sc);
1158   inbody = FALSE;
1159 }
1160
1161 static
1162 void printError (FILE *stream, /*@only@*/ cstring sc)
1163 {
1164   int maxlen = context_getLineLen ();
1165   int nspaces = lastfileloclen + 5;
1166   int nextlen = maxlen - nspaces;
1167   int len = cstring_length (sc);
1168   int indent = 0;
1169   char *s = cstring_toCharsSafe (sc);
1170   char *os = s;
1171   char *t = NULL;
1172
1173   DPRINTF (("Print error: [%s]", sc));
1174
1175   if (len < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
1176     {
1177       mstring_split (&s, &t, maxlen, &indent);
1178
1179       fprintf (stream, "%s\n", s);
1180
1181       if (t != NULL)
1182         {
1183           len = mstring_length (t);
1184
1185           if (len < (maxlen - 3) && (strchr (t, '\n') == NULL)
1186               && len > (nextlen - 1))
1187             {
1188               fprintf (stream, "    %s\n", t);
1189             }
1190           else
1191             {
1192               char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1193               int i;
1194
1195               for (i = 0; i < nspaces; i++)
1196                 {
1197                   spaces[i] = ' ';
1198                 }
1199
1200               spaces[nspaces] = '\0';
1201
1202               while (t != NULL)
1203                 {
1204                   char *st = t;
1205                   mstring_split (&st, &t, nextlen, &indent);
1206                   fprintf (stream, "%s%s\n", spaces, st);
1207                 }
1208
1209               sfree (spaces);
1210             }
1211         }
1212     }
1213   else
1214     {
1215       DPRINTF (("Here 1: [%s]", sc));
1216
1217       if (len < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
1218         {
1219           nspaces = ((maxlen + maxlen - 1) - len) / 2;
1220
1221           if (nspaces < 1) nspaces = 1;
1222
1223           nextlen = maxlen - nspaces;
1224
1225           mstring_split (&s, &t, maxlen, &indent);
1226
1227           fprintf (stream, "%s\n", s);
1228
1229           if (t != NULL)
1230             {
1231               char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1232               int i;
1233
1234               for (i = 0; i < nspaces; i++)
1235                 {
1236                   spaces[i] = ' ';
1237                 }
1238
1239               spaces[nspaces] = '\0';
1240
1241               while (t != NULL)
1242                 {
1243                   char *st = t;
1244
1245                   mstring_split (&st, &t, nextlen, &indent);
1246                   fprintf (stream, "%s%s\n", spaces, st);
1247                 }
1248
1249               sfree (spaces);
1250             }
1251         }
1252       else
1253         {
1254           nspaces = 4;
1255           nextlen = maxlen - nspaces;
1256
1257           DPRINTF (("Here 2: [%s]", s));
1258           mstring_split (&s, &t, maxlen, &indent);
1259           DPRINTF (("Here 3: [%s] [%s]", s, t));
1260
1261           fprintf (stream, "%s\n", s);
1262
1263           if (t != NULL)
1264             {
1265               char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1266               int i;
1267
1268               for (i = 0; i < nspaces; i++)
1269                 {
1270                   spaces[i] = ' ';
1271                 }
1272
1273               spaces[nspaces] = '\0';
1274
1275               while (t != NULL)
1276                 {
1277                   char *st = t;
1278                   DPRINTF (("Loop: [%s]", t));
1279                   mstring_split (&st, &t, nextlen, &indent);
1280                   DPRINTF (("Split: [%s] [%s]", st, t));
1281                   fprintf (stream, "%s%s\n", spaces, st);
1282                   DPRINTF (("Next..."));
1283                 }
1284
1285               sfree (spaces);
1286             }
1287         }
1288     }
1289
1290   DPRINTF (("Done"));
1291   sfree (os);
1292 }
1293
1294 void
1295 xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
1296 {
1297   prepareMessage ();
1298   printError (stderr, message ("%q: *** Fatal bug: %q",
1299                                fileloc_unparse (g_currentloc), s));
1300   showSourceLoc (srcFile, srcLine);
1301   printCodePoint ();
1302   printBugReport ();
1303   llexit (LLFAILURE);
1304 }
1305
1306 # ifndef NOLCL
1307 void
1308 lclfatalbug (char *msg)
1309 {
1310   prepareMessage ();
1311   printError (stderr,
1312               message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1313   printCodePoint ();
1314   printBugReport ();
1315   llexit (LLFAILURE);
1316 }
1317 # endif
1318
1319 void
1320 checkParseError (void)
1321 {
1322   if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1323     {
1324       llfatalerror (message ("%q: Cannot recover from parse error.",
1325                              fileloc_unparse (g_currentloc)));
1326     }
1327 }
1328
1329 void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1330 {
1331   /*@unchecked@*/
1332   static int numbugs = 0;
1333   static bool inbug = FALSE;
1334
1335   if (inbug)
1336     {
1337       cstring temps = fileloc_unparseRaw (file, line);
1338
1339       fprintf (stderr, "%s: Recursive bug detected: %s\n",
1340                cstring_toCharsSafe (temps),
1341                cstring_toCharsSafe (s));
1342       cstring_free (temps);
1343
1344       llexit (LLFAILURE);
1345     }
1346
1347   inbug = TRUE;
1348
1349   prepareMessage ();
1350
1351   /*@i3232@*/
1352   /*
1353   if (fileloc_isRealLib (g_currentloc))
1354     {
1355       DPRINTF (("Here we are!"));
1356       llfatalerror (message ("%q: Library file appears to be corrupted.  Error: %q: %s",
1357                         fileloc_unparse (g_currentloc), 
1358                         fileloc_unparseRaw (file, line), 
1359                         s));
1360     }
1361   */
1362
1363   if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1364     {
1365       llfatalerror (message ("%q: Cannot recover from parse error.",
1366                              fileloc_unparse (g_currentloc)));
1367     }
1368
1369   (void) fflush (g_msgstream);
1370   printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1371                                fileloc_unparse (g_currentloc),
1372                                fileloc_unparseRaw (file, line),
1373                                s, errno));
1374   printCodePoint ();
1375
1376   (void) fflush (stderr);
1377   if (errno != 0)
1378     {
1379       perror ("Possible system error diagnostic: ");
1380     }
1381   (void) fflush (stderr);
1382
1383   printBugReport ();
1384
1385   numbugs++;
1386
1387   if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
1388     {
1389       llfatalerror (message ("%q: Cannot recover from last bug. (If you really want Splint to try to continue, use -bugslimit <n>.)",
1390                              fileloc_unparse (g_currentloc)));
1391     }
1392   
1393   fprintf (stderr, "       (attempting to continue, results may be incorrect)\n");
1394   fileloc_free (lastbug);
1395   lastbug = fileloc_copy (g_currentloc);
1396   closeMessage ();
1397
1398   (void) fflush (stderr);
1399   inbug = FALSE;
1400 }
1401
1402 # ifndef NOLCL
1403 void
1404 lclbug (/*@only@*/ cstring s)
1405 {
1406   prepareMessage ();
1407   printError (stderr, message ("*** Internal Bug: %q", s));
1408   printCodePoint ();
1409   printBugReport ();
1410   fprintf (stderr, "       (attempting to continue, results may be incorrect)\n");
1411   closeMessage ();
1412 }
1413 # endif
1414
1415 void
1416 llfatalerror (cstring s)
1417 {
1418   prepareMessage ();
1419   printError (stderr, s);
1420   printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1421   llexit (LLFAILURE);
1422 }
1423
1424 void
1425 llfatalerrorLoc (/*@only@*/ cstring s)
1426 {
1427   prepareMessage ();
1428   (void) fflush (g_msgstream);
1429   printError (stderr, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1430   printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1431   (void) fflush (g_msgstream);
1432   llexit (LLFAILURE);
1433 }
1434
1435 # ifndef NOLCL
1436 bool
1437 lclHadError (void)
1438 {
1439   return (lclerrors > 0);
1440 }
1441
1442 bool
1443 lclHadNewError (void)
1444 {
1445   static int lastcall = 0;
1446
1447   if (lclerrors > lastcall)
1448     {
1449       lastcall = lclerrors;
1450       return TRUE;
1451     }
1452   else
1453     {
1454       return FALSE;
1455     }
1456 }
1457
1458 int
1459 lclNumberErrors (void)
1460 {
1461   return (lclerrors);
1462 }
1463
1464 void
1465 xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
1466 {
1467   lclerrors++;
1468
1469   if (ltoken_getCode (t) != NOTTOKEN)
1470     {
1471       cstring loc = ltoken_unparseLoc (t);
1472
1473       lastfileloclen = cstring_length (loc);
1474
1475       printError (g_msgstream, message ("%q: %q", loc, msg));
1476       showSourceLoc (srcFile, srcLine);
1477     }
1478   else
1479     {
1480       printError (g_msgstream, msg);
1481       showSourceLoc (srcFile, srcLine);
1482     }
1483 }
1484
1485 void
1486 lclplainerror (/*@only@*/ cstring msg)
1487 {
1488   lclerrors++;
1489
1490   printError (g_msgstream, msg);
1491 }
1492
1493 void
1494 lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1495 {
1496   lclerror (t, msg);
1497   (void) fflush (g_msgstream);
1498   printError (stderr, cstring_makeLiteral ("*** Cannot continue"));
1499   llexit (LLFAILURE);
1500 }
1501
1502 void
1503 lclplainfatalerror (/*@only@*/ cstring msg)
1504 {
1505   (void) fflush (g_msgstream);
1506   printError (stderr, message ("*** Cannot continue: %q", msg));
1507   llexit (LLFAILURE);
1508 }
1509
1510 void
1511 lclRedeclarationError (ltoken id)
1512 {
1513   cstring s = ltoken_getRawString (id);
1514
1515
1516   if (usymtab_existsEither (s))
1517     {
1518       uentry le = usymtab_lookupEither (s);
1519
1520       lclerror (id, message ("Respecification of %s", s));
1521       llgenindentmsg (message ("Previous specification of %q",
1522                                uentry_getName (le)),
1523                 uentry_whereSpecified (le));
1524     }
1525   else
1526     {
1527       lclerror (id, message ("Identifier redeclared: %s", s));
1528     }
1529 }
1530 # endif
1531
1532 void genppllerror (flagcode code, /*@only@*/ cstring s)
1533 {
1534   if (context_inSuppressZone (g_currentloc))
1535     {
1536       cstring_free (s);
1537     }
1538   else
1539     {
1540       if (context_getFlag (code))
1541         {
1542           if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1543             {
1544               fprintf (g_msgstream, " >\n");
1545             }
1546
1547           llerror (code, s);
1548
1549           if (code != FLG_PREPROC)
1550             {
1551               llsuppresshint ('-', code);
1552             }
1553
1554           if (context_getFlag (FLG_SHOWSCAN) && !context_isInCommandLine ())
1555             {
1556               fprintf (stderr, "< more preprocessing .");
1557             }
1558         }
1559       else
1560         {
1561           cstring_free (s);
1562         }
1563     }
1564 }
1565
1566 void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1567                        /*@only@*/ cstring hint)
1568 {
1569   if (context_inSuppressZone (g_currentloc))
1570     {
1571       cstring_free (s);
1572       cstring_free (hint);
1573     }
1574   else
1575     {
1576       if (context_getFlag (code))
1577         {
1578           prepareMessage ();
1579           context_clearPreprocessing ();
1580           llerror (code, s);
1581           llgenhint (hint);
1582           context_setPreprocessing ();
1583           closeMessage ();
1584         }
1585       else
1586         {
1587           cstring_free (s);
1588           cstring_free (hint);
1589         }
1590     }
1591 }
1592
1593 void ppllerror (/*@only@*/ cstring s)
1594 {
1595   genppllerror (FLG_PREPROC, s);
1596 }
1597
1598 void pplldiagmsg (cstring s)
1599 {
1600   if (context_getDebug (FLG_SHOWSCAN) && !context_isInCommandLine ())
1601     {
1602       fprintf (stderr, " >\n");
1603       lldiagmsg (s);
1604       fprintf (stderr, "< more preprocessing .");
1605     }
1606   else
1607     {
1608       lldiagmsg (s);
1609     }
1610 }
1611
1612 void loadllmsg (cstring s)
1613 {
1614   if (context_getDebug (FLG_SHOWSCAN))
1615     {
1616       fprintf (stderr, " >\n");
1617       lldiagmsg (s);
1618       fprintf (stderr, "< .");
1619     }
1620   else
1621     {
1622       lldiagmsg (s);
1623     }
1624 }
1625
1626 static void llreportparseerror (/*@only@*/ cstring s)
1627 {
1628   if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1629     {
1630       cstring_free (s);
1631     }
1632   else
1633     {
1634       llerror (FLG_SYNTAX, s);
1635
1636       fileloc_free (lastparseerror);
1637       lastparseerror = fileloc_copy (g_currentloc);
1638     }
1639 }
1640
1641 bool xcppoptgenerror (char *srcFile, int srcLine,
1642                       flagcode o,
1643                       /*@only@*/ cstring s,
1644                       cppReader *pfile)
1645 {
1646   bool res = FALSE;
1647   fileloc loc = cppReader_getLoc (pfile);
1648
1649   if (context_flagOn (o, loc))
1650     {
1651       if (xlloptgenerror (srcFile, srcLine, o, s, loc))
1652         {
1653           cppReader_printContainingFiles (pfile);
1654           res = TRUE;
1655         }
1656     }
1657   else
1658     {
1659       cstring_free (s);
1660     }
1661
1662   fileloc_free (loc);
1663
1664   return res;
1665 }
1666
1667 bool xlloptgenerror (char *srcFile, int srcLine, 
1668                      flagcode o, /*@only@*/ cstring s, fileloc loc)
1669 {
1670   DPRINTF (("xllopt: %s", s));
1671
1672   if (llrealerror (srcFile, srcLine, s, loc))
1673     {
1674       DPRINTF (("Here we are!"));
1675       llsuppresshint ('-', o);
1676       closeMessage ();
1677       flagcode_recordError (o);
1678       return TRUE;
1679     }
1680   else
1681     {
1682       DPRINTF (("Suppressed!"));
1683       flagcode_recordSuppressed (o);
1684       return FALSE;
1685     }
1686 }
1687
1688 bool xoptgenerror2 (char *srcFile, int srcLine,
1689                     flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1690 {
1691   if (context_suppressFlagMsg (f1, loc))
1692     {
1693       flagcode_recordSuppressed (f1);
1694       cstring_free (s);
1695     }
1696   else
1697     {
1698       if (context_suppressFlagMsg (f2, loc))
1699         {
1700           flagcode_recordSuppressed (f2);
1701           cstring_free (s);
1702         }
1703       else
1704         {
1705           if (llrealerror (srcFile, srcLine, s, loc))
1706             {
1707               llsuppresshint2 ('-', f1, f2);
1708               flagcode_recordError (f2);
1709               closeMessage ();
1710               return TRUE;
1711             }
1712           else
1713             {
1714               flagcode_recordSuppressed (f2);
1715             }
1716         }
1717     }
1718
1719   return FALSE;
1720 }
1721
1722 bool xoptgenerror2n (char *srcFile, int srcLine,
1723                      flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
1724 {
1725
1726   if (context_suppressFlagMsg (f1, loc))
1727     {
1728       flagcode_recordSuppressed (f1);
1729       cstring_free (s);
1730     }
1731   else
1732     {
1733       if (context_suppressNotFlagMsg (f2, loc))
1734         {
1735           flagcode_recordSuppressed (f2);
1736           cstring_free (s);
1737         }
1738       else
1739         {
1740           if (llrealerror (srcFile, srcLine, s, loc))
1741             {
1742               llsuppresshint ('+', f2);
1743               flagcode_recordError (f2);
1744               closeMessage ();
1745               return TRUE;
1746             }
1747
1748           flagcode_recordSuppressed (f2);
1749         }
1750     }
1751   return FALSE;
1752 }
1753
1754 bool xllnoptgenerror (char *srcFile, int srcLine,
1755                       flagcode o, /*@only@*/ cstring s, fileloc loc)
1756 {
1757   if (llrealerror (srcFile, srcLine, s, loc))
1758     {
1759       llsuppresshint ('+', o);
1760       flagcode_recordError (o);
1761       closeMessage ();
1762       return TRUE;
1763     }
1764
1765   flagcode_recordSuppressed (o);
1766   return FALSE;
1767 }
1768
1769 void llparseerror (cstring s)
1770 {
1771   if (context_getFlag (FLG_TRYTORECOVER))
1772     {
1773       parseerrorcount++;
1774
1775       if (parseerrorcount > GIVEUPPARSE)
1776         {
1777           if (cstring_isDefined (s))
1778             {
1779               llfatalerror (message ("%q: Parse Error: %q.  "
1780                                      "Too many errors, giving up.",
1781                                      fileloc_unparse (g_currentloc), s));
1782             }
1783           else
1784             {
1785               llfatalerror (message ("%q: Parse Error.  Too many errors, giving up.",
1786                                      fileloc_unparse (g_currentloc)));
1787             }
1788         }
1789       else
1790         {
1791           if (cstring_isDefined (s))
1792             {
1793               llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1794                                            s));
1795             }
1796           else
1797             {
1798               llreportparseerror (message ("Parse Error. Attempting to continue."));
1799             }
1800         }
1801     }
1802   else
1803     {
1804       cstring msg;
1805
1806       if (cstring_isDefined (s))
1807         {
1808           msg = message ("Parse Error: %q.", s);
1809         }
1810       else
1811         {
1812           msg = message ("Parse Error.");
1813         }
1814
1815       llfatalerror
1816         (message ("%q: %s (For help on parse errors, "
1817                   "see lclint -help parseerrors.)",
1818                   fileloc_unparse (g_currentloc), msg));
1819     }
1820 }
1821
1822 bool xfsgenerror (char *srcFile, int srcLine,
1823                    flagSpec fs, /*@only@*/ cstring s, fileloc fl) 
1824 {
1825   if (flagSpec_isOn (fs, fl))
1826     {
1827       if (llgenerroraux (srcFile, srcLine, s, fl, TRUE, FALSE))
1828         {
1829           llsuppresshint ('-', flagSpec_getFirstOn (fs, fl));
1830           flagcode_recordError (flagSpec_getFirstOn (fs, fl));
1831           return TRUE;
1832         }
1833       else
1834         {
1835           flagcode_recordSuppressed (flagSpec_getFirstOn (fs, fl));
1836           return FALSE;
1837         }
1838     }
1839   else
1840     {
1841       flagcode_recordSuppressed (flagSpec_getDominant (fs));
1842       cstring_free (s);
1843       return FALSE;
1844     }
1845 }
1846
1847 bool doCheck (bool x, cstring pred, cstring file, int line)
1848 {
1849   if (!x) {
1850     llbug (message ("%q: Check Failed: %s",
1851                     fileloc_unparseRaw (file, line),
1852                     pred));
1853   }
1854
1855   return x;
1856 }
1857
1858 /*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
1859 {
1860   char *result;
1861
1862 #ifndef VMS
1863 #ifndef HAVE_STRERROR
1864   result = NULL;
1865 #else
1866   result = strerror (errnum);
1867 #endif
1868 #else   /* VMS */
1869   /* VAXCRTL's strerror() takes an optional second argument, which only
1870      matters when the first argument is EVMSERR.  However, it's simplest
1871      just to pass it unconditionally.  `vaxc$errno' is declared in
1872      <errno.h>, and maintained by the library in parallel with `errno'.
1873      We assume that caller's `errnum' either matches the last setting of
1874      `errno' by the library or else does not have the value `EVMSERR'.  */
1875
1876   result = strerror (errnum, vaxc$errno);
1877 #endif
1878
1879   if (result == NULL)
1880     {
1881       result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
1882     }
1883
1884   return cstring_fromChars (result);
1885 }
1886
1887 void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
1888 {
1889 # if 0
1890 # ifdef HOMEVERSION
1891   llflush ();
1892   printError (stderr, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1893                                fileloc_unparse (g_currentloc),
1894                                fileloc_unparseRaw (file, line),
1895                                s, errno));
1896   printCodePoint ();
1897   llflush ();
1898 # endif
1899 # else
1900   cstring_free (s);
1901 # endif
1902 }
1903
1904 void llflush (void)
1905 {
1906   (void) fflush (g_msgstream);
1907   (void) fflush (stderr);
1908 }
This page took 0.202966 seconds and 5 git commands to generate.