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