]> andersk Git - splint.git/blame - src/lcllib.c
Updated build to use automake files created by Tim Van Holder.
[splint.git] / src / lcllib.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
28bf4b0b 3** Copyright (C) 1994-2001 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**
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
23*/
24/*
25** lcllib.c
26**
27** routines for loading and creating library files
28**
29** this is a brute-force implementation, a more efficient
30** representation should be designed.
31**
32*/
33
34# include "lclintMacros.nf"
35# include "llbasic.h"
36
37# include "osd.h"
38
39# ifndef NOLCL
40# include "gram.h"
41
42# include "lclscan.h"
43# endif
44
616915dd 45# include "lcllib.h"
46# include "llmain.h"
47# include "portab.h"
48
49/*@-incondefs@*/ /*@-redecl@*/
15b3d2b2 50extern /*:open:*/ /*@dependent@*/ FILE *yyin;
616915dd 51/*@=incondefs@*/ /*@=redecl@*/
52
53/*@constant int NUMLIBS; @*/
54# define NUMLIBS 17
55
56/*@constant int NUMPOSIXLIBS; @*/
d1eb0f0f 57# define NUMPOSIXLIBS 18
616915dd 58
59static ob_mstring posixlibs[NUMPOSIXLIBS] =
60{
616915dd 61 "dirent",
62 "fcntl",
63 "grp",
64 "pwd",
b072092f 65 "regex",
d1eb0f0f 66 "sys/stat",
616915dd 67 "sys/times",
d1eb0f0f 68 "sys/types",
69 "netdb", /* unix */
70 "netinet/in", /* unix */
71 "sys/resource", /* unix */
72 "sys/socket", /* not posix */
73 "sys/syslog", /* not posix */
616915dd 74 "sys/utsname",
75 "sys/wait",
76 "termios",
77 "unistd",
78 "utime"
79} ;
80
81static ob_mstring stdlibs[NUMLIBS] =
82{
83 "assert",
84 "ctype",
85 "errno",
86 "float",
87 "limits",
88 "locale",
89 "math",
90 "setjmp",
91 "signal",
92 "stdarg",
93 "stddef",
94 "stdio",
95 "stdlib",
96 "strings",
97 "string",
98 "time",
99 "wchar"
100} ;
101
28bf4b0b 102static bool loadLCDFile (FILE * p_f, cstring p_name);
616915dd 103
104bool
105lcllib_isSkipHeader (cstring sname)
106{
107 int i;
108 bool posixlib = FALSE;
109 char *libname;
616915dd 110 char *matchname;
28bf4b0b 111 cstring xname;
616915dd 112
113 llassert (cstring_isDefined (sname));
28bf4b0b 114 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
616915dd 115
d1eb0f0f 116 DPRINTF (("Include? %s", sname));
117
28bf4b0b 118 /*@access cstring@*/
119 llassert (cstring_isDefined (xname));
120 libname = strrchr (xname, CONNECTCHAR);
616915dd 121 matchname = libname;
122
123 if (libname == NULL)
124 {
28bf4b0b 125 libname = xname;
616915dd 126 }
127 else
128 {
129 libname++;
130 /*@-branchstate@*/
131 }
132 /*@=branchstate@*/
133
134 if (mstring_equal (libname, "varargs"))
135 {
136 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
137
138 voptgenerror
139 (FLG_USEVARARGS,
1d239d69 140 message ("Include file <%s.h> is inconsistent with "
616915dd 141 "ANSI library (should use <stdarg.h>)",
142 cstring_fromChars (libname)),
143 tmp);
144
145 fileloc_free (tmp);
7ebcc5bb 146 cstring_free (xname);
616915dd 147 return TRUE;
148 }
149
150 if (context_getFlag (FLG_SKIPANSIHEADERS)
151 && context_usingAnsiLibrary ())
152 {
153
154 for (i = 0; i < NUMLIBS; i++)
155 {
156 if (mstring_equal (libname, stdlibs[i]))
157 {
28bf4b0b 158 sfree (xname);
616915dd 159 return TRUE;
160 }
161 }
162 }
163
164 for (i = 0; i < NUMPOSIXLIBS; i++)
165 {
166 if (strchr (posixlibs[i], CONNECTCHAR) != NULL)
167 {
168 char *ptr;
169
28bf4b0b 170 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
616915dd 171 {
172 if (ptr[strlen (posixlibs[i])] == '\0')
173 {
174 posixlib = TRUE;
175 matchname = ptr;
176 break;
177 }
178 else
179 {
180 ; /* no match */
181 }
182 }
183 }
184 else
185 {
186 if (mstring_equal (libname, posixlibs[i]))
187 {
188 posixlib = TRUE;
189 matchname = libname;
190 break;
191 }
192 /*@-branchstate@*/
193 }
194 } /*@=branchstate@*/
195
196 if (posixlib)
197 {
198 if (context_usingPosixLibrary ())
199 {
200 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
201 {
7ebcc5bb 202 cstring_free (xname);
616915dd 203 return TRUE;
204 }
205 }
206 else
207 {
208 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
209
210 voptgenerror
211 (FLG_WARNPOSIX,
1d239d69 212 message ("Include file <%s.h> matches the name of a "
616915dd 213 "POSIX library, but the POSIX library is "
214 "not being used. Consider using +posixlib "
215 "or +posixstrictlib to select the POSIX "
216 "library, or -warnposix "
217 "to suppress this message.",
218 cstring_fromChars (matchname)),
219 tmp);
220
221 fileloc_free (tmp);
222 }
223 }
224
28bf4b0b 225 cstring_free (xname);
226 /*@noaccess cstring@*/
616915dd 227 return FALSE;
228}
229
230static void printDot (void)
231{
232 if (context_getFlag (FLG_SHOWSCAN))
233 {
234 (void) fflush (g_msgstream);
235 fprintf (stderr, ".");
236 (void) fflush (stderr);
237 }
238}
239
240void
241dumpState (cstring cfname)
242{
243 FILE *f;
28bf4b0b 244 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 245
dfd82dce 246 f = fileTable_openFile (context_fileTable (), fname, "w");
616915dd 247
248 if (context_getFlag (FLG_SHOWSCAN))
249 {
28bf4b0b 250 fprintf (stderr, "< Dumping to %s ", cstring_toCharsSafe (fname));
616915dd 251 }
252
253 if (f == NULL)
254 {
efd360a3 255 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 256 }
257 else
258 {
259 /*
260 ** sequence is convulted --- must call usymtab_prepareDump before
261 ** dumping ctype table to convert type uid's
262 */
263
264 printDot ();
265
28bf4b0b 266 /*
267 DPRINTF (("Before prepare dump:"));
268 ctype_printTable ();
269 DPRINTF (("Preparing dump..."));
270 */
271
616915dd 272 usymtab_prepareDump ();
273
274 /*
28bf4b0b 275 ** Be careful, these lines must match loadLCDFile checking.
616915dd 276 */
277
28bf4b0b 278 fprintf (f, ";;LCLint Dump: %s\n", cstring_toCharsSafe (fname));
616915dd 279 fprintf (f, ";;%s\n", LCL_VERSION);
280 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
281 fprintf (f, ";;ctTable\n");
28bf4b0b 282
283 DPRINTF (("Dumping types..."));
616915dd 284 printDot ();
28bf4b0b 285 ctype_dumpTable (f);
616915dd 286 printDot ();
28bf4b0b 287
288 DPRINTF (("Dumping type sets..."));
616915dd 289 fprintf (f, ";;tistable\n");
290 typeIdSet_dumpTable (f);
291 printDot ();
28bf4b0b 292
293 DPRINTF (("Dumping usymtab..."));
294 fprintf (f, ";;symTable\n");
616915dd 295 usymtab_dump (f);
296 printDot ();
297
28bf4b0b 298 DPRINTF (("Dumping modules..."));
616915dd 299 fprintf (f, ";; Modules access\n");
300 context_dumpModuleAccess (f);
301 fprintf (f, ";;End\n");
dfd82dce 302 check (fileTable_closeFile (context_fileTable (), f));
616915dd 303 }
304
305 if (context_getFlag (FLG_SHOWSCAN))
306 {
307 fprintf (g_msgstream, " >\n");
308 }
309
28bf4b0b 310 cstring_free (fname);
616915dd 311}
312
313bool
314loadStandardState ()
315{
28bf4b0b 316 cstring fpath;
616915dd 317 FILE *stdlib;
318 bool result;
28bf4b0b 319 cstring libname = fileLib_addExtension (context_selectedLibrary (),
320 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 321
322 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
323 {
324 lldiagmsg (message ("Cannot find %sstandard library: %s",
325 cstring_makeLiteralTemp
326 (context_getFlag (FLG_STRICTLIB) ? "strict "
327 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 328 libname));
616915dd 329 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
330 result = FALSE;
331 }
332 else
333 {
dfd82dce 334 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
616915dd 335
336 if (stdlib == NULL)
337 {
338 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 339 fpath));
616915dd 340 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
341
342 result = FALSE;
343 }
344 else
345 {
346 if (context_getFlag (FLG_WHICHLIB))
347 {
348 char *t = mstring_create (MAX_NAME_LENGTH);
349 char *ot = t;
350
28bf4b0b 351 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 352 {
353 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
354 }
355
28bf4b0b 356 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 357 {
358 if (*t == ';' && *(t + 1) == ';')
359 {
360 t += 2;
361 }
362 }
363
364 if (t == NULL)
365 {
366 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 367 fpath));
616915dd 368 }
369 else
370 {
371 char *tt;
372
373 tt = strrchr (t, '\n');
374 if (tt != NULL)
375 *tt = '\0';
376
28bf4b0b 377 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 378 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
379 }
380
381 sfree (ot);
382
dfd82dce 383 check (fileTable_closeFile (context_fileTable (), stdlib));
384 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
616915dd 385 }
386
387 llassert (stdlib != NULL);
388
389 fileloc_reallyFree (g_currentloc);
28bf4b0b 390 g_currentloc = fileloc_createLib (libname);
391
392 DPRINTF (("Loading: %s", fpath));
616915dd 393
394 if (context_getDebug (FLG_SHOWSCAN))
395 {
28bf4b0b 396 fprintf (g_msgstream, "< loading standard library %s ",
397 cstring_toCharsSafe (fpath));
398 result = loadLCDFile (stdlib, fpath);
399 fprintf (g_msgstream, " >\n");
616915dd 400 }
401 else
402 {
28bf4b0b 403 result = loadLCDFile (stdlib, fpath);
616915dd 404 }
405
dfd82dce 406 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 407 }
408 }
409
28bf4b0b 410 cstring_free (libname);
616915dd 411 return result;
412}
413
414/*@constant int BUFLEN;@*/
415# define BUFLEN 128
416
417static bool
28bf4b0b 418loadLCDFile (FILE *f, cstring name)
616915dd 419{
420 char buf[BUFLEN];
421
422 /*
28bf4b0b 423 ** Check version. Should be >= LCLINT_LIBVERSION
616915dd 424 */
425
28bf4b0b 426 if (reader_readLine (f, buf, BUFLEN) == NULL
616915dd 427 || !mstring_equalPrefix (buf, ";;LCLint Dump:"))
428 {
429 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
28bf4b0b 430 "to continue without library.", name));
616915dd 431 return FALSE;
432 }
433
28bf4b0b 434 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 435 {
436 if (!mstring_equalPrefix (buf, ";;"))
437 {
438 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
28bf4b0b 439 "to continue without library.", name));
616915dd 440 return FALSE;
441 }
442 else if (mstring_equalPrefix (buf, ";;ctTable"))
443 {
444 loadllmsg (message ("Load library %s is in obsolete LCLint library format. Attempting "
28bf4b0b 445 "to continue anyway, but results may be incorrect. Rebuild "
446 "the library with this version of lclint.",
447 name));
616915dd 448 }
449 else
450 {
451 float version = 0.0;
452
453 if (sscanf (buf, ";;LCLint %f", &version) != 1)
454 {
455 loadllmsg (message ("Load library %s is not in LCLint library format (missing version "
28bf4b0b 456 "number). Attempting "
457 "to continue without library.", name));
616915dd 458 return FALSE;
459 }
460 else
461 {
28bf4b0b 462 if ((LCLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 463 {
464 cstring vname;
465 char *nl = strchr (buf, '\n');
466
28bf4b0b 467 *nl = '\0';
616915dd 468
469 vname = cstring_fromChars (buf + 9);
470
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.",
475 name, vname));
476 }
477 else
478 {
28bf4b0b 479 if (reader_readLine (f, buf, BUFLEN) == NULL)
616915dd 480 {
481 loadllmsg (message ("Load library %s is not in LCLint library "
482 "format (missing library code). Attempting "
483 "to continue without library.", name));
484 return FALSE;
485 }
486 else
487 {
488 int lib;
489
490 if (sscanf (buf, ";;lib:%d", &lib) != 1)
491 {
492 loadllmsg (message ("Load library %s is not in LCLint library "
493 "format (missing library code). Attempting "
494 "to continue without library.", name));
495 return FALSE;
496 }
497 else
498 {
499 flagcode code = (flagcode) lib;
500
501 if (flagcode_isLibraryFlag (code))
502 {
503 if (context_doMerge ())
504 {
505 context_setLibrary (code);
506 }
507 }
508 else
509 {
28bf4b0b 510 loadllmsg (message ("Load library %s has invalid library code (%s). "
616915dd 511 "Attempting to continue without library.",
28bf4b0b 512 name,
513 flagcode_unparse (code)));
616915dd 514
515 return FALSE;
516 }
517 }
518 }
519 }
520 }
521 }
522 }
523 else
524 {
525 loadllmsg (message ("Load library %s is not in LCLint library format (missing lines). "
526 "Attempting to continue without library.", name));
527 return FALSE;
528 }
529
530 ctype_loadTable (f);
531 printDot ();
532
533 typeIdSet_loadTable (f);
534 printDot ();
535
536 usymtab_load (f);
537 printDot ();
538
539 context_loadModuleAccess (f);
540 printDot ();
541
542 return TRUE;
543}
544
545/*
546** load state from file created by dumpState
547*/
548
549void
550loadState (cstring cfname)
551{
552 FILE *f;
28bf4b0b 553 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 554
dfd82dce 555 f = fileTable_openFile (context_fileTable (), fname, "r");
616915dd 556
557 if (f == NULL)
558 {
559 if (context_getDebug (FLG_SHOWSCAN))
560 fprintf (g_msgstream, " >\n");
561
28bf4b0b 562 llfatalerror (message ("Cannot open dump file for loading: %s",
563 fname));
616915dd 564 }
565 else
566 {
567 fileloc_reallyFree (g_currentloc);
28bf4b0b 568 g_currentloc = fileloc_createLib (cfname);
616915dd 569
28bf4b0b 570 if (!loadLCDFile (f, cfname))
616915dd 571 {
572 if (!loadStandardState ())
573 {
574 ctype_initTable ();
575 }
576 }
577
dfd82dce 578 check (fileTable_closeFile (context_fileTable (), f));
616915dd 579 }
580
28bf4b0b 581 /* usymtab_printAll (); */
582 cstring_free (fname);
616915dd 583}
584
This page took 0.134503 seconds and 5 git commands to generate.