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