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 lclint: lclint-request@cs.virginia.edu
21 ** To report a bug: lclint-bug@cs.virginia.edu
22 ** For more information: http://www.splint.org
27 ** routines for loading and creating library files
29 ** this is a brute-force implementation, a more efficient
30 ** representation should be designed.
34 # include "lclintMacros.nf"
48 /*@-incondefs@*/ /*@-redecl@*/
49 extern /*:open:*/ /*@dependent@*/ FILE *yyin;
50 /*@=incondefs@*/ /*@=redecl@*/
52 /*@constant int NUMLIBS; @*/
55 /*@constant int NUMPOSIXLIBS; @*/
56 # define NUMPOSIXLIBS 18
58 static ob_mstring posixlibs[NUMPOSIXLIBS] =
69 "netinet/in", /* unix */
70 "sys/resource", /* unix */
71 "sys/socket", /* not posix */
72 "sys/syslog", /* not posix */
80 static ob_mstring stdlibs[NUMLIBS] =
101 static bool loadLCDFile (FILE * p_f, cstring p_name);
104 lcllib_isSkipHeader (cstring sname)
107 bool posixlib = FALSE;
112 llassert (cstring_isDefined (sname));
113 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
115 DPRINTF (("Include? %s", sname));
118 llassert (cstring_isDefined (xname));
119 libname = strrchr (xname, CONNECTCHAR);
133 if (mstring_equal (libname, "varargs"))
135 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
139 message ("Include file <%s.h> is inconsistent with "
140 "ANSI library (should use <stdarg.h>)",
141 cstring_fromChars (libname)),
145 cstring_free (xname);
149 if (context_getFlag (FLG_SKIPANSIHEADERS)
150 && context_usingAnsiLibrary ())
153 for (i = 0; i < NUMLIBS; i++)
155 if (mstring_equal (libname, stdlibs[i]))
163 for (i = 0; i < NUMPOSIXLIBS; i++)
165 if (strchr (posixlibs[i], CONNECTCHAR) != NULL)
169 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
171 if (ptr[strlen (posixlibs[i])] == '\0')
185 if (mstring_equal (libname, posixlibs[i]))
197 if (context_usingPosixLibrary ())
199 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
201 cstring_free (xname);
207 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
211 message ("Include file <%s.h> matches the name of a "
212 "POSIX library, but the POSIX library is "
213 "not being used. Consider using +posixlib "
214 "or +posixstrictlib to select the POSIX "
215 "library, or -warnposix "
216 "to suppress this message.",
217 cstring_fromChars (matchname)),
224 cstring_free (xname);
225 /*@noaccess cstring@*/
229 static void printDot (void)
231 if (context_getFlag (FLG_SHOWSCAN))
233 (void) fflush (g_msgstream);
234 fprintf (stderr, ".");
235 (void) fflush (stderr);
240 dumpState (cstring cfname)
243 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
245 f = fileTable_openFile (context_fileTable (), fname, "w");
247 if (context_getFlag (FLG_SHOWSCAN))
249 fprintf (stderr, "< Dumping to %s ", cstring_toCharsSafe (fname));
254 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
259 ** sequence is convulted --- must call usymtab_prepareDump before
260 ** dumping ctype table to convert type uid's
266 DPRINTF (("Before prepare dump:"));
268 DPRINTF (("Preparing dump..."));
271 usymtab_prepareDump ();
274 ** Be careful, these lines must match loadLCDFile checking.
277 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
278 fprintf (f, ";;%s\n", SPLINT_VERSION);
279 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
280 fprintf (f, ";;ctTable\n");
282 DPRINTF (("Dumping types..."));
287 DPRINTF (("Dumping type sets..."));
288 fprintf (f, ";;tistable\n");
289 typeIdSet_dumpTable (f);
292 DPRINTF (("Dumping usymtab..."));
293 fprintf (f, ";;symTable\n");
297 DPRINTF (("Dumping modules..."));
298 fprintf (f, ";; Modules access\n");
299 context_dumpModuleAccess (f);
300 fprintf (f, ";;End\n");
301 check (fileTable_closeFile (context_fileTable (), f));
304 if (context_getFlag (FLG_SHOWSCAN))
306 fprintf (g_msgstream, " >\n");
309 cstring_free (fname);
318 cstring libname = fileLib_addExtension (context_selectedLibrary (),
319 cstring_makeLiteralTemp (DUMP_SUFFIX));
321 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
323 lldiagmsg (message ("Cannot find %sstandard library: %s",
324 cstring_makeLiteralTemp
325 (context_getFlag (FLG_STRICTLIB) ? "strict "
326 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
328 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
333 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
337 lldiagmsg (message ("Cannot read standard library: %s",
339 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
345 if (context_getFlag (FLG_WHICHLIB))
347 char *t = mstring_create (MAX_NAME_LENGTH);
350 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
352 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
355 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
357 if (*t == ';' && *(t + 1) == ';')
365 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
372 tt = strrchr (t, '\n');
376 lldiagmsg (message ("Standard library: %s", fpath));
377 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
382 check (fileTable_closeFile (context_fileTable (), stdlib));
383 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
386 llassert (stdlib != NULL);
388 fileloc_reallyFree (g_currentloc);
389 g_currentloc = fileloc_createLib (libname);
391 DPRINTF (("Loading: %s", fpath));
393 if (context_getDebug (FLG_SHOWSCAN))
395 fprintf (g_msgstream, "< loading standard library %s ",
396 cstring_toCharsSafe (fpath));
397 result = loadLCDFile (stdlib, fpath);
398 fprintf (g_msgstream, " >\n");
402 result = loadLCDFile (stdlib, fpath);
405 check (fileTable_closeFile (context_fileTable (), stdlib));
409 cstring_free (libname);
413 /*@constant int BUFLEN;@*/
417 loadLCDFile (FILE *f, cstring name)
422 ** Check version. Should be >= LCLINT_LIBVERSION
425 if (reader_readLine (f, buf, BUFLEN) == NULL
426 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
428 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
429 "to continue without library.", name));
433 if (reader_readLine (f, buf, BUFLEN) != NULL)
435 if (!mstring_equalPrefix (buf, ";;"))
437 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
438 "to continue without library.", name));
441 else if (mstring_equalPrefix (buf, ";;ctTable"))
443 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
444 "to continue anyway, but results may be incorrect. Rebuild "
445 "the library with this version of lclint.",
452 if (sscanf (buf, ";;Splint %f", &version) != 1
453 && (sscanf (buf, ";;LCLint %f", &version) != 1))
455 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
456 "number). Attempting "
457 "to continue without library.", name));
462 if ((LCLINT_LIBVERSION - version) >= FLT_EPSILON)
465 char *nl = strchr (buf, '\n');
469 vname = cstring_fromChars (buf + 9);
471 loadllmsg (message ("Load library %s is in obsolete LCLint library "
472 "format (version %s). Attempting "
473 "to continue anyway, but results may be incorrect. Rebuild "
474 "the library with this version of lclint.",
479 if (reader_readLine (f, buf, BUFLEN) == NULL)
481 loadllmsg (message ("Load library %s is not in Splint library "
482 "format (missing library code). Attempting "
483 "to continue without library.", name));
490 if (sscanf (buf, ";;lib:%d", &lib) != 1)
492 loadllmsg (message ("Load library %s is not in Splint library "
493 "format (missing library code). Attempting "
494 "to continue without library.", name));
499 flagcode code = (flagcode) lib;
501 if (flagcode_isLibraryFlag (code))
503 if (context_doMerge ())
505 context_setLibrary (code);
510 loadllmsg (message ("Load library %s has invalid library code (%s). "
511 "Attempting to continue without library.",
513 flagcode_unparse (code)));
525 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
526 "Attempting to continue without library.", name));
533 typeIdSet_loadTable (f);
539 context_loadModuleAccess (f);
546 ** load state from file created by dumpState
550 loadState (cstring cfname)
553 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
555 f = fileTable_openFile (context_fileTable (), fname, "r");
559 if (context_getDebug (FLG_SHOWSCAN))
560 fprintf (g_msgstream, " >\n");
562 llfatalerror (message ("Cannot open dump file for loading: %s",
567 fileloc_reallyFree (g_currentloc);
568 g_currentloc = fileloc_createLib (cfname);
570 if (!loadLCDFile (f, cfname))
572 if (!loadStandardState ())
578 check (fileTable_closeFile (context_fileTable (), f));
581 /* usymtab_printAll (); */
582 cstring_free (fname);