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