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