]> andersk Git - splint.git/blob - src/llerror.c
Renaming - LCLint => Splint
[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   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
1011   DPRINTF (("Here..."));
1012
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);
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
1107   showSourceLoc (srcFile, srcLine);
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
1121 static
1122 void printMessage (FILE *stream, /*@only@*/ cstring s)
1123 {
1124   printIndentMessage (stream, s, 0);
1125 }
1126
1127 static
1128 void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1129 {
1130   static bool inbody = FALSE;
1131   int maxlen = context_getLineLen ();
1132   char *s = cstring_toCharsSafe (sc);
1133   char *olds = NULL;
1134
1135   llassertprotect (!inbody);
1136   inbody = TRUE;
1137
1138   do
1139     {
1140       char *t = NULL;
1141       char *st = s;
1142
1143       llassertprotect (st != olds);
1144       olds = st;
1145       mstring_split (&st, &t, maxlen, &indent);
1146       fprintf (stream, "%s\n", st);
1147       llassertprotect (t != s);
1148       s = t;
1149     } while (s != NULL) ;
1150
1151   cstring_free (sc);
1152   inbody = FALSE;
1153 }
1154
1155 static
1156 void 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
1167   DPRINTF (("Print error: [%s]", sc));
1168
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     {
1209       DPRINTF (("Here 1: [%s]", sc));
1210
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
1251           DPRINTF (("Here 2: [%s]", s));
1252           mstring_split (&s, &t, maxlen, &indent);
1253           DPRINTF (("Here 3: [%s] [%s]", s, t));
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;
1272                   DPRINTF (("Loop: [%s]", t));
1273                   mstring_split (&st, &t, nextlen, &indent);
1274                   DPRINTF (("Split: [%s] [%s]", st, t));
1275                   fprintf (stream, "%s%s\n", spaces, st);
1276                   DPRINTF (("Next..."));
1277                 }
1278
1279               sfree (spaces);
1280             }
1281         }
1282     }
1283
1284   DPRINTF (("Done"));
1285   sfree (os);
1286 }
1287
1288 void
1289 xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
1290 {
1291   prepareMessage ();
1292   printError (stderr, message ("%q: *** Fatal bug: %q",
1293                                fileloc_unparse (g_currentloc), s));
1294   showSourceLoc (srcFile, srcLine);
1295   printCodePoint ();
1296   printBugReport ();
1297   llexit (LLFAILURE);
1298 }
1299
1300 # ifndef NOLCL
1301 void
1302 lclfatalbug (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
1313 void
1314 checkParseError (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
1323 void 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
1345   /*@i3232@*/
1346   /*
1347   if (fileloc_isRealLib (g_currentloc))
1348     {
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));
1354     }
1355   */
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);
1371   if (errno != 0)
1372     {
1373       perror ("Possible system error diagnostic: ");
1374     }
1375   (void) fflush (stderr);
1376
1377   printBugReport ();
1378
1379   numbugs++;
1380
1381   if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
1382     {
1383       llfatalerror (message ("%q: Cannot recover from last bug. (If you really want Splint to try to continue, use -bugslimit <n>.)",
1384                              fileloc_unparse (g_currentloc)));
1385     }
1386   
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
1397 void
1398 lclbug (/*@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
1409 void
1410 llfatalerror (cstring s)
1411 {
1412   prepareMessage ();
1413   printError (stderr, s);
1414   printError (stderr, cstring_makeLiteral ("*** Cannot continue."));
1415   llexit (LLFAILURE);
1416 }
1417
1418 void
1419 llfatalerrorLoc (/*@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."));
1425   (void) fflush (g_msgstream);
1426   llexit (LLFAILURE);
1427 }
1428
1429 # ifndef NOLCL
1430 bool
1431 lclHadError (void)
1432 {
1433   return (lclerrors > 0);
1434 }
1435
1436 bool
1437 lclHadNewError (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
1452 int
1453 lclNumberErrors (void)
1454 {
1455   return (lclerrors);
1456 }
1457
1458 void
1459 xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
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));
1470       showSourceLoc (srcFile, srcLine);
1471     }
1472   else
1473     {
1474       printError (g_msgstream, msg);
1475       showSourceLoc (srcFile, srcLine);
1476     }
1477 }
1478
1479 void
1480 lclplainerror (/*@only@*/ cstring msg)
1481 {
1482   lclerrors++;
1483
1484   printError (g_msgstream, msg);
1485 }
1486
1487 void
1488 lclfatalerror (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
1496 void
1497 lclplainfatalerror (/*@only@*/ cstring msg)
1498 {
1499   (void) fflush (g_msgstream);
1500   printError (stderr, message ("*** Cannot continue: %q", msg));
1501   llexit (LLFAILURE);
1502 }
1503
1504 void
1505 lclRedeclarationError (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
1526 void 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
1560 void 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
1587 void ppllerror (/*@only@*/ cstring s)
1588 {
1589   genppllerror (FLG_PREPROC, s);
1590 }
1591
1592 void 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
1606 void 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
1620 static 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
1635 bool 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
1661 bool xlloptgenerror (char *srcFile, int srcLine, 
1662                      flagcode o, /*@only@*/ cstring s, fileloc loc)
1663 {
1664   DPRINTF (("xllopt: %s", s));
1665
1666   if (llrealerror (srcFile, srcLine, s, loc))
1667     {
1668       DPRINTF (("Here we are!"));
1669       llsuppresshint ('-', o);
1670       closeMessage ();
1671       flagcode_recordError (o);
1672       return TRUE;
1673     }
1674   else
1675     {
1676       DPRINTF (("Suppressed!"));
1677       flagcode_recordSuppressed (o);
1678       return FALSE;
1679     }
1680 }
1681
1682 bool xoptgenerror2 (char *srcFile, int srcLine,
1683                     flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
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         {
1699           if (llrealerror (srcFile, srcLine, s, loc))
1700             {
1701               llsuppresshint2 ('-', f1, f2);
1702               flagcode_recordError (f2);
1703               closeMessage ();
1704               return TRUE;
1705             }
1706           else
1707             {
1708               flagcode_recordSuppressed (f2);
1709             }
1710         }
1711     }
1712
1713   return FALSE;
1714 }
1715
1716 bool xoptgenerror2n (char *srcFile, int srcLine,
1717                      flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
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         {
1734           if (llrealerror (srcFile, srcLine, s, loc))
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
1748 bool xllnoptgenerror (char *srcFile, int srcLine,
1749                       flagcode o, /*@only@*/ cstring s, fileloc loc)
1750 {
1751   if (llrealerror (srcFile, srcLine, s, loc))
1752     {
1753       llsuppresshint ('+', o);
1754       flagcode_recordError (o);
1755       closeMessage ();
1756       return TRUE;
1757     }
1758
1759   flagcode_recordSuppressed (o);
1760   return FALSE;
1761 }
1762
1763 void 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
1816 bool 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
1841 bool 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
1881 void 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
1898 void llflush (void)
1899 {
1900   (void) fflush (g_msgstream);
1901   (void) fflush (stderr);
1902 }
This page took 0.190922 seconds and 5 git commands to generate.