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