]> andersk Git - splint.git/blame - src/lcllib.c
Fixed problem with assertion checking for negative shifts in
[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"
616915dd 49
50/*@-incondefs@*/ /*@-redecl@*/
15b3d2b2 51extern /*:open:*/ /*@dependent@*/ FILE *yyin;
616915dd 52/*@=incondefs@*/ /*@=redecl@*/
53
54/*@constant int NUMLIBS; @*/
45569d72 55# define NUMLIBS 25
616915dd 56
57/*@constant int NUMPOSIXLIBS; @*/
d1eb0f0f 58# define NUMPOSIXLIBS 18
616915dd 59
60static ob_mstring posixlibs[NUMPOSIXLIBS] =
61{
616915dd 62 "dirent",
63 "fcntl",
64 "grp",
65 "pwd",
b072092f 66 "regex",
d1eb0f0f 67 "sys/stat",
616915dd 68 "sys/times",
d1eb0f0f 69 "sys/types",
70 "netdb", /* unix */
71 "netinet/in", /* unix */
72 "sys/resource", /* unix */
73 "sys/socket", /* not posix */
74 "sys/syslog", /* not posix */
616915dd 75 "sys/utsname",
76 "sys/wait",
77 "termios",
78 "unistd",
79 "utime"
80} ;
81
82static ob_mstring stdlibs[NUMLIBS] =
83{
84 "assert",
45569d72 85 "complex"
616915dd 86 "ctype",
87 "errno",
45569d72 88 "fenv",
89 "float",
90 "inttypes",
91 "iso646",
616915dd 92 "limits",
93 "locale",
94 "math",
95 "setjmp",
96 "signal",
97 "stdarg",
45569d72 98 "stdbool",
616915dd 99 "stddef",
45569d72 100 "stdint",
616915dd 101 "stdio",
102 "stdlib",
616915dd 103 "string",
45569d72 104 "strings", /* some systems use this...they shouldn't */
105 "tgmath",
616915dd 106 "time",
45569d72 107 "wchar",
108 "wctype"
616915dd 109} ;
110
28bf4b0b 111static bool loadLCDFile (FILE * p_f, cstring p_name);
616915dd 112
113bool
114lcllib_isSkipHeader (cstring sname)
115{
116 int i;
117 bool posixlib = FALSE;
118 char *libname;
616915dd 119 char *matchname;
28bf4b0b 120 cstring xname;
616915dd 121
122 llassert (cstring_isDefined (sname));
28bf4b0b 123 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
616915dd 124
d1eb0f0f 125 DPRINTF (("Include? %s", sname));
126
28bf4b0b 127 /*@access cstring@*/
128 llassert (cstring_isDefined (xname));
7ac543fa 129# if defined (OS2)
130 {
131 /* Posixlibs use forward slashes, so we use them here, too */
132 cstring_replaceAll (xname, '\\', '/');
133 libname = strrchr (xname, '/');
134 DPRINTF (("libname: %s", libname));
135 }
136# else
28bf4b0b 137 libname = strrchr (xname, CONNECTCHAR);
7ac543fa 138# endif
616915dd 139 matchname = libname;
140
141 if (libname == NULL)
142 {
28bf4b0b 143 libname = xname;
616915dd 144 }
145 else
146 {
147 libname++;
148 /*@-branchstate@*/
149 }
150 /*@=branchstate@*/
151
152 if (mstring_equal (libname, "varargs"))
153 {
154 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
155
156 voptgenerror
157 (FLG_USEVARARGS,
1d239d69 158 message ("Include file <%s.h> is inconsistent with "
616915dd 159 "ANSI library (should use <stdarg.h>)",
160 cstring_fromChars (libname)),
161 tmp);
162
163 fileloc_free (tmp);
7ebcc5bb 164 cstring_free (xname);
616915dd 165 return TRUE;
166 }
167
abd7f895 168 if (context_getFlag (FLG_SKIPISOHEADERS)
616915dd 169 && context_usingAnsiLibrary ())
170 {
616915dd 171 for (i = 0; i < NUMLIBS; i++)
172 {
173 if (mstring_equal (libname, stdlibs[i]))
174 {
28bf4b0b 175 sfree (xname);
616915dd 176 return TRUE;
177 }
178 }
179 }
180
181 for (i = 0; i < NUMPOSIXLIBS; i++)
182 {
7ac543fa 183 if (strchr (posixlibs[i], CONNECTCHAR) != NULL
184# if defined (OS2)
185 || strchr (posixlibs[i], ALTCONNECTCHAR) != NULL
186# endif
187 )
616915dd 188 {
189 char *ptr;
190
7ac543fa 191 DPRINTF (("xname: %s, posix: %s", xname, posixlibs[i]));
28bf4b0b 192 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
616915dd 193 {
194 if (ptr[strlen (posixlibs[i])] == '\0')
195 {
196 posixlib = TRUE;
197 matchname = ptr;
198 break;
199 }
200 else
201 {
202 ; /* no match */
203 }
204 }
205 }
206 else
207 {
208 if (mstring_equal (libname, posixlibs[i]))
209 {
210 posixlib = TRUE;
211 matchname = libname;
212 break;
213 }
214 /*@-branchstate@*/
215 }
216 } /*@=branchstate@*/
217
218 if (posixlib)
219 {
220 if (context_usingPosixLibrary ())
221 {
222 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
223 {
7ebcc5bb 224 cstring_free (xname);
393e573f 225 /*@-nullstate@*/
226 return TRUE;
227 /*@=nullstate@*/
b73d1009 228
393e573f 229 /* evans 2002-03-02:
b73d1009 230 the returned reference is possibly null,
231 but this should not change the null state of the parameter
393e573f 232 */
616915dd 233 }
234 }
235 else
236 {
237 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
238
239 voptgenerror
240 (FLG_WARNPOSIX,
1d239d69 241 message ("Include file <%s.h> matches the name of a "
616915dd 242 "POSIX library, but the POSIX library is "
243 "not being used. Consider using +posixlib "
244 "or +posixstrictlib to select the POSIX "
245 "library, or -warnposix "
246 "to suppress this message.",
247 cstring_fromChars (matchname)),
248 tmp);
249
250 fileloc_free (tmp);
251 }
252 }
253
28bf4b0b 254 cstring_free (xname);
255 /*@noaccess cstring@*/
b73d1009 256 /*@-nullstate@*/ /* same problem as above */
616915dd 257 return FALSE;
393e573f 258 /*@=nullstate@*/
616915dd 259}
260
261static void printDot (void)
262{
80489f0a 263 displayScanContinue (cstring_makeLiteralTemp ("."));
616915dd 264}
265
266void
267dumpState (cstring cfname)
268{
269 FILE *f;
28bf4b0b 270 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 271
d5047b91 272 f = fileTable_openWriteFile (context_fileTable (), fname);
616915dd 273
80489f0a 274 displayScanOpen (message ("Dumping to %s ", fname));
616915dd 275
276 if (f == NULL)
277 {
efd360a3 278 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 279 }
280 else
281 {
282 /*
283 ** sequence is convulted --- must call usymtab_prepareDump before
284 ** dumping ctype table to convert type uid's
285 */
286
287 printDot ();
288
28bf4b0b 289 /*
290 DPRINTF (("Before prepare dump:"));
291 ctype_printTable ();
292 DPRINTF (("Preparing dump..."));
293 */
294
616915dd 295 usymtab_prepareDump ();
296
297 /*
28bf4b0b 298 ** Be careful, these lines must match loadLCDFile checking.
616915dd 299 */
300
11db3170 301 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
e5081f8c 302 fprintf (f, ";;Splint %f\n", SPLINT_LIBVERSION);
616915dd 303 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
304 fprintf (f, ";;ctTable\n");
28bf4b0b 305
306 DPRINTF (("Dumping types..."));
616915dd 307 printDot ();
28bf4b0b 308 ctype_dumpTable (f);
616915dd 309 printDot ();
28bf4b0b 310
311 DPRINTF (("Dumping type sets..."));
616915dd 312 fprintf (f, ";;tistable\n");
313 typeIdSet_dumpTable (f);
314 printDot ();
28bf4b0b 315
316 DPRINTF (("Dumping usymtab..."));
317 fprintf (f, ";;symTable\n");
616915dd 318 usymtab_dump (f);
319 printDot ();
320
28bf4b0b 321 DPRINTF (("Dumping modules..."));
616915dd 322 fprintf (f, ";; Modules access\n");
323 context_dumpModuleAccess (f);
324 fprintf (f, ";;End\n");
dfd82dce 325 check (fileTable_closeFile (context_fileTable (), f));
616915dd 326 }
327
80489f0a 328 displayScanClose ();
28bf4b0b 329 cstring_free (fname);
616915dd 330}
331
332bool
333loadStandardState ()
334{
28bf4b0b 335 cstring fpath;
616915dd 336 FILE *stdlib;
337 bool result;
28bf4b0b 338 cstring libname = fileLib_addExtension (context_selectedLibrary (),
339 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 340
341 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
342 {
343 lldiagmsg (message ("Cannot find %sstandard library: %s",
344 cstring_makeLiteralTemp
345 (context_getFlag (FLG_STRICTLIB) ? "strict "
346 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 347 libname));
616915dd 348 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
349 result = FALSE;
350 }
351 else
352 {
d5047b91 353 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 354
355 if (stdlib == NULL)
356 {
357 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 358 fpath));
616915dd 359 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
360
361 result = FALSE;
362 }
363 else
364 {
365 if (context_getFlag (FLG_WHICHLIB))
366 {
367 char *t = mstring_create (MAX_NAME_LENGTH);
368 char *ot = t;
369
28bf4b0b 370 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 371 {
372 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
373 }
374
28bf4b0b 375 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 376 {
377 if (*t == ';' && *(t + 1) == ';')
378 {
379 t += 2;
380 }
381 }
382
383 if (t == NULL)
384 {
385 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 386 fpath));
616915dd 387 }
388 else
389 {
390 char *tt;
391
392 tt = strrchr (t, '\n');
393 if (tt != NULL)
394 *tt = '\0';
395
28bf4b0b 396 lldiagmsg (message ("Standard library: %s", fpath));
b8dce3c7 397 /* evans 2004-01-13: removed this (it is the libversion which is confusing) */
398 /* lldiagmsg (message (" (created using %s)", cstring_fromChars (t))); */
616915dd 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.164636 seconds and 5 git commands to generate.