]> andersk Git - splint.git/blame - src/llerror.c
Fixed scanf %x problem.
[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
9f618ec5 698 /*drl 4-270-2003 even if ignoresigns is set there may be another
699 problem that is causing splint to complain about a type error.
700 Don't tell the user that they can add +ignoresigns if it's
701 already on*/
6fcd0b1e 702 {
9f618ec5 703 DPRINTF(("TEST INGORESIGNS"));
704 if (context_getFlag(FLG_IGNORESIGNS) )
705 {
706 DPRINTF(("INGORESIGNS SET"));
707 hcode = FLG_IGNOREQUALS;
708 }
709
710 else
711 {
712 DPRINTF(("INGORESIGNS NOT SET"));
713 hcode = FLG_IGNORESIGNS;
714 }
6fcd0b1e 715 }
616915dd 716 }
717 else
718 {
719 hcode = FLG_IGNOREQUALS;
720 }
721 }
722 else if (ctype_isArbitraryIntegral (ctype_realType (ut1)))
723 {
e0a05ba9 724 DPRINTF (("HERE: %s", ctype_unparse (ctype_realType (ut2))));
725
616915dd 726 if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
727 {
728 hcode = FLG_MATCHANYINTEGRAL;
729 }
e0a05ba9 730 else if (ctype_equal (ut2, ctype_ulint))
616915dd 731 {
732 hcode = FLG_LONGUNSIGNEDINTEGRAL;
733 }
e0a05ba9 734 else if (ctype_equal (ut2, ctype_lint))
616915dd 735 {
736 hcode = FLG_LONGINTEGRAL;
737 }
738 else if (ctype_isInt (ut2))
739 {
740 hcode = FLG_MATCHANYINTEGRAL;
e0a05ba9 741 }
616915dd 742 else
743 {
e0a05ba9 744 hcode = FLG_TYPE;
616915dd 745 }
746 }
747 else if (ctype_isArbitraryIntegral (ctype_realType (ut2)))
748 {
749 ctype tr = ctype_realType (ut1);
750
751 if (ctype_isArbitraryIntegral (tr))
752 {
753 hcode = FLG_MATCHANYINTEGRAL;
754 }
755 else if (ctype_match (ut1, ctype_ulint))
756 {
757 if (ctype_isUnsignedIntegral (tr))
758 {
759 hcode = FLG_LONGUNSIGNEDUNSIGNEDINTEGRAL;
760 }
761 else if (ctype_isSignedIntegral (tr))
762 {
763 ;
764 }
765 else
766 {
767 hcode = FLG_LONGUNSIGNEDINTEGRAL;
768 }
769 }
770 else if (ctype_match (ut1, ctype_lint))
771 {
772 if (ctype_isSignedIntegral (tr))
773 {
774 hcode = FLG_LONGSIGNEDINTEGRAL;
775 }
776 else if (ctype_isSignedIntegral (tr))
777 {
778 ;
779 }
780 else
781 {
782 hcode = FLG_LONGINTEGRAL;
783 }
784 }
785 else if (ctype_isInt (ut1))
786 {
787 hcode = FLG_MATCHANYINTEGRAL;
788 }
789 else
790 {
791 ;
792 }
793 }
990ec868 794 else
795 {
796 ;
797 }
798
799 if (hcode == INVALID_FLAG)
616915dd 800 {
990ec868 801 DPRINTF (("[%s] %s - %s / %s",
802 ctype_unparse (ut1),
803 bool_unparse (ctype_isEnum (ut1)),
804 bool_unparse (ctype_isEnum (ctype_realType (ut1))),
805 bool_unparse (ctype_isInt (ut2))));
616915dd 806
990ec868 807 if (ctype_isAbstract (ut1) && !ctype_isAbstract (ut2))
616915dd 808 {
990ec868 809 uentry ue1 = usymtab_getTypeEntry (ctype_typeId (ut1));
810 ctype ct = uentry_getType (ue1);
811
812 if (ctype_match (ct, ut2))
813 {
814 code = FLG_ABSTRACT;
815 hint = message ("Underlying types match, but %s is an "
816 "abstract type that is not accessible here.",
817 ctype_unparse (t1));
818 }
616915dd 819 }
990ec868 820 else if (ctype_isAbstract (ut2) && !ctype_isAbstract (ut1))
821 {
822 uentry ue = usymtab_getTypeEntry (ctype_typeId (ut2));
823 ctype ct = uentry_getType (ue);
824
825 if (ctype_match (ct, ut1))
826 {
e5081f8c 827 if (ctype_isNumAbstract (ut2))
828 {
829 if (exprNode_isNumLiteral (e1))
830 {
831 code = FLG_NUMABSTRACTLIT;
832 hint = message ("Underlying types match, but %s is a "
833 "numabstract type that is not accessible here. "
834 "(Use +numabstractlit to allow numeric literals "
835 "to be used as numabstract type values.)",
836 ctype_unparse (t2));
837 }
838 else
839 {
840 code = FLG_NUMABSTRACT;
841 hint = message ("Underlying types match, but %s is a "
842 "numabstract type that is not accessible here.",
843 ctype_unparse (t2));
844 }
845 }
846 else
847 {
848 code = FLG_ABSTRACT;
849 hint = message ("Underlying types match, but %s is an "
850 "abstract type that is not accessible here.",
851 ctype_unparse (t2));
852 }
990ec868 853 }
854 }
855 else
856 {
857 ; /* Not an abstract mismatch. */
858 }
859
616915dd 860
990ec868 861 if (hcode == INVALID_FLAG)
616915dd 862 {
990ec868 863 if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
864 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
865 {
866 hcode = FLG_ENUMINT;
867 }
868 else if ((ctype_isEnum (ut1) && ctype_isInt (ut2))
869 || (ctype_isEnum (ut2) && ctype_isInt (ut1)))
870 {
871 hcode = FLG_ENUMINT;
872 }
873 else if ((ctype_isSignedChar (ut1) && ctype_isUnsignedChar (ut2))
874 || (ctype_isUnsignedChar (ut1) && ctype_isSignedChar (ut2)))
875 {
876 hcode = FLG_CHARUNSIGNEDCHAR;
877 }
878 else if (ctype_isNumeric (ut1) && ctype_isNumeric (ut2))
879 {
880 hcode = FLG_RELAXTYPES;
881 DPRINTF (("Setting relax types!"));
882 }
883 else
884 {
885 DPRINTF (("No special type rule: %s / %s", ctype_unparse (ut1),
886 ctype_unparse (ut2)));
887 }
616915dd 888 }
889 }
616915dd 890
891 if (cstring_isDefined (hint))
892 {
893 if (!context_suppressFlagMsg (ocode, fl))
894 {
e5081f8c 895 return xllgenhinterror (srcFile, srcLine, code, s, hint, fl);
616915dd 896 }
897 else
898 {
899 cstring_free (s);
900 cstring_free (hint);
901 return FALSE;
902 }
903 }
904 else
905 {
53306cab 906 if (hcode != INVALID_FLAG && hcode != ocode)
907 {
908 code = hcode;
909 }
910
e5081f8c 911 if (llgenerroraux (ocode, srcFile, srcLine, s,
912 flagcodeHint (code), fl, TRUE, FALSE))
616915dd 913 {
53306cab 914 if (code != ocode)
616915dd 915 {
6fcd0b1e 916 if (context_flagOn (code, fl))
917 {
918 /* The flag is alreay set, something buggy in the flag code */
919 llcontbug (message ("No hint available, flag %s is already set.",
920 flagcode_unparse (code)));
921 }
922 else
923 {
924 llshowhint (code);
925 }
53306cab 926 }
616915dd 927 else
928 {
929 llsuppresshint ('-', code);
930 }
931
932 flagcode_recordError (code);
933 return TRUE;
934 }
935
936 return FALSE;
937 }
938}
939
940bool
28bf4b0b 941xllgentypeerror (char *srcFile, int srcLine,
942 ctype t1, exprNode e1, ctype t2, exprNode e2,
943 /*@only@*/ cstring s, fileloc fl)
616915dd 944{
28bf4b0b 945 return llgentypeerroraux (srcFile, srcLine, FLG_TYPE, t1, e1, t2, e2, s, fl);
616915dd 946}
947
948bool
28bf4b0b 949xllgenformattypeerror (char *srcFile, int srcLine,
950 ctype t1, exprNode e1, ctype t2, exprNode e2,
951 /*@only@*/ cstring s, fileloc fl)
616915dd 952{
ccf0a4a8 953 if (!context_suppressFlagMsg (FLG_FORMATTYPE, fl))
954 {
b73d1009 955 if (ctype_isInt (t1)
956 && ctype_isNumAbstract (t2))
957 {
958 if (!context_suppressFlagMsg (FLG_NUMABSTRACTPRINT, fl))
959 {
960 return llgentypeerroraux (srcFile, srcLine, FLG_NUMABSTRACTPRINT, t1, e1, t2, e2, s, fl);
961 }
962 else
963 {
964 return FALSE;
965 }
966 }
967 else
968 {
969 return llgentypeerroraux (srcFile, srcLine, FLG_FORMATTYPE, t1, e1, t2, e2, s, fl);
970 }
ccf0a4a8 971 }
972 else
973 {
974 cstring_free (s);
975 return FALSE;
976 }
616915dd 977}
978
979bool
28bf4b0b 980xllgenerror (char *srcFile, int srcLine, flagcode o, /*@only@*/ cstring s, fileloc fl)
616915dd 981{
53306cab 982 if (llgenerroraux (o, srcFile, srcLine, s, flagcodeHint (o), fl, TRUE, FALSE))
616915dd 983 {
984 llnosuppresshint (o);
985 flagcode_recordError (o);
986 closeMessage ();
987 return TRUE;
988 }
989 else
990 {
991 flagcode_recordSuppressed (o);
992 return FALSE;
993 }
994}
995
996bool
28bf4b0b 997xllgenhinterror (char *srcFile, int srcLine,
998 flagcode o, /*@only@*/ cstring s, /*@only@*/ cstring hint,
999 fileloc fl)
616915dd 1000{
1001 if (!context_suppressFlagMsg (o, fl))
1002 {
53306cab 1003 if (llgenerroraux (o, srcFile, srcLine, s, hint, fl, TRUE, FALSE))
616915dd 1004 {
1005 flagcode_recordError (o);
1006
1007 if (context_getFlag (FLG_HINTS))
1008 {
1009 llgenhint (hint);
1010 }
1011 else
1012 {
1013 cstring_free (hint);
1014 }
1015
1016 closeMessage ();
1017 return TRUE;
1018 }
1019
1020 cstring_free (hint);
1021 }
1022 else
1023 {
1024 cstring_free (hint);
1025 cstring_free (s);
1026 }
1027
1028 flagcode_recordSuppressed (o);
1029 return FALSE;
1030}
1031
1032static bool
53306cab 1033llrealerror (flagcode code, char *srcFile, int srcLine, /*@only@*/ cstring s, /*@temp@*/ cstring addtext, fileloc fl)
616915dd 1034{
53306cab 1035 return (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, TRUE, FALSE));
616915dd 1036}
1037
1038static bool
53306cab 1039llgenerroraux (flagcode code,
1040 char *srcFile, int srcLine,
1041 /*@only@*/ cstring s,
1042 cstring addtext,
1043 fileloc fl, bool iserror, bool indent)
616915dd 1044{
616915dd 1045 if (context_inSuppressZone (fl))
1046 {
1047 cstring_free (s);
1048 return FALSE;
1049 }
ccf0a4a8 1050
53306cab 1051 if (llgenerrorreal (code, srcFile, srcLine, s, addtext, fl, iserror, indent)) {
28bf4b0b 1052 return TRUE;
1053 } else {
1054 return FALSE;
1055 }
616915dd 1056}
1057
28bf4b0b 1058bool
1059xllforceerror (char *srcFile, int srcLine,
1060 flagcode code, /*@only@*/ cstring s, fileloc fl)
616915dd 1061{
1062 flagcode_recordError (code);
28bf4b0b 1063
53306cab 1064 if (llgenerrorreal (code, srcFile, srcLine, s, cstring_undefined, fl, TRUE, FALSE)) {
28bf4b0b 1065 closeMessage ();
1066 return TRUE;
1067 } else {
1068 return FALSE;
1069 }
616915dd 1070}
1071
53306cab 1072static void generateCSV (flagcode code, cstring s, cstring addtext, fileloc fl)
1073{
1074
1075 if (g_csvstream != NULL) {
1076 /* Warning, Flag Code, Flag Name, Priority, File, Line, Column, Warning Text, Additional Text */
1077 fprintf (g_csvstream, "%d,%d,%s,%d,%s,%d,%d,\"%s\"",
1078 context_numErrors (),
1079 (int) code, /* flag code */
1080 cstring_toCharsSafe (flagcode_unparse (code)), /* flag name */
1081 flagcode_priority (code), /* priority */
1082 cstring_toCharsSafe (fileloc_outputFilename (fl)),
1083 fileloc_lineno (fl),
1084 fileloc_column (fl),
1085 cstring_toCharsSafe (s));
1086
1087 if (cstring_isDefined (addtext)) {
1088 fprintf (g_csvstream, ",\"%s\"\n", cstring_toCharsSafe (addtext));
1089 } else {
1090 fprintf (g_csvstream, "\n");
1091 }
1092 }
1093}
1094
616915dd 1095static bool
53306cab 1096llgenerrorreal (flagcode code, char *srcFile, int srcLine,
1097 /*@only@*/ cstring s,
1098 cstring addtext,
1099 fileloc fl, bool iserror, bool indent)
616915dd 1100{
1101 cstring flstring;
1102
1103 /* duplicate message (rescanning a header file */
1104
1105 if (!messageLog_add (context_messageLog (), fl, s))
1106 {
28bf4b0b 1107 DPRINTF (("Duplicate message suppressed! %s / %s",
1108 fileloc_unparse (fl), s));
616915dd 1109 cstring_free (s);
1110 return FALSE;
1111 }
1112
60868d40 1113 /*
1114 ** If herald has not been displayed, display it before the first message.
1115 */
1116
1117 showHerald ();
1118
616915dd 1119 if (iserror) context_hasError ();
1120
1121 if (context_unlimitedMessages ())
1122 {
1123 ;
1124 }
1125 else
1126 {
1127 /*
1128 ** suppress excessive messages:
1129 ** check up to ':'
1130 **
1131 */
1132
1133 char *sc = cstring_toCharsSafe (s);
1134 char *tmpmsg = strchr (sc, ':');
1135
1136 if (tmpmsg == NULL)
1137 {
1138 tmpmsg = sc;
1139 }
1140 else
1141 {
1142 char *savechar = tmpmsg;
1143 *tmpmsg = '\0';
1144 tmpmsg = sc;
1145 *savechar = ':';
1146 }
1147
517a2db3 1148 if (cstring_equal (s_lastmsg, cstring_fromChars (tmpmsg)))
616915dd 1149 {
517a2db3 1150 s_mcount++;
1151 if (s_mcount == (context_getLimit () + 1))
616915dd 1152 {
1153 limitmessage (s, fl);
1154 return FALSE;
1155 }
1156
517a2db3 1157 if (s_mcount > (context_getLimit ()))
616915dd 1158 {
1159 cstring_free (s);
1160 return FALSE;
1161 }
1162 }
1163 else
1164 {
1165 cleanupMessages ();
517a2db3 1166 s_mcount = 0;
1167 cstring_free (s_lastmsg);
1168 s_lastmsg = cstring_fromCharsNew (tmpmsg);
616915dd 1169 }
1170 }
1171
28bf4b0b 1172 DPRINTF (("Here..."));
1173
616915dd 1174 if (context_hasAliasAnnote ())
1175 {
1176 char *sc = cstring_toCharsSafe (s);
1177 char *fcolon = strchr (sc, ':');
1178 cstring a = context_getAliasAnnote ();
1179
1180
1181 if (fcolon == NULL)
1182 {
1183 s = message ("%q (%q)", s, a);
1184 }
1185 else
1186 {
1187 cstring afterColon;
1188
1189 *fcolon = '\0';
1190 afterColon = cstring_fromCharsNew (fcolon + 1);
1191
1192 s = message ("%q (%q):%q", s, a, afterColon);
1193 }
1194 }
1195
1196 if (context_hasMessageAnnote ())
1197 {
1198 char *fcolon = strchr (cstring_toCharsSafe (s), ':');
1199
1200
1201 if (fcolon == NULL)
1202 {
1203 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1204 s = message ("%q (%q)", s, context_getMessageAnnote ());
1205 /*@=dependenttrans@*/
1206 }
1207 else
1208 {
1209 cstring afterColon;
1210
1211 *fcolon = '\0';
1212 afterColon = cstring_fromCharsNew (fcolon + 1);
1213
1214 /*@-dependenttrans@*/ /* s becomes dependent for fcolon */
1215 s = message ("%q (%q):%q", s,
1216 context_getMessageAnnote (), afterColon);
1217 /*@=dependenttrans@*/
1218 }
1219 }
1220
1221 context_setNeednl ();
1222 prepareMessage ();
1223
1224 if (context_showFunction ())
1225 {
1226 cstring fname = fileloc_unparseFilename (g_currentloc);
1227
1228 if (context_inIterDef ())
1229 {
80489f0a 1230 fprintf (g_warningstream, "%s: (in iter %s)\n",
616915dd 1231 cstring_toCharsSafe (fname),
1232 cstring_toCharsSafe (context_inFunctionName ()));
1233 }
1234 else if (context_inIterEnd ())
1235 {
80489f0a 1236 fprintf (g_warningstream, "%s: (in iter finalizer %s)\n",
616915dd 1237 cstring_toCharsSafe (fname),
1238 cstring_toCharsSafe (context_inFunctionName ()));
1239 }
1240 else if (context_inMacro ())
1241 {
80489f0a 1242 fprintf (g_warningstream, "%s: (in macro %s)\n", cstring_toCharsSafe (fname),
616915dd 1243 cstring_toCharsSafe (context_inFunctionName ()));
1244 }
1245 else
1246 {
80489f0a 1247 fprintf (g_warningstream, "%s: (in function %s)\n",
616915dd 1248 cstring_toCharsSafe (fname),
1249 cstring_toCharsSafe (context_inFunctionName ()));
1250 }
1251
1252 cstring_free (fname);
1253 context_setShownFunction ();
1254 }
1255
1256 flstring = fileloc_unparse (fl);
517a2db3 1257 s_lastfileloclen = cstring_length (flstring);
616915dd 1258
53306cab 1259 generateCSV (code, s, addtext, fl);
1260
616915dd 1261 if (indent)
1262 {
80489f0a 1263 printError (g_warningstream, message (" %q: %q", flstring, s));
616915dd 1264 }
1265 else
1266 {
80489f0a 1267 printError (g_warningstream, message ("%q: %q", flstring, s));
616915dd 1268 }
1269
28bf4b0b 1270 showSourceLoc (srcFile, srcLine);
53306cab 1271
616915dd 1272 return TRUE;
1273}
1274
1275/*
1276** printMessage
1277**
1278** message contains no '\n'
1279** message fits in one line: print it
1280** message fits in two lines with 3-space indent after fileloc: print it
1281** split line with 5-space indent from left margin: print it
1282**
1283*/
1284
1285static
1286void printMessage (FILE *stream, /*@only@*/ cstring s)
1287{
1288 printIndentMessage (stream, s, 0);
1289}
1290
1291static
1292void printIndentMessage (FILE *stream, /*@only@*/ cstring sc, int indent)
1293{
28bf4b0b 1294 static bool inbody = FALSE;
616915dd 1295 int maxlen = context_getLineLen ();
1296 char *s = cstring_toCharsSafe (sc);
28bf4b0b 1297 char *olds = NULL;
616915dd 1298
28bf4b0b 1299 llassertprotect (!inbody);
1300 inbody = TRUE;
616915dd 1301
1302 do
1303 {
1304 char *t = NULL;
1305 char *st = s;
1306
28bf4b0b 1307 llassertprotect (st != olds);
1308 olds = st;
616915dd 1309 mstring_split (&st, &t, maxlen, &indent);
1310 fprintf (stream, "%s\n", st);
28bf4b0b 1311 llassertprotect (t != s);
616915dd 1312 s = t;
1313 } while (s != NULL) ;
1314
1315 cstring_free (sc);
28bf4b0b 1316 inbody = FALSE;
616915dd 1317}
1318
1319static
1320void printError (FILE *stream, /*@only@*/ cstring sc)
1321{
1322 int maxlen = context_getLineLen ();
517a2db3 1323 size_t nspaces = s_lastfileloclen + 5;
e5081f8c 1324 int nextlen = maxlen - size_toInt (nspaces);
abd7f895 1325 size_t len = cstring_length (sc);
616915dd 1326 int indent = 0;
1327 char *s = cstring_toCharsSafe (sc);
1328 char *os = s;
1329 char *t = NULL;
1330
28bf4b0b 1331 DPRINTF (("Print error: [%s]", sc));
1332
abd7f895 1333 if (size_toInt (len) < (maxlen + nextlen) && (strchr (s, '\n') == NULL))
616915dd 1334 {
1335 mstring_split (&s, &t, maxlen, &indent);
1336
1337 fprintf (stream, "%s\n", s);
1338
1339 if (t != NULL)
1340 {
1341 len = mstring_length (t);
1342
abd7f895 1343 if (size_toInt (len) < (maxlen - 3) && (strchr (t, '\n') == NULL)
1344 && size_toInt (len) > (nextlen - 1))
616915dd 1345 {
1346 fprintf (stream, " %s\n", t);
1347 }
1348 else
1349 {
1350 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1351 int i;
1352
abd7f895 1353 for (i = 0; i < size_toInt (nspaces); i++)
616915dd 1354 {
1355 spaces[i] = ' ';
1356 }
1357
1358 spaces[nspaces] = '\0';
1359
1360 while (t != NULL)
1361 {
1362 char *st = t;
1363 mstring_split (&st, &t, nextlen, &indent);
1364 fprintf (stream, "%s%s\n", spaces, st);
1365 }
1366
1367 sfree (spaces);
1368 }
1369 }
1370 }
1371 else
1372 {
28bf4b0b 1373 DPRINTF (("Here 1: [%s]", sc));
1374
abd7f895 1375 if (size_toInt (len) < (maxlen + maxlen - 1) && (strchr (s, '\n') != NULL))
616915dd 1376 {
1377 nspaces = ((maxlen + maxlen - 1) - len) / 2;
1378
1379 if (nspaces < 1) nspaces = 1;
1380
e5081f8c 1381 nextlen = size_toInt (maxlen - nspaces);
616915dd 1382
1383 mstring_split (&s, &t, maxlen, &indent);
1384
1385 fprintf (stream, "%s\n", s);
1386
1387 if (t != NULL)
1388 {
1389 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
1390 int i;
1391
abd7f895 1392 for (i = 0; i < size_toInt (nspaces); i++)
616915dd 1393 {
1394 spaces[i] = ' ';
1395 }
1396
1397 spaces[nspaces] = '\0';
1398
1399 while (t != NULL)
1400 {
1401 char *st = t;
1402
1403 mstring_split (&st, &t, nextlen, &indent);
1404 fprintf (stream, "%s%s\n", spaces, st);
1405 }
1406
1407 sfree (spaces);
1408 }
1409 }
1410 else
1411 {
1412 nspaces = 4;
e5081f8c 1413 nextlen = size_toInt (maxlen - nspaces);
616915dd 1414
28bf4b0b 1415 DPRINTF (("Here 2: [%s]", s));
616915dd 1416 mstring_split (&s, &t, maxlen, &indent);
28bf4b0b 1417 DPRINTF (("Here 3: [%s] [%s]", s, t));
616915dd 1418
1419 fprintf (stream, "%s\n", s);
1420
1421 if (t != NULL)
1422 {
1423 char *spaces = (char *) dmalloc ((nspaces + 1) * sizeof (*spaces));
abd7f895 1424 size_t i;
616915dd 1425
1426 for (i = 0; i < nspaces; i++)
1427 {
1428 spaces[i] = ' ';
1429 }
1430
1431 spaces[nspaces] = '\0';
1432
1433 while (t != NULL)
1434 {
1435 char *st = t;
28bf4b0b 1436 DPRINTF (("Loop: [%s]", t));
616915dd 1437 mstring_split (&st, &t, nextlen, &indent);
28bf4b0b 1438 DPRINTF (("Split: [%s] [%s]", st, t));
616915dd 1439 fprintf (stream, "%s%s\n", spaces, st);
28bf4b0b 1440 DPRINTF (("Next..."));
616915dd 1441 }
1442
1443 sfree (spaces);
1444 }
1445 }
1446 }
1447
28bf4b0b 1448 DPRINTF (("Done"));
616915dd 1449 sfree (os);
1450}
1451
1452void
28bf4b0b 1453xllfatalbug (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1454{
1455 prepareMessage ();
80489f0a 1456 printError (g_errorstream, message ("%q: *** Fatal bug: %q",
1457 fileloc_unparse (g_currentloc), s));
28bf4b0b 1458 showSourceLoc (srcFile, srcLine);
616915dd 1459 printCodePoint ();
1460 printBugReport ();
1461 llexit (LLFAILURE);
1462}
1463
616915dd 1464void
1465lclfatalbug (char *msg)
1466{
1467 prepareMessage ();
80489f0a 1468 printError (g_errorstream,
616915dd 1469 message ("*** Fatal Bug: %s", cstring_fromChars (msg)));
1470 printCodePoint ();
1471 printBugReport ();
1472 llexit (LLFAILURE);
1473}
616915dd 1474
1475void
1476checkParseError (void)
1477{
1478 if (fileloc_withinLines (lastparseerror, g_currentloc, 10))
1479 {
1480 llfatalerror (message ("%q: Cannot recover from parse error.",
1481 fileloc_unparse (g_currentloc)));
1482 }
1483}
1484
1485void llbugaux (cstring file, int line, /*@only@*/ cstring s)
1486{
1487 /*@unchecked@*/
1488 static int numbugs = 0;
1489 static bool inbug = FALSE;
1490
909cf5eb 1491 context_recordBug ();
1492
616915dd 1493 if (inbug)
1494 {
1495 cstring temps = fileloc_unparseRaw (file, line);
1496
80489f0a 1497 fprintf (g_errorstream,
1498 "%s: Recursive bug detected: %s\n",
616915dd 1499 cstring_toCharsSafe (temps),
1500 cstring_toCharsSafe (s));
1501 cstring_free (temps);
1502
1503 llexit (LLFAILURE);
1504 }
1505
1506 inbug = TRUE;
1507
1508 prepareMessage ();
1509
616915dd 1510 if (fileloc_withinLines (lastparseerror, g_currentloc, 7))
1511 {
1512 llfatalerror (message ("%q: Cannot recover from parse error.",
1513 fileloc_unparse (g_currentloc)));
1514 }
1515
80489f0a 1516 (void) fflush (g_warningstream);
abd7f895 1517
80489f0a 1518 printError (g_errorstream,
1519 message ("%q: *** Internal Bug at %q: %q [errno: %d]",
1520 fileloc_unparse (g_currentloc),
1521 fileloc_unparseRaw (file, line),
1522 s, errno));
1523
abd7f895 1524 /* printCodePoint (); no longer useful */
616915dd 1525
80489f0a 1526 llflush ();
1527
6483a926 1528 /*
1529 ** This is confusing, and hardly ever useful.
1530
3120b462 1531 if (errno != 0)
1532 {
1533 perror ("Possible system error diagnostic: ");
1534 }
abd7f895 1535
6483a926 1536 **
1537 */
1538
616915dd 1539 printBugReport ();
80489f0a 1540 llflush ();
616915dd 1541
1542 numbugs++;
1543
28bf4b0b 1544 if (numbugs > context_getBugsLimit () && fileloc_withinLines (lastbug, g_currentloc, 2))
616915dd 1545 {
80489f0a 1546 llfatalerror
1547 (message ("%q: Cannot recover from last bug. "
1548 "(If you really want Splint to try to continue, use -bugslimit <n>.)",
1549 fileloc_unparse (g_currentloc)));
616915dd 1550 }
28bf4b0b 1551
80489f0a 1552 fprintf (g_errorstream, " (attempting to continue, results may be incorrect)\n");
616915dd 1553 fileloc_free (lastbug);
1554 lastbug = fileloc_copy (g_currentloc);
1555 closeMessage ();
616915dd 1556 inbug = FALSE;
1557}
1558
616915dd 1559void
1560lclbug (/*@only@*/ cstring s)
1561{
1562 prepareMessage ();
80489f0a 1563 printError (g_errorstream, message ("*** Internal Bug: %q", s));
616915dd 1564 printCodePoint ();
1565 printBugReport ();
80489f0a 1566 fprintf (g_errorstream, " (attempting to continue, results may be incorrect)\n");
616915dd 1567 closeMessage ();
1568}
616915dd 1569
1570void
01a8227e 1571xllfatalerror (char *srcFile, int srcLine, cstring s)
616915dd 1572{
1573 prepareMessage ();
80489f0a 1574 printError (g_errorstream, s);
1575 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
01a8227e 1576 showSourceLoc (srcFile, srcLine);
616915dd 1577 llexit (LLFAILURE);
1578}
1579
1580void
01a8227e 1581xllfatalerrorLoc (char *srcFile, int srcLine, /*@only@*/ cstring s)
616915dd 1582{
1583 prepareMessage ();
80489f0a 1584 (void) fflush (g_warningstream);
1585 printError (g_errorstream, message ("%q: %q", fileloc_unparse (g_currentloc), s));
1586 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue."));
01a8227e 1587 showSourceLoc (srcFile, srcLine);
80489f0a 1588 (void) fflush (g_warningstream);
616915dd 1589 llexit (LLFAILURE);
1590}
1591
616915dd 1592bool
1593lclHadError (void)
1594{
517a2db3 1595 return (s_lclerrors > 0);
616915dd 1596}
1597
1598bool
1599lclHadNewError (void)
1600{
1601 static int lastcall = 0;
1602
517a2db3 1603 if (s_lclerrors > lastcall)
616915dd 1604 {
517a2db3 1605 lastcall = s_lclerrors;
616915dd 1606 return TRUE;
1607 }
1608 else
1609 {
1610 return FALSE;
1611 }
1612}
1613
1614int
1615lclNumberErrors (void)
1616{
517a2db3 1617 return (s_lclerrors);
616915dd 1618}
1619
1620void
28bf4b0b 1621xlclerror (char *srcFile, int srcLine, ltoken t, /*@only@*/ cstring msg)
616915dd 1622{
517a2db3 1623 s_lclerrors++;
616915dd 1624
1625 if (ltoken_getCode (t) != NOTTOKEN)
1626 {
1627 cstring loc = ltoken_unparseLoc (t);
517a2db3 1628 s_lastfileloclen = cstring_length (loc);
616915dd 1629
80489f0a 1630 printError (g_warningstream, message ("%q: %q", loc, msg));
28bf4b0b 1631 showSourceLoc (srcFile, srcLine);
616915dd 1632 }
1633 else
1634 {
80489f0a 1635 printError (g_warningstream, msg);
28bf4b0b 1636 showSourceLoc (srcFile, srcLine);
616915dd 1637 }
1638}
1639
1640void
1641lclplainerror (/*@only@*/ cstring msg)
1642{
517a2db3 1643 s_lclerrors++;
80489f0a 1644 printError (g_warningstream, msg);
616915dd 1645}
1646
1647void
1648lclfatalerror (ltoken t, /*@only@*/ cstring msg)
1649{
80489f0a 1650 if (ltoken_getCode (t) != NOTTOKEN)
1651 {
1652 cstring loc = ltoken_unparseLoc (t);
517a2db3 1653 s_lastfileloclen = cstring_length (loc);
80489f0a 1654 printError (g_errorstream, message ("%q: %q", loc, msg));
1655 }
1656 else
1657 {
1658 printError (g_errorstream, msg);
1659 }
1660
1661 printError (g_errorstream, cstring_makeLiteral ("*** Cannot continue"));
616915dd 1662 llexit (LLFAILURE);
1663}
1664
1665void
1666lclplainfatalerror (/*@only@*/ cstring msg)
1667{
80489f0a 1668 (void) fflush (g_warningstream);
1669 printError (g_errorstream, message ("*** Cannot continue: %q", msg));
616915dd 1670 llexit (LLFAILURE);
1671}
1672
1673void
1674lclRedeclarationError (ltoken id)
1675{
1676 cstring s = ltoken_getRawString (id);
1677
1678
1679 if (usymtab_existsEither (s))
1680 {
1681 uentry le = usymtab_lookupEither (s);
1682
1683 lclerror (id, message ("Respecification of %s", s));
1684 llgenindentmsg (message ("Previous specification of %q",
1685 uentry_getName (le)),
1686 uentry_whereSpecified (le));
1687 }
1688 else
1689 {
1690 lclerror (id, message ("Identifier redeclared: %s", s));
1691 }
1692}
616915dd 1693
1694void genppllerror (flagcode code, /*@only@*/ cstring s)
1695{
1696 if (context_inSuppressZone (g_currentloc))
1697 {
1698 cstring_free (s);
1699 }
1700 else
1701 {
1702 if (context_getFlag (code))
1703 {
517a2db3 1704 if (s_scanOpen)
616915dd 1705 {
80489f0a 1706 displayScanClose ();
616915dd 1707 }
1708
1709 llerror (code, s);
1710
1711 if (code != FLG_PREPROC)
1712 {
1713 llsuppresshint ('-', code);
1714 }
1715
80489f0a 1716 if (!context_isInCommandLine ())
616915dd 1717 {
80489f0a 1718 displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
616915dd 1719 }
1720 }
1721 else
1722 {
1723 cstring_free (s);
1724 }
1725 }
1726}
1727
1728void genppllerrorhint (flagcode code, /*@only@*/ cstring s,
1729 /*@only@*/ cstring hint)
1730{
1731 if (context_inSuppressZone (g_currentloc))
1732 {
1733 cstring_free (s);
1734 cstring_free (hint);
1735 }
1736 else
1737 {
1738 if (context_getFlag (code))
1739 {
53306cab 1740 generateCSV (code, s, hint, g_currentloc);
616915dd 1741 prepareMessage ();
1742 context_clearPreprocessing ();
1743 llerror (code, s);
1744 llgenhint (hint);
1745 context_setPreprocessing ();
1746 closeMessage ();
1747 }
1748 else
1749 {
1750 cstring_free (s);
1751 cstring_free (hint);
1752 }
1753 }
1754}
1755
1756void ppllerror (/*@only@*/ cstring s)
1757{
1758 genppllerror (FLG_PREPROC, s);
1759}
1760
1761void pplldiagmsg (cstring s)
1762{
80489f0a 1763 if (!context_isInCommandLine ())
616915dd 1764 {
517a2db3 1765 if (s_scanOpen)
1766 {
1767 displayScanClose ();
1768 }
1769
616915dd 1770 lldiagmsg (s);
80489f0a 1771 displayScanOpen (cstring_makeLiteral ("< more preprocessing ."));
616915dd 1772 }
1773 else
1774 {
1775 lldiagmsg (s);
1776 }
1777}
1778
1779void loadllmsg (cstring s)
1780{
80489f0a 1781 displayScanClose ();
1782 lldiagmsg (s);
1783 displayScanOpen (cstring_makeLiteral ("< ."));
616915dd 1784}
1785
1786static void llreportparseerror (/*@only@*/ cstring s)
1787{
1788 if (fileloc_withinLines (lastparseerror, g_currentloc, 5))
1789 {
1790 cstring_free (s);
1791 }
1792 else
1793 {
1794 llerror (FLG_SYNTAX, s);
1795
1796 fileloc_free (lastparseerror);
1797 lastparseerror = fileloc_copy (g_currentloc);
1798 }
1799}
1800
b072092f 1801bool xcppoptgenerror (char *srcFile, int srcLine,
1802 flagcode o,
1803 /*@only@*/ cstring s,
1804 cppReader *pfile)
1805{
1806 bool res = FALSE;
1807 fileloc loc = cppReader_getLoc (pfile);
1808
1809 if (context_flagOn (o, loc))
1810 {
1811 if (xlloptgenerror (srcFile, srcLine, o, s, loc))
1812 {
1813 cppReader_printContainingFiles (pfile);
1814 res = TRUE;
1815 }
1816 }
1817 else
1818 {
1819 cstring_free (s);
1820 }
1821
1822 fileloc_free (loc);
1823
1824 return res;
1825}
1826
28bf4b0b 1827bool xlloptgenerror (char *srcFile, int srcLine,
1828 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1829{
28bf4b0b 1830 DPRINTF (("xllopt: %s", s));
1831
53306cab 1832 if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
616915dd 1833 {
28bf4b0b 1834 DPRINTF (("Here we are!"));
616915dd 1835 llsuppresshint ('-', o);
1836 closeMessage ();
1837 flagcode_recordError (o);
1838 return TRUE;
1839 }
28bf4b0b 1840 else
1841 {
1842 DPRINTF (("Suppressed!"));
1843 flagcode_recordSuppressed (o);
1844 return FALSE;
1845 }
616915dd 1846}
1847
28bf4b0b 1848bool xoptgenerror2 (char *srcFile, int srcLine,
1849 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1850{
1851 if (context_suppressFlagMsg (f1, loc))
1852 {
1853 flagcode_recordSuppressed (f1);
1854 cstring_free (s);
1855 }
1856 else
1857 {
1858 if (context_suppressFlagMsg (f2, loc))
1859 {
1860 flagcode_recordSuppressed (f2);
1861 cstring_free (s);
1862 }
1863 else
1864 {
53306cab 1865 if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f1), loc))
616915dd 1866 {
28bf4b0b 1867 llsuppresshint2 ('-', f1, f2);
616915dd 1868 flagcode_recordError (f2);
1869 closeMessage ();
1870 return TRUE;
1871 }
28bf4b0b 1872 else
1873 {
1874 flagcode_recordSuppressed (f2);
1875 }
616915dd 1876 }
1877 }
28bf4b0b 1878
616915dd 1879 return FALSE;
1880}
1881
28bf4b0b 1882bool xoptgenerror2n (char *srcFile, int srcLine,
1883 flagcode f1, flagcode f2, /*@only@*/ cstring s, fileloc loc)
616915dd 1884{
1885
1886 if (context_suppressFlagMsg (f1, loc))
1887 {
1888 flagcode_recordSuppressed (f1);
1889 cstring_free (s);
1890 }
1891 else
1892 {
1893 if (context_suppressNotFlagMsg (f2, loc))
1894 {
1895 flagcode_recordSuppressed (f2);
1896 cstring_free (s);
1897 }
1898 else
1899 {
53306cab 1900 if (llrealerror (f1, srcFile, srcLine, s, flagcodeHint (f2), loc))
616915dd 1901 {
1902 llsuppresshint ('+', f2);
1903 flagcode_recordError (f2);
1904 closeMessage ();
1905 return TRUE;
1906 }
1907
1908 flagcode_recordSuppressed (f2);
1909 }
1910 }
1911 return FALSE;
1912}
1913
28bf4b0b 1914bool xllnoptgenerror (char *srcFile, int srcLine,
1915 flagcode o, /*@only@*/ cstring s, fileloc loc)
616915dd 1916{
53306cab 1917 if (llrealerror (o, srcFile, srcLine, s, flagcodeHint (o), loc))
616915dd 1918 {
1919 llsuppresshint ('+', o);
1920 flagcode_recordError (o);
1921 closeMessage ();
1922 return TRUE;
1923 }
1924
1925 flagcode_recordSuppressed (o);
1926 return FALSE;
1927}
1928
01a8227e 1929void xllparseerror (char *srcFile, int srcLine, cstring s)
616915dd 1930{
1931 if (context_getFlag (FLG_TRYTORECOVER))
1932 {
1933 parseerrorcount++;
1934
1935 if (parseerrorcount > GIVEUPPARSE)
1936 {
1937 if (cstring_isDefined (s))
1938 {
01a8227e 1939 xllfatalerror (srcFile, srcLine,
1940 message ("%q: Parse Error: %q. "
1941 "Too many errors, giving up.",
1942 fileloc_unparse (g_currentloc), s));
616915dd 1943 }
1944 else
1945 {
01a8227e 1946 xllfatalerror (srcFile, srcLine,
1947 message ("%q: Parse Error. Too many errors, giving up.",
1948 fileloc_unparse (g_currentloc)));
616915dd 1949 }
1950 }
1951 else
1952 {
1953 if (cstring_isDefined (s))
1954 {
1955 llreportparseerror (message ("Parse Error: %q. Attempting to continue.",
1956 s));
01a8227e 1957 showSourceLoc (srcFile, srcLine);
616915dd 1958 }
1959 else
1960 {
1961 llreportparseerror (message ("Parse Error. Attempting to continue."));
01a8227e 1962 showSourceLoc (srcFile, srcLine);
616915dd 1963 }
1964 }
1965 }
1966 else
1967 {
1968 cstring msg;
1969
1970 if (cstring_isDefined (s))
1971 {
1972 msg = message ("Parse Error: %q.", s);
1973 }
1974 else
1975 {
1976 msg = message ("Parse Error.");
1977 }
1978
01a8227e 1979 xllfatalerror
1980 (srcFile, srcLine,
1981 message ("%q: %s (For help on parse errors, "
1b8ae690 1982 "see splint -help parseerrors.)",
616915dd 1983 fileloc_unparse (g_currentloc), msg));
1984 }
1985}
1986
28bf4b0b 1987bool xfsgenerror (char *srcFile, int srcLine,
53306cab 1988 flagSpec fs, /*@only@*/ cstring s, fileloc fl)
28bf4b0b 1989{
1990 if (flagSpec_isOn (fs, fl))
1991 {
53306cab 1992 flagcode firston = flagSpec_getFirstOn (fs, fl);
1993
1994 if (llgenerroraux (firston, srcFile, srcLine, s,
1995 flagcodeHint (firston),
1996 fl, TRUE, FALSE))
28bf4b0b 1997 {
53306cab 1998 llsuppresshint ('-', firston);
1999 flagcode_recordError (firston);
28bf4b0b 2000 return TRUE;
2001 }
2002 else
2003 {
53306cab 2004 flagcode_recordSuppressed (firston);
28bf4b0b 2005 return FALSE;
2006 }
2007 }
2008 else
2009 {
2010 flagcode_recordSuppressed (flagSpec_getDominant (fs));
2011 cstring_free (s);
2012 return FALSE;
2013 }
2014}
2015
616915dd 2016bool doCheck (bool x, cstring pred, cstring file, int line)
2017{
2018 if (!x) {
2019 llbug (message ("%q: Check Failed: %s",
2020 fileloc_unparseRaw (file, line),
2021 pred));
2022 }
2023
2024 return x;
2025}
2026
2027/*@observer@*/ cstring lldecodeerror (/*@unused@*/ int errnum)
2028{
2029 char *result;
2030
2031#ifndef VMS
2032#ifndef HAVE_STRERROR
2033 result = NULL;
2034#else
2035 result = strerror (errnum);
2036#endif
2037#else /* VMS */
2038 /* VAXCRTL's strerror() takes an optional second argument, which only
2039 matters when the first argument is EVMSERR. However, it's simplest
2040 just to pass it unconditionally. `vaxc$errno' is declared in
2041 <errno.h>, and maintained by the library in parallel with `errno'.
2042 We assume that caller's `errnum' either matches the last setting of
2043 `errno' by the library or else does not have the value `EVMSERR'. */
2044
2045 result = strerror (errnum, vaxc$errno);
2046#endif
2047
2048 if (result == NULL)
2049 {
2050 result = cstring_toCharsSafe (message ("undocumented I/O error: %d", errnum));
2051 }
2052
2053 return cstring_fromChars (result);
2054}
2055
2056void llquietbugaux (cstring s, /*@unused@*/ cstring file, /*@unused@*/ int line)
2057{
2058# if 0
2059# ifdef HOMEVERSION
2060 llflush ();
80489f0a 2061 printError (g_errorstream, message ("%q: *** Internal Bug at %q: %q [errno: %d]",
2062 fileloc_unparse (g_currentloc),
2063 fileloc_unparseRaw (file, line),
2064 s, errno));
616915dd 2065 printCodePoint ();
2066 llflush ();
2067# endif
2068# else
2069 cstring_free (s);
2070# endif
2071}
2072
2073void llflush (void)
2074{
80489f0a 2075 (void) fflush (g_warningstream);
2076 (void) fflush (g_messagestream);
2077}
2078
80489f0a 2079void displayScan (cstring msg)
2080{
ce7034f0 2081 if (s_scanOpen)
2082 {
2083 displayScanClose ();
2084 }
2085
80489f0a 2086 llassert (!s_scanOpen);
2087
2088 if (context_getFlag (FLG_SHOWSCAN))
2089 {
ce7034f0 2090 showHerald ();
80489f0a 2091 fprintf (g_messagestream, "< %s >\n", cstring_toCharsSafe (msg));
2092 (void) fflush (g_messagestream);
2093 }
2094
2095 cstring_free (msg);
2096}
2097
2098void displayScanOpen (cstring msg)
2099{
ce7034f0 2100 if (s_scanOpen)
2101 {
2102 displayScanClose ();
2103 }
2104
80489f0a 2105 llassert (!s_scanOpen);
2106 s_scanOpen = TRUE;
2107
2108 if (context_getFlag (FLG_SHOWSCAN))
2109 {
2110 fprintf (g_messagestream, "< %s", cstring_toCharsSafe (msg));
2111 (void) fflush (g_messagestream);
2112 }
2113
2114 cstring_free (msg);
2115}
2116
2117void displayScanContinue (/*@temp@*/ cstring msg)
2118{
2119 if (context_getFlag (FLG_SHOWSCAN))
2120 {
6483a926 2121 if (s_scanOpen)
2122 {
2123 fprintf (g_messagestream, "%s", cstring_toCharsSafe (msg));
2124 (void) fflush (g_messagestream);
2125 }
2126 else
2127 {
2128 /*
2129 ** Don't call bug recursively
2130 */
2131
2132 fprintf (stderr, "*** Bug: scan continue scan not open\n");
2133 }
80489f0a 2134 }
2135}
2136
2137void displayScanClose (void)
2138{
6483a926 2139 if (s_scanOpen)
80489f0a 2140 {
6483a926 2141 if (context_getFlag (FLG_SHOWSCAN))
2142 {
2143 fprintf (g_messagestream, " >\n");
2144 (void) fflush (g_messagestream);
2145 }
80489f0a 2146 }
6483a926 2147 else
2148 {
2149 /*
2150 ** Don't call bug recursively
2151 */
2152
2153 fprintf (stderr, "*** Bug: scan close scan not open\n");
2154 }
2155
80489f0a 2156 s_scanOpen = FALSE;
616915dd 2157}
80489f0a 2158
2159
This page took 0.39432 seconds and 5 git commands to generate.