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