]> andersk Git - splint.git/blame - src/lcllib.c
Cleaned up flags to generate manual help.
[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**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-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
34# include "lclintMacros.nf"
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; @*/
53# define NUMLIBS 17
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",
83 "ctype",
84 "errno",
85 "float",
86 "limits",
87 "locale",
88 "math",
89 "setjmp",
90 "signal",
91 "stdarg",
92 "stddef",
93 "stdio",
94 "stdlib",
95 "strings",
96 "string",
97 "time",
98 "wchar"
99} ;
100
28bf4b0b 101static bool loadLCDFile (FILE * p_f, cstring p_name);
616915dd 102
103bool
104lcllib_isSkipHeader (cstring sname)
105{
106 int i;
107 bool posixlib = FALSE;
108 char *libname;
616915dd 109 char *matchname;
28bf4b0b 110 cstring xname;
616915dd 111
112 llassert (cstring_isDefined (sname));
28bf4b0b 113 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
616915dd 114
d1eb0f0f 115 DPRINTF (("Include? %s", sname));
116
28bf4b0b 117 /*@access cstring@*/
118 llassert (cstring_isDefined (xname));
119 libname = strrchr (xname, CONNECTCHAR);
616915dd 120 matchname = libname;
121
122 if (libname == NULL)
123 {
28bf4b0b 124 libname = xname;
616915dd 125 }
126 else
127 {
128 libname++;
129 /*@-branchstate@*/
130 }
131 /*@=branchstate@*/
132
133 if (mstring_equal (libname, "varargs"))
134 {
135 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
136
137 voptgenerror
138 (FLG_USEVARARGS,
1d239d69 139 message ("Include file <%s.h> is inconsistent with "
616915dd 140 "ANSI library (should use <stdarg.h>)",
141 cstring_fromChars (libname)),
142 tmp);
143
144 fileloc_free (tmp);
7ebcc5bb 145 cstring_free (xname);
616915dd 146 return TRUE;
147 }
148
149 if (context_getFlag (FLG_SKIPANSIHEADERS)
150 && context_usingAnsiLibrary ())
151 {
152
153 for (i = 0; i < NUMLIBS; i++)
154 {
155 if (mstring_equal (libname, stdlibs[i]))
156 {
28bf4b0b 157 sfree (xname);
616915dd 158 return TRUE;
159 }
160 }
161 }
162
163 for (i = 0; i < NUMPOSIXLIBS; i++)
164 {
165 if (strchr (posixlibs[i], CONNECTCHAR) != NULL)
166 {
167 char *ptr;
168
28bf4b0b 169 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
616915dd 170 {
171 if (ptr[strlen (posixlibs[i])] == '\0')
172 {
173 posixlib = TRUE;
174 matchname = ptr;
175 break;
176 }
177 else
178 {
179 ; /* no match */
180 }
181 }
182 }
183 else
184 {
185 if (mstring_equal (libname, posixlibs[i]))
186 {
187 posixlib = TRUE;
188 matchname = libname;
189 break;
190 }
191 /*@-branchstate@*/
192 }
193 } /*@=branchstate@*/
194
195 if (posixlib)
196 {
197 if (context_usingPosixLibrary ())
198 {
199 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
200 {
7ebcc5bb 201 cstring_free (xname);
616915dd 202 return TRUE;
203 }
204 }
205 else
206 {
207 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
208
209 voptgenerror
210 (FLG_WARNPOSIX,
1d239d69 211 message ("Include file <%s.h> matches the name of a "
616915dd 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)),
218 tmp);
219
220 fileloc_free (tmp);
221 }
222 }
223
28bf4b0b 224 cstring_free (xname);
225 /*@noaccess cstring@*/
616915dd 226 return FALSE;
227}
228
229static void printDot (void)
230{
231 if (context_getFlag (FLG_SHOWSCAN))
232 {
233 (void) fflush (g_msgstream);
234 fprintf (stderr, ".");
235 (void) fflush (stderr);
236 }
237}
238
239void
240dumpState (cstring cfname)
241{
242 FILE *f;
28bf4b0b 243 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 244
dfd82dce 245 f = fileTable_openFile (context_fileTable (), fname, "w");
616915dd 246
247 if (context_getFlag (FLG_SHOWSCAN))
248 {
28bf4b0b 249 fprintf (stderr, "< Dumping to %s ", cstring_toCharsSafe (fname));
616915dd 250 }
251
252 if (f == NULL)
253 {
efd360a3 254 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 255 }
256 else
257 {
258 /*
259 ** sequence is convulted --- must call usymtab_prepareDump before
260 ** dumping ctype table to convert type uid's
261 */
262
263 printDot ();
264
28bf4b0b 265 /*
266 DPRINTF (("Before prepare dump:"));
267 ctype_printTable ();
268 DPRINTF (("Preparing dump..."));
269 */
270
616915dd 271 usymtab_prepareDump ();
272
273 /*
28bf4b0b 274 ** Be careful, these lines must match loadLCDFile checking.
616915dd 275 */
276
11db3170 277 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
60868d40 278 fprintf (f, ";;%s\n", SPLINT_VERSION);
616915dd 279 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
280 fprintf (f, ";;ctTable\n");
28bf4b0b 281
282 DPRINTF (("Dumping types..."));
616915dd 283 printDot ();
28bf4b0b 284 ctype_dumpTable (f);
616915dd 285 printDot ();
28bf4b0b 286
287 DPRINTF (("Dumping type sets..."));
616915dd 288 fprintf (f, ";;tistable\n");
289 typeIdSet_dumpTable (f);
290 printDot ();
28bf4b0b 291
292 DPRINTF (("Dumping usymtab..."));
293 fprintf (f, ";;symTable\n");
616915dd 294 usymtab_dump (f);
295 printDot ();
296
28bf4b0b 297 DPRINTF (("Dumping modules..."));
616915dd 298 fprintf (f, ";; Modules access\n");
299 context_dumpModuleAccess (f);
300 fprintf (f, ";;End\n");
dfd82dce 301 check (fileTable_closeFile (context_fileTable (), f));
616915dd 302 }
303
304 if (context_getFlag (FLG_SHOWSCAN))
305 {
306 fprintf (g_msgstream, " >\n");
307 }
308
28bf4b0b 309 cstring_free (fname);
616915dd 310}
311
312bool
313loadStandardState ()
314{
28bf4b0b 315 cstring fpath;
616915dd 316 FILE *stdlib;
317 bool result;
28bf4b0b 318 cstring libname = fileLib_addExtension (context_selectedLibrary (),
319 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 320
321 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
322 {
323 lldiagmsg (message ("Cannot find %sstandard library: %s",
324 cstring_makeLiteralTemp
325 (context_getFlag (FLG_STRICTLIB) ? "strict "
326 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 327 libname));
616915dd 328 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
329 result = FALSE;
330 }
331 else
332 {
dfd82dce 333 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
616915dd 334
335 if (stdlib == NULL)
336 {
337 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 338 fpath));
616915dd 339 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
340
341 result = FALSE;
342 }
343 else
344 {
345 if (context_getFlag (FLG_WHICHLIB))
346 {
347 char *t = mstring_create (MAX_NAME_LENGTH);
348 char *ot = t;
349
28bf4b0b 350 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 351 {
352 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
353 }
354
28bf4b0b 355 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 356 {
357 if (*t == ';' && *(t + 1) == ';')
358 {
359 t += 2;
360 }
361 }
362
363 if (t == NULL)
364 {
365 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 366 fpath));
616915dd 367 }
368 else
369 {
370 char *tt;
371
372 tt = strrchr (t, '\n');
373 if (tt != NULL)
374 *tt = '\0';
375
28bf4b0b 376 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 377 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
378 }
379
380 sfree (ot);
381
dfd82dce 382 check (fileTable_closeFile (context_fileTable (), stdlib));
383 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
616915dd 384 }
385
386 llassert (stdlib != NULL);
387
388 fileloc_reallyFree (g_currentloc);
28bf4b0b 389 g_currentloc = fileloc_createLib (libname);
390
391 DPRINTF (("Loading: %s", fpath));
616915dd 392
393 if (context_getDebug (FLG_SHOWSCAN))
394 {
28bf4b0b 395 fprintf (g_msgstream, "< loading standard library %s ",
396 cstring_toCharsSafe (fpath));
397 result = loadLCDFile (stdlib, fpath);
398 fprintf (g_msgstream, " >\n");
616915dd 399 }
400 else
401 {
28bf4b0b 402 result = loadLCDFile (stdlib, fpath);
616915dd 403 }
404
dfd82dce 405 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 406 }
407 }
408
28bf4b0b 409 cstring_free (libname);
616915dd 410 return result;
411}
412
413/*@constant int BUFLEN;@*/
414# define BUFLEN 128
415
416static bool
28bf4b0b 417loadLCDFile (FILE *f, cstring name)
616915dd 418{
419 char buf[BUFLEN];
420
421 /*
28bf4b0b 422 ** Check version. Should be >= LCLINT_LIBVERSION
616915dd 423 */
424
28bf4b0b 425 if (reader_readLine (f, buf, BUFLEN) == NULL
11db3170 426 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
616915dd 427 {
11db3170 428 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 429 "to continue without library.", name));
616915dd 430 return FALSE;
431 }
432
28bf4b0b 433 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 434 {
435 if (!mstring_equalPrefix (buf, ";;"))
436 {
11db3170 437 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 438 "to continue without library.", name));
616915dd 439 return FALSE;
440 }
441 else if (mstring_equalPrefix (buf, ";;ctTable"))
442 {
11db3170 443 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
28bf4b0b 444 "to continue anyway, but results may be incorrect. Rebuild "
445 "the library with this version of lclint.",
446 name));
616915dd 447 }
448 else
449 {
450 float version = 0.0;
451
11db3170 452 if (sscanf (buf, ";;Splint %f", &version) != 1
453 && (sscanf (buf, ";;LCLint %f", &version) != 1))
616915dd 454 {
11db3170 455 loadllmsg (message ("Load library %s is not in Splint 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 {
11db3170 481 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 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 {
11db3170 492 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 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 {
11db3170 525 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
616915dd 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.197125 seconds and 5 git commands to generate.