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
27 ** routines for loading and creating library files
29 ** this is a brute-force implementation, a more efficient
30 ** representation should be designed.
36 * - fixed the recognition of Posix headers for OS/2
39 # include "splintMacros.nf"
53 /*@-incondefs@*/ /*@-redecl@*/
54 extern /*:open:*/ /*@dependent@*/ FILE *yyin;
55 /*@=incondefs@*/ /*@=redecl@*/
57 /*@constant int NUMLIBS; @*/
60 /*@constant int NUMPOSIXLIBS; @*/
61 # define NUMPOSIXLIBS 18
63 static ob_mstring posixlibs[NUMPOSIXLIBS] =
74 "netinet/in", /* unix */
75 "sys/resource", /* unix */
76 "sys/socket", /* not posix */
77 "sys/syslog", /* not posix */
85 static ob_mstring stdlibs[NUMLIBS] =
107 "strings", /* some systems use this...they shouldn't */
114 static bool loadLCDFile (FILE * p_f, cstring p_name);
117 lcllib_isSkipHeader (cstring sname)
120 bool posixlib = FALSE;
125 llassert (cstring_isDefined (sname));
126 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
128 DPRINTF (("Include? %s", sname));
131 llassert (cstring_isDefined (xname));
134 /* Posixlibs use forward slashes, so we use them here, too */
135 cstring_replaceAll (xname, '\\', '/');
136 libname = strrchr (xname, '/');
137 DPRINTF (("libname: %s", libname));
140 libname = strrchr (xname, CONNECTCHAR);
155 if (mstring_equal (libname, "varargs"))
157 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
161 message ("Include file <%s.h> is inconsistent with "
162 "ANSI library (should use <stdarg.h>)",
163 cstring_fromChars (libname)),
167 cstring_free (xname);
171 if (context_getFlag (FLG_SKIPISOHEADERS)
172 && context_usingAnsiLibrary ())
175 for (i = 0; i < NUMLIBS; i++)
177 if (mstring_equal (libname, stdlibs[i]))
185 for (i = 0; i < NUMPOSIXLIBS; i++)
187 if (strchr (posixlibs[i], CONNECTCHAR) != NULL
189 || strchr (posixlibs[i], ALTCONNECTCHAR) != NULL
195 DPRINTF (("xname: %s, posix: %s", xname, posixlibs[i]));
196 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
198 if (ptr[strlen (posixlibs[i])] == '\0')
212 if (mstring_equal (libname, posixlibs[i]))
224 if (context_usingPosixLibrary ())
226 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
228 cstring_free (xname);
229 return TRUE; /* evans 2002-03-02: investigate this warning */
234 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
238 message ("Include file <%s.h> matches the name of a "
239 "POSIX library, but the POSIX library is "
240 "not being used. Consider using +posixlib "
241 "or +posixstrictlib to select the POSIX "
242 "library, or -warnposix "
243 "to suppress this message.",
244 cstring_fromChars (matchname)),
251 cstring_free (xname);
252 /*@noaccess cstring@*/
256 static void printDot (void)
258 if (context_getFlag (FLG_SHOWSCAN))
260 (void) fflush (g_msgstream);
261 fprintf (stderr, ".");
262 (void) fflush (stderr);
267 dumpState (cstring cfname)
270 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
272 f = fileTable_openFile (context_fileTable (), fname, "w");
274 if (context_getFlag (FLG_SHOWSCAN))
276 fprintf (stderr, "< Dumping to %s ", cstring_toCharsSafe (fname));
281 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
286 ** sequence is convulted --- must call usymtab_prepareDump before
287 ** dumping ctype table to convert type uid's
293 DPRINTF (("Before prepare dump:"));
295 DPRINTF (("Preparing dump..."));
298 usymtab_prepareDump ();
301 ** Be careful, these lines must match loadLCDFile checking.
304 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
305 fprintf (f, ";;%s\n", SPLINT_VERSION);
306 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
307 fprintf (f, ";;ctTable\n");
309 DPRINTF (("Dumping types..."));
314 DPRINTF (("Dumping type sets..."));
315 fprintf (f, ";;tistable\n");
316 typeIdSet_dumpTable (f);
319 DPRINTF (("Dumping usymtab..."));
320 fprintf (f, ";;symTable\n");
324 DPRINTF (("Dumping modules..."));
325 fprintf (f, ";; Modules access\n");
326 context_dumpModuleAccess (f);
327 fprintf (f, ";;End\n");
328 check (fileTable_closeFile (context_fileTable (), f));
331 if (context_getFlag (FLG_SHOWSCAN))
333 fprintf (g_msgstream, " >\n");
336 cstring_free (fname);
345 cstring libname = fileLib_addExtension (context_selectedLibrary (),
346 cstring_makeLiteralTemp (DUMP_SUFFIX));
348 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
350 lldiagmsg (message ("Cannot find %sstandard library: %s",
351 cstring_makeLiteralTemp
352 (context_getFlag (FLG_STRICTLIB) ? "strict "
353 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
355 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
360 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
364 lldiagmsg (message ("Cannot read standard library: %s",
366 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
372 if (context_getFlag (FLG_WHICHLIB))
374 char *t = mstring_create (MAX_NAME_LENGTH);
377 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
379 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
382 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
384 if (*t == ';' && *(t + 1) == ';')
392 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
399 tt = strrchr (t, '\n');
403 lldiagmsg (message ("Standard library: %s", fpath));
404 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
409 check (fileTable_closeFile (context_fileTable (), stdlib));
410 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
413 llassert (stdlib != NULL);
415 fileloc_reallyFree (g_currentloc);
416 g_currentloc = fileloc_createLib (libname);
418 DPRINTF (("Loading: %s", fpath));
420 if (context_getDebug (FLG_SHOWSCAN))
422 fprintf (g_msgstream, "< loading standard library %s ",
423 cstring_toCharsSafe (fpath));
424 result = loadLCDFile (stdlib, fpath);
425 fprintf (g_msgstream, " >\n");
429 result = loadLCDFile (stdlib, fpath);
432 check (fileTable_closeFile (context_fileTable (), stdlib));
436 cstring_free (libname);
440 /*@constant int BUFLEN;@*/
444 loadLCDFile (FILE *f, cstring name)
449 ** Check version. Should be >= SPLINT_LIBVERSION
452 if (reader_readLine (f, buf, BUFLEN) == NULL
453 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
455 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
456 "to continue without library.", name));
460 if (reader_readLine (f, buf, BUFLEN) != NULL)
462 if (!mstring_equalPrefix (buf, ";;"))
464 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
465 "to continue without library.", name));
468 else if (mstring_equalPrefix (buf, ";;ctTable"))
470 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
471 "to continue anyway, but results may be incorrect. Rebuild "
472 "the library with this version of splint.",
479 if (sscanf (buf, ";;Splint %f", &version) != 1
480 && (sscanf (buf, ";;LCLint %f", &version) != 1))
482 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
483 "number). Attempting "
484 "to continue without library.", name));
489 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
492 char *nl = strchr (buf, '\n');
496 vname = cstring_fromChars (buf + 9);
498 loadllmsg (message ("Load library %s is in obsolete Splint library "
499 "format (version %s). Attempting "
500 "to continue anyway, but results may be incorrect. Rebuild "
501 "the library with this version of splint.",
506 if (reader_readLine (f, buf, BUFLEN) == NULL)
508 loadllmsg (message ("Load library %s is not in Splint library "
509 "format (missing library code). Attempting "
510 "to continue without library.", name));
517 if (sscanf (buf, ";;lib:%d", &lib) != 1)
519 loadllmsg (message ("Load library %s is not in Splint library "
520 "format (missing library code). Attempting "
521 "to continue without library.", name));
526 flagcode code = (flagcode) lib;
528 if (flagcode_isLibraryFlag (code))
530 if (context_doMerge ())
532 context_setLibrary (code);
537 loadllmsg (message ("Load library %s has invalid library code (%s). "
538 "Attempting to continue without library.",
540 flagcode_unparse (code)));
552 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
553 "Attempting to continue without library.", name));
560 typeIdSet_loadTable (f);
566 context_loadModuleAccess (f);
573 ** load state from file created by dumpState
577 loadState (cstring cfname)
580 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
582 f = fileTable_openFile (context_fileTable (), fname, "r");
586 if (context_getDebug (FLG_SHOWSCAN))
587 fprintf (g_msgstream, " >\n");
589 llfatalerror (message ("Cannot open dump file for loading: %s",
594 fileloc_reallyFree (g_currentloc);
595 g_currentloc = fileloc_createLib (cfname);
597 if (!loadLCDFile (f, cfname))
599 if (!loadStandardState ())
605 check (fileTable_closeFile (context_fileTable (), f));
608 /* usymtab_printAll (); */
609 cstring_free (fname);