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