2 ** Splint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2002 University of Virginia,
4 ** Massachusetts Institute of Technology
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.
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.
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.
20 ** For information on splint: info@splint.org
21 ** To report a bug: splint-bug@splint.org
22 ** For more information: http://www.splint.org
28 * Modified by Herbert 04/19/97:
29 * - added new include file portab.h.
30 * - added new private function fileloc_filenameForCpp() to handle
31 * filenames belonging to "#line" statements for OS/2 and MSDOS. It
32 * gets called by fileloc_lineMarker() and fileloc_previousLineMarker()
33 * instead of fileloc_unparseFilename().
36 # include "splintMacros.nf"
38 # include "fileIdList.h"
42 static /*@only@*/ fileloc fileloc_createPrim (flkind p_kind, fileId p_fid, int p_line, int p_col);
44 static flkind fileId_kind (fileId s)
46 cstring fname = fileTable_rootFileName (s);
48 if (fileLib_isLCLFile (fname))
52 else if (cstring_equalPrefix (fname, cstring_makeLiteralTemp (SYSTEM_LIBDIR)))
63 fileloc_decColumn (fileloc f, int x)
65 fileloc ret = fileloc_copy (f);
69 if (x > 0 && fileloc_isDefined (ret))
71 llassertprint (ret->column > x, ("decColumn: %d", x));
79 fileloc_noColumn (fileloc f)
81 if (fileloc_isDefined (f))
83 fileloc ret = fileloc_copy (f);
85 if (fileloc_isDefined (ret))
94 return fileloc_undefined;
99 fileloc_subColumn (fileloc f, int x)
101 if (x > 0 && fileloc_isDefined (f))
103 llassert (f->column > x);
108 fileloc fileloc_copy (fileloc f)
110 if (fileloc_isDefined (f))
112 if (fileloc_isBuiltin (f) || fileloc_isExternal (f))
115 ** Legitimate (spurious) errors reported since no copy
119 /*@i3@*/ return f; /* No copy is necessary. */
123 return (fileloc_createPrim (f->kind, f->fid, f->lineno, f->column));
128 return fileloc_undefined;
132 fileloc fileloc_update (/*@only@*/ fileloc old, fileloc fnew)
134 if (fileloc_isUndefined (fnew))
137 return fileloc_undefined;
139 else if (fileloc_isUndefined (old) || fileloc_isBuiltin (old) || fileloc_isExternal (old))
141 return (fileloc_copy (fnew));
145 old->kind = fnew->kind;
146 old->fid = fnew->fid;
147 old->lineno = fnew->lineno;
148 old->column = fnew->column;
154 fileloc fileloc_updateFileId (/*@only@*/ fileloc old, fileId s)
156 if (fileloc_isUndefined (old) || fileloc_isBuiltin (old) || fileloc_isExternal (old))
158 return (fileloc_create (s, 1, 1));
162 old->kind = fileId_kind (s);
172 fileloc_free (/*@only@*/ fileloc f)
174 if (fileloc_isDefined (f))
176 if (f != g_currentloc)
178 if (fileloc_isBuiltin (f) || fileloc_isExternal (f))
190 ; /* Don't free g_currentloc ever! */
197 fileloc_reallyFree (/*@only@*/ fileloc f)
199 if (fileloc_isDefined (f))
201 if (fileloc_isBuiltin (f) || fileloc_isExternal (f))
208 /*@-branchstate@*/ } /*@=branchstate@*/
212 /*drl added 04/16/2002 */
213 bool fileloc_canGetName (fileloc f)
215 if (fileloc_isValid(f) && (fileId_isValid (f->fid)) )
223 /*drl added 04/16/2002 */
224 cstring fileloc_getName (fileloc f)
228 if (! (fileloc_isValid(f) && (fileId_isValid (f->fid)) ) )
230 llcontbug(cstring_makeLiteral("fileloc_getName call with invalid fileloc and fileloc->id"));
231 return cstring_newEmpty();
234 // rootName = fileTable_getRootName (context_fileTable(), f->fid);
236 rootName = fileTable_fileName ( f->fid);
238 return cstring_copy(rootName);
243 cstring fileloc_getBase (fileloc f)
245 llassert (fileloc_isDefined (f));
247 return (fileTable_fileNameBase (f->fid));
251 fileloc_equal (fileloc f1, fileloc f2)
254 || (fileloc_isDefined (f1) && fileloc_isDefined (f2)
255 && ((f1->column == f2->column) &&
256 (f1->lineno == f2->lineno) && fileloc_sameFile (f1, f2))));
260 fileloc_compare (fileloc f1, fileloc f2)
262 if (fileloc_isUndefined (f1))
264 if (fileloc_isUndefined (f2)) return 0;
268 if (fileloc_isUndefined (f2))
272 INTCOMPARERETURN (f1->fid, f2->fid);
273 /*@noaccess fileId@*/
276 /* drl 8-11-01 fix what I think is a bug
277 lineno should more important than column number*/
279 INTCOMPARERETURN (f1->lineno, f2->lineno);
280 INTCOMPARERETURN (f1->column, f2->column);
286 fileloc_withinLines (fileloc f1, fileloc f2, int n)
289 return (fileloc_isDefined (f1) &&
290 fileloc_isDefined (f2) &&
291 ((f2->lineno <= f1->lineno + n)
292 && (f2->lineno >= f1->lineno)
293 && fileloc_sameFile (f1, f2)));
297 fileloc_lessthan (fileloc f1, fileloc f2)
300 return ((fileloc_isDefined (f1) && fileloc_isDefined (f2))
301 && ((f1->fid < f2->fid)
302 || ((f1->fid == f2->fid)
303 && ((f1->lineno < f2->lineno)
304 || ((f1->lineno == f2->lineno)
305 && (f1->column < f2->column))))));
310 ** returns true if f1 and f2 are different files,
311 ** or f1 is before f2 in same file
315 fileloc_notAfter (fileloc f1, fileloc f2)
318 return ((fileloc_isDefined (f1) && fileloc_isDefined (f2))
319 && ((f1->fid != f2->fid)
320 || ((f1->lineno < f2->lineno)
321 || ((f1->lineno == f2->lineno)
322 && (f1->column <= f2->column)))));
323 /*@noaccess fileId@*/
328 fileloc_isStandardLibrary (fileloc f)
330 cstring s = fileloc_getBase (f);
332 return (cstring_equalLit (s, LLSTDLIBS_NAME)
333 || cstring_equalLit (s, LLSTRICTLIBS_NAME)
334 || cstring_equalLit (s, LLUNIXLIBS_NAME)
335 || cstring_equalLit (s, LLUNIXSTRICTLIBS_NAME)
336 || cstring_equalLit (s, LLPOSIXSTRICTLIBS_NAME)
337 || cstring_equalLit (s, LLPOSIXLIBS_NAME));
342 fileloc_sameFileAndLine (fileloc f1, fileloc f2)
344 return (fileloc_sameFile (f1, f2)
345 && (fileloc_isDefined (f1) && fileloc_isDefined (f2)
346 && f1->lineno == f2->lineno));
350 fileloc_sameFile (fileloc f1, fileloc f2)
352 if ((fileloc_isUndefined (f1) || (fileloc_isUndefined (f2))
353 || (fileloc_isLib (f1)) || (fileloc_isLib (f2))))
359 return (fileId_equal (f1->fid, f2->fid));
364 fileloc_sameModule (fileloc f1, fileloc f2)
366 if (fileloc_isUndefined (f1))
368 return (fileloc_isUndefined (f2));
370 else if (fileloc_isUndefined (f2))
376 if (fileloc_isBuiltin (f1) || fileloc_isBuiltin (f2)
377 || fileloc_isExternal (f1) || fileloc_isExternal (f2))
379 return fileloc_sameFile (f1, f2);
383 cstring s1 = fileloc_getBase (f1);
384 cstring s2 = fileloc_getBase (f2);
386 return (cstring_equal (s1, s2));
392 fileloc_sameBaseFile (fileloc f1, fileloc f2)
394 if (fileloc_isUndefined (f1))
396 return (fileloc_isUndefined (f2));
398 else if (fileloc_isUndefined (f2))
404 return (fileId_baseEqual (f1->fid, f2->fid));
408 bool fileloc_isSystemFile (fileloc f1)
410 if (fileloc_isDefined (f1)
411 && !fileloc_isBuiltin (f1)
412 && !fileloc_isExternal (f1))
414 return (fileTable_isSystemFile (context_fileTable (), f1->fid));
420 bool fileloc_isXHFile (fileloc f1)
422 if (fileloc_isDefined (f1)
423 && !fileloc_isBuiltin (f1)
424 && !fileloc_isExternal (f1))
426 DPRINTF (("Fileloc is XH: [%p] %s", f1, fileloc_unparse (f1)));
427 return (fileTable_isXHFile (context_fileTable (), f1->fid));
434 fileloc_almostSameFile (fileloc f1, fileloc f2)
436 if ((fileloc_isUndefined (f1) || (fileloc_isUndefined (f2))
437 || (fileloc_isLib (f1)) || (fileloc_isLib (f2))))
443 if (fileId_baseEqual (f1->fid, f2->fid))
447 else if (fileTable_isSystemFile (context_fileTable (), f1->fid)
448 || fileTable_isSystemFile (context_fileTable (), f2->fid))
452 else if (fileTable_isSpecialFile (context_fileTable (), f1->fid)
453 || fileTable_isSpecialFile (context_fileTable (), f2->fid))
455 return (cstring_equal (fileloc_getBase (f1),
456 fileloc_getBase (f2)));
467 fileloc_fromTok (ltoken t)
469 cstring fname = ltoken_fileName (t);
470 fileId fid = fileTable_lookup (context_fileTable (), fname);
473 if (!fileId_isValid (fid))
475 fid = fileTable_addLCLFile (context_fileTable (), fname);
478 fl = fileloc_create (fid, (int) ltoken_getLine (t), (int) ltoken_getCol (t));
485 fileloc_createLib (cstring ln)
488 fileId fid = fileTable_lookup (context_fileTable (), ln);
490 if (!fileId_isValid (fid))
492 fid = fileTable_addLibraryFile (context_fileTable (), ln);
495 if (cstring_equalPrefix (ln, cstring_makeLiteralTemp (SYSTEM_LIBDIR)))
500 return (fileloc_createPrim (fk, fid, 0, 0));
503 fileloc fileloc_createRc (cstring name)
505 fileId fid = fileTable_addFile (context_fileTable (), name);
507 return (fileloc_createPrim (FL_RC, fid, 0, 0));
510 fileloc fileloc_createExternal (void)
512 /*@i@*/ return (fileloc_getExternal ());
515 fileloc fileloc_getExternal (void)
517 static /*@owned@*/ fileloc res = fileloc_undefined;
519 if (res == fileloc_undefined)
521 res = fileloc_createPrim (FL_EXTERNAL, fileId_invalid, 0, 0);
527 fileloc fileloc_observeBuiltin ()
529 /*@-onlytrans@*/ return (fileloc_getBuiltin ()); /*@=onlytrans@*/
532 fileloc fileloc_getBuiltin ()
534 static /*@owned@*/ fileloc res = fileloc_undefined;
536 if (res == fileloc_undefined)
538 res = fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0);
545 fileloc_makePreproc (fileloc loc)
547 if (fileloc_isDefined (loc))
549 return (fileloc_createPrim (FL_PREPROC, loc->fid,
550 loc->lineno, loc->column));
553 return (fileloc_createPrim (FL_PREPROC, fileId_invalid, 0, 0));
557 fileloc_makePreprocPrevious (fileloc loc)
559 if (fileloc_isDefined (loc))
563 return (fileloc_createPrim (FL_PREPROC, loc->fid,
564 loc->lineno - 1, 0));
568 return (fileloc_createPrim (FL_PREPROC, loc->fid,
573 return (fileloc_createPrim (FL_PREPROC, fileId_invalid, 0, 0));
577 fileloc_createBuiltin ()
579 return (fileloc_createPrim (FL_BUILTIN, fileId_invalid, 0, 0));
584 fileloc_createImport (cstring fname, int lineno)
586 fileId fid = fileTable_lookup (context_fileTable (), fname);
588 if (!fileId_isValid (fid))
590 fid = fileTable_addImportFile (context_fileTable (), fname);
593 return (fileloc_createPrim (FL_IMPORT, fid, lineno, 0));
597 static /*@only@*/ fileloc
598 fileloc_createPrim (flkind kind, fileId fid, int line, int col)
600 fileloc f = (fileloc) dmalloc (sizeof (*f));
607 DPRINTF (("Fileloc create: [%p] %s", f, fileloc_unparse (f)));
613 fileloc_createSpec (fileId fid, int line, int col)
615 return (fileloc_createPrim (FL_SPEC, fid, line, col));
619 fileloc fileloc_create (fileId fid, int line, int col)
621 return (fileloc_createPrim (fileId_kind (fid), fid, line, col));
624 /*@observer@*/ cstring
625 fileloc_filename (fileloc f)
627 return (fileloc_isDefined (f) ? fileTable_rootFileName (f->fid) : cstring_makeLiteralTemp ("<unknown>"));
630 /*@only@*/ cstring fileloc_outputFilename (fileloc f)
632 if (fileloc_isDefined (f))
634 return osd_outputPath (fileTable_rootFileName (f->fid));
638 return cstring_makeLiteral ("<unknown>");
643 fileloc_unparseFilename (fileloc f)
645 if (fileloc_isDefined (f))
650 return (message ("load file %q", fileloc_outputFilename (f)));
652 return (cstring_makeLiteral ("# builtin #"));
654 return (message ("import file %q", fileloc_outputFilename (f)));
656 return (cstring_makeLiteral ("<external>"));
658 return (fileloc_outputFilename (f));
661 return cstring_undefined;
665 fileloc_lineno (fileloc f)
667 return (fileloc_isDefined (f) ? f->lineno : -1);
671 fileloc_column (fileloc f)
673 return (fileloc_isDefined (f) ? f->column : -1);
677 fileloc_unparse (fileloc f)
679 bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT);
680 bool htmlFormat = context_getFlag (FLG_HTMLFILEFORMAT);
681 cstring res = cstring_undefined;
683 if (fileloc_isDefined (f))
688 return (cstring_makeLiteral ("Command Line"));
692 res = message ("import file %q(%d)", fileloc_outputFilename (f), f->lineno);
696 res = message ("import file %q:%d", fileloc_outputFilename (f), f->lineno);
703 res = message ("%q(%d)", fileloc_outputFilename (f), f->lineno);
707 res = message ("%q:%d", fileloc_outputFilename (f), f->lineno);
713 res = cstring_makeLiteral ("<external>");
719 if (f->kind == FL_LIB)
721 fname = message ("load file %q", fileloc_outputFilename (f));
725 fname = fileloc_outputFilename (f);
728 if (context_getFlag (FLG_SHOWCOL))
730 if (fileloc_linenoDefined (f))
732 if (fileloc_columnDefined (f))
736 res = message ("%q(%d,%d)", fname, f->lineno, f->column);
740 res = message ("%q:%d:%d", fname, f->lineno, f->column);
747 res = message ("%q(%d)", fname, f->lineno);
751 res = message ("%q:%d", fname, f->lineno);
760 else if (fileloc_linenoDefined (f))
764 res = message ("%q(%d)", fname, f->lineno);
768 res = message ("%q:%d", fname, f->lineno);
778 if (htmlFormat && fileloc_linenoDefined (f))
780 res = message ("<a href=\"#line%d\">%s</a>", f->lineno, res);
785 res = cstring_makeLiteral ("< Location unknown >");
792 fileloc_unparseRaw (cstring fname, int lineno)
794 if (!cstring_isEmpty (fname))
796 bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT);
800 return (message ("%q(%d)", osd_outputPath (fname), lineno));
804 return (message ("%q:%d", osd_outputPath (fname), lineno));
809 return cstring_makeLiteral ("Command Line");
814 fileloc_unparseRawCol (cstring fname, int lineno, int col)
816 if (!cstring_isEmpty (fname))
818 if (context_getFlag (FLG_SHOWCOL))
820 bool parenFormat = context_getFlag (FLG_PARENFILEFORMAT);
824 return (message ("%q(%d,%d)", osd_outputPath (fname), lineno, col));
828 return (message ("%q:%d:%d", osd_outputPath (fname), lineno, col));
833 return fileloc_unparseRaw (fname, lineno);
838 return cstring_makeLiteral ("Command Line");
842 bool fileloc_isSpecialFile (fileloc f)
844 if (fileloc_isDefined (f)
845 && fileId_isValid (f->fid))
847 return (fileTable_isSpecialFile (context_fileTable (), f->fid));
855 bool fileloc_isHeader (fileloc f)
857 /* returns true if is not a .c file */
859 return (fileloc_isDefined (f) && fileId_isValid (f->fid)
860 && fileId_isHeader (f->fid));
863 bool fileloc_isSpec (fileloc f)
865 return (fileloc_isDefined (f) &&
866 (f->kind == FL_LIB || f->kind == FL_STDLIB || f->kind == FL_SPEC));
869 bool fileloc_isRealSpec (fileloc f)
871 return (fileloc_isDefined (f) && (f->kind == FL_SPEC));
874 bool fileloc_isLib (fileloc f)
876 return (fileloc_isDefined (f)
877 && (f->kind == FL_LIB || f->kind == FL_STDHDR || f->kind == FL_STDLIB));
880 bool fileloc_isStandardLib (fileloc f)
882 return (fileloc_isDefined (f) && f->kind == FL_STDLIB);
885 /*@only@*/ cstring fileloc_unparseDirect (fileloc fl)
887 if (fileloc_isDefined (fl))
889 return (message ("%d:%d:%d",
890 /*@access fileId@*/ (int) fl->fid, /*@noaccess fileId@*/
891 fl->lineno, fl->column));
895 return (cstring_makeLiteral ("<undef>"));
899 bool fileloc_isUser (fileloc f)
901 return (fileloc_isDefined (f)
902 && f->kind == FL_NORMAL);
908 bool fileloc_isDotH (fileloc f)
912 if (! (fileloc_isValid(f) && (fileId_isValid (f->fid)) ) )
917 rootName = fileTable_getRootName (context_fileTable() , f->fid);
919 if (cstring_isDotH(rootName) )