2 ** LCLint - annotation-assisted static program checker
3 ** Copyright (C) 1994-2001 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://lclint.cs.virginia.edu
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"
51 /*@-incondefs@*/ /*@-redecl@*/
52 extern /*@open@*/ /*@dependent@*/ FILE *yyin;
53 /*@=incondefs@*/ /*@=redecl@*/
55 /*@constant int NUMLIBS; @*/
58 /*@constant int NUMPOSIXLIBS; @*/
59 # define NUMPOSIXLIBS 18
61 static ob_mstring posixlibs[NUMPOSIXLIBS] =
72 "netinet/in", /* unix */
73 "sys/resource", /* unix */
74 "sys/socket", /* not posix */
75 "sys/syslog", /* not posix */
83 static ob_mstring stdlibs[NUMLIBS] =
104 static bool loadLCDFile (FILE * p_f, cstring p_name);
107 lcllib_isSkipHeader (cstring sname)
110 bool posixlib = FALSE;
115 llassert (cstring_isDefined (sname));
116 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
118 DPRINTF (("Include? %s", sname));
121 llassert (cstring_isDefined (xname));
122 libname = strrchr (xname, CONNECTCHAR);
136 if (mstring_equal (libname, "varargs"))
138 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
142 message ("Include file <%s> is inconsistent with "
143 "ANSI library (should use <stdarg.h>)",
144 cstring_fromChars (libname)),
148 cstring_free (xname);
152 if (context_getFlag (FLG_SKIPANSIHEADERS)
153 && context_usingAnsiLibrary ())
156 for (i = 0; i < NUMLIBS; i++)
158 if (mstring_equal (libname, stdlibs[i]))
166 for (i = 0; i < NUMPOSIXLIBS; i++)
168 if (strchr (posixlibs[i], CONNECTCHAR) != NULL)
172 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
174 if (ptr[strlen (posixlibs[i])] == '\0')
188 if (mstring_equal (libname, posixlibs[i]))
200 if (context_usingPosixLibrary ())
202 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
204 cstring_free (xname);
210 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
214 message ("Include file <%s> matches the name of a "
215 "POSIX library, but the POSIX library is "
216 "not being used. Consider using +posixlib "
217 "or +posixstrictlib to select the POSIX "
218 "library, or -warnposix "
219 "to suppress this message.",
220 cstring_fromChars (matchname)),
227 cstring_free (xname);
228 /*@noaccess cstring@*/
232 static void printDot (void)
234 if (context_getFlag (FLG_SHOWSCAN))
236 (void) fflush (g_msgstream);
237 fprintf (stderr, ".");
238 (void) fflush (stderr);
243 dumpState (cstring cfname)
246 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
248 f = fopen (cstring_toCharsSafe (fname), "w");
250 if (context_getFlag (FLG_SHOWSCAN))
252 fprintf (stderr, "< Dumping to %s ", cstring_toCharsSafe (fname));
257 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
262 ** sequence is convulted --- must call usymtab_prepareDump before
263 ** dumping ctype table to convert type uid's
269 DPRINTF (("Before prepare dump:"));
271 DPRINTF (("Preparing dump..."));
274 usymtab_prepareDump ();
277 ** Be careful, these lines must match loadLCDFile checking.
280 fprintf (f, ";;LCLint Dump: %s\n", cstring_toCharsSafe (fname));
281 fprintf (f, ";;%s\n", LCL_VERSION);
282 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
283 fprintf (f, ";;ctTable\n");
285 DPRINTF (("Dumping types..."));
290 DPRINTF (("Dumping type sets..."));
291 fprintf (f, ";;tistable\n");
292 typeIdSet_dumpTable (f);
295 DPRINTF (("Dumping usymtab..."));
296 fprintf (f, ";;symTable\n");
300 DPRINTF (("Dumping modules..."));
301 fprintf (f, ";; Modules access\n");
302 context_dumpModuleAccess (f);
303 fprintf (f, ";;End\n");
304 check (fclose (f) == 0);
307 if (context_getFlag (FLG_SHOWSCAN))
309 fprintf (g_msgstream, " >\n");
312 cstring_free (fname);
321 cstring libname = fileLib_addExtension (context_selectedLibrary (),
322 cstring_makeLiteralTemp (DUMP_SUFFIX));
324 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
326 lldiagmsg (message ("Cannot find %sstandard library: %s",
327 cstring_makeLiteralTemp
328 (context_getFlag (FLG_STRICTLIB) ? "strict "
329 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
331 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
336 stdlib = fopen (cstring_toCharsSafe (fpath), "r");
340 lldiagmsg (message ("Cannot read standard library: %s",
342 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
348 if (context_getFlag (FLG_WHICHLIB))
350 char *t = mstring_create (MAX_NAME_LENGTH);
353 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
355 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
358 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
360 if (*t == ';' && *(t + 1) == ';')
368 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
375 tt = strrchr (t, '\n');
379 lldiagmsg (message ("Standard library: %s", fpath));
380 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
385 check (fclose (stdlib) == 0);
386 stdlib = fopen (cstring_toCharsSafe (fpath), "r");
389 llassert (stdlib != NULL);
391 fileloc_reallyFree (g_currentloc);
392 g_currentloc = fileloc_createLib (libname);
394 DPRINTF (("Loading: %s", fpath));
396 if (context_getDebug (FLG_SHOWSCAN))
398 fprintf (g_msgstream, "< loading standard library %s ",
399 cstring_toCharsSafe (fpath));
400 result = loadLCDFile (stdlib, fpath);
401 fprintf (g_msgstream, " >\n");
405 result = loadLCDFile (stdlib, fpath);
408 check (fclose (stdlib) == 0);
412 cstring_free (libname);
416 /*@constant int BUFLEN;@*/
420 loadLCDFile (FILE *f, cstring name)
425 ** Check version. Should be >= LCLINT_LIBVERSION
428 if (reader_readLine (f, buf, BUFLEN) == NULL
429 || !mstring_equalPrefix (buf, ";;LCLint Dump:"))
431 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
432 "to continue without library.", name));
436 if (reader_readLine (f, buf, BUFLEN) != NULL)
438 if (!mstring_equalPrefix (buf, ";;"))
440 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
441 "to continue without library.", name));
444 else if (mstring_equalPrefix (buf, ";;ctTable"))
446 loadllmsg (message ("Load library %s is in obsolete LCLint library format. Attempting "
447 "to continue anyway, but results may be incorrect. Rebuild "
448 "the library with this version of lclint.",
455 if (sscanf (buf, ";;LCLint %f", &version) != 1)
457 loadllmsg (message ("Load library %s is not in LCLint library format (missing version "
458 "number). Attempting "
459 "to continue without library.", name));
464 if ((LCLINT_LIBVERSION - version) >= FLT_EPSILON)
467 char *nl = strchr (buf, '\n');
471 vname = cstring_fromChars (buf + 9);
473 loadllmsg (message ("Load library %s is in obsolete LCLint library "
474 "format (version %s). Attempting "
475 "to continue anyway, but results may be incorrect. Rebuild "
476 "the library with this version of lclint.",
481 if (reader_readLine (f, buf, BUFLEN) == NULL)
483 loadllmsg (message ("Load library %s is not in LCLint library "
484 "format (missing library code). Attempting "
485 "to continue without library.", name));
492 if (sscanf (buf, ";;lib:%d", &lib) != 1)
494 loadllmsg (message ("Load library %s is not in LCLint library "
495 "format (missing library code). Attempting "
496 "to continue without library.", name));
501 flagcode code = (flagcode) lib;
503 if (flagcode_isLibraryFlag (code))
505 if (context_doMerge ())
507 context_setLibrary (code);
512 loadllmsg (message ("Load library %s has invalid library code (%s). "
513 "Attempting to continue without library.",
515 flagcode_unparse (code)));
527 loadllmsg (message ("Load library %s is not in LCLint library format (missing lines). "
528 "Attempting to continue without library.", name));
535 typeIdSet_loadTable (f);
541 context_loadModuleAccess (f);
548 ** load state from file created by dumpState
552 loadState (cstring cfname)
555 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
557 f = fopen (cstring_toCharsSafe (fname), "r");
561 if (context_getDebug (FLG_SHOWSCAN))
562 fprintf (g_msgstream, " >\n");
564 llfatalerror (message ("Cannot open dump file for loading: %s",
569 fileloc_reallyFree (g_currentloc);
570 g_currentloc = fileloc_createLib (cfname);
572 if (!loadLCDFile (f, cfname))
574 if (!loadStandardState ())
580 check (fclose (f) == 0);
583 /* usymtab_printAll (); */
584 cstring_free (fname);