]> andersk Git - splint.git/blame - src/lcllib.c
Pushed back constraintResolve.c to the previous version.
[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"
616915dd 40# include "llbasic.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 {
172
173 for (i = 0; i < NUMLIBS; i++)
174 {
175 if (mstring_equal (libname, stdlibs[i]))
176 {
28bf4b0b 177 sfree (xname);
616915dd 178 return TRUE;
179 }
180 }
181 }
182
183 for (i = 0; i < NUMPOSIXLIBS; i++)
184 {
7ac543fa 185 if (strchr (posixlibs[i], CONNECTCHAR) != NULL
186# if defined (OS2)
187 || strchr (posixlibs[i], ALTCONNECTCHAR) != NULL
188# endif
189 )
616915dd 190 {
191 char *ptr;
192
7ac543fa 193 DPRINTF (("xname: %s, posix: %s", xname, posixlibs[i]));
28bf4b0b 194 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
616915dd 195 {
196 if (ptr[strlen (posixlibs[i])] == '\0')
197 {
198 posixlib = TRUE;
199 matchname = ptr;
200 break;
201 }
202 else
203 {
204 ; /* no match */
205 }
206 }
207 }
208 else
209 {
210 if (mstring_equal (libname, posixlibs[i]))
211 {
212 posixlib = TRUE;
213 matchname = libname;
214 break;
215 }
216 /*@-branchstate@*/
217 }
218 } /*@=branchstate@*/
219
220 if (posixlib)
221 {
222 if (context_usingPosixLibrary ())
223 {
224 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
225 {
7ebcc5bb 226 cstring_free (xname);
393e573f 227 /*@-nullstate@*/
228 return TRUE;
229 /*@=nullstate@*/
230 /*@i233@*/
231 /* evans 2002-03-02:
232 the returned reference is possibly null,
233 but this should not change the null state of the parameter
234 investigate this warning
235 */
616915dd 236 }
237 }
238 else
239 {
240 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
241
242 voptgenerror
243 (FLG_WARNPOSIX,
1d239d69 244 message ("Include file <%s.h> matches the name of a "
616915dd 245 "POSIX library, but the POSIX library is "
246 "not being used. Consider using +posixlib "
247 "or +posixstrictlib to select the POSIX "
248 "library, or -warnposix "
249 "to suppress this message.",
250 cstring_fromChars (matchname)),
251 tmp);
252
253 fileloc_free (tmp);
254 }
255 }
256
28bf4b0b 257 cstring_free (xname);
258 /*@noaccess cstring@*/
393e573f 259 /*@-nullstate@*/ /*@i233@*/ /* same problem as above */
616915dd 260 return FALSE;
393e573f 261 /*@=nullstate@*/
616915dd 262}
263
264static void printDot (void)
265{
80489f0a 266 displayScanContinue (cstring_makeLiteralTemp ("."));
616915dd 267}
268
269void
270dumpState (cstring cfname)
271{
272 FILE *f;
28bf4b0b 273 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 274
d5047b91 275 f = fileTable_openWriteFile (context_fileTable (), fname);
616915dd 276
80489f0a 277 displayScanOpen (message ("Dumping to %s ", fname));
616915dd 278
279 if (f == NULL)
280 {
efd360a3 281 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 282 }
283 else
284 {
285 /*
286 ** sequence is convulted --- must call usymtab_prepareDump before
287 ** dumping ctype table to convert type uid's
288 */
289
290 printDot ();
291
28bf4b0b 292 /*
293 DPRINTF (("Before prepare dump:"));
294 ctype_printTable ();
295 DPRINTF (("Preparing dump..."));
296 */
297
616915dd 298 usymtab_prepareDump ();
299
300 /*
28bf4b0b 301 ** Be careful, these lines must match loadLCDFile checking.
616915dd 302 */
303
11db3170 304 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
e5081f8c 305 fprintf (f, ";;Splint %f\n", SPLINT_LIBVERSION);
616915dd 306 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
307 fprintf (f, ";;ctTable\n");
28bf4b0b 308
309 DPRINTF (("Dumping types..."));
616915dd 310 printDot ();
28bf4b0b 311 ctype_dumpTable (f);
616915dd 312 printDot ();
28bf4b0b 313
314 DPRINTF (("Dumping type sets..."));
616915dd 315 fprintf (f, ";;tistable\n");
316 typeIdSet_dumpTable (f);
317 printDot ();
28bf4b0b 318
319 DPRINTF (("Dumping usymtab..."));
320 fprintf (f, ";;symTable\n");
616915dd 321 usymtab_dump (f);
322 printDot ();
323
28bf4b0b 324 DPRINTF (("Dumping modules..."));
616915dd 325 fprintf (f, ";; Modules access\n");
326 context_dumpModuleAccess (f);
327 fprintf (f, ";;End\n");
dfd82dce 328 check (fileTable_closeFile (context_fileTable (), f));
616915dd 329 }
330
80489f0a 331 displayScanClose ();
28bf4b0b 332 cstring_free (fname);
616915dd 333}
334
335bool
336loadStandardState ()
337{
28bf4b0b 338 cstring fpath;
616915dd 339 FILE *stdlib;
340 bool result;
28bf4b0b 341 cstring libname = fileLib_addExtension (context_selectedLibrary (),
342 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 343
344 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
345 {
346 lldiagmsg (message ("Cannot find %sstandard library: %s",
347 cstring_makeLiteralTemp
348 (context_getFlag (FLG_STRICTLIB) ? "strict "
349 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 350 libname));
616915dd 351 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
352 result = FALSE;
353 }
354 else
355 {
d5047b91 356 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 357
358 if (stdlib == NULL)
359 {
360 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 361 fpath));
616915dd 362 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
363
364 result = FALSE;
365 }
366 else
367 {
368 if (context_getFlag (FLG_WHICHLIB))
369 {
370 char *t = mstring_create (MAX_NAME_LENGTH);
371 char *ot = t;
372
28bf4b0b 373 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 374 {
375 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
376 }
377
28bf4b0b 378 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 379 {
380 if (*t == ';' && *(t + 1) == ';')
381 {
382 t += 2;
383 }
384 }
385
386 if (t == NULL)
387 {
388 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 389 fpath));
616915dd 390 }
391 else
392 {
393 char *tt;
394
395 tt = strrchr (t, '\n');
396 if (tt != NULL)
397 *tt = '\0';
398
28bf4b0b 399 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 400 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
401 }
402
403 sfree (ot);
404
dfd82dce 405 check (fileTable_closeFile (context_fileTable (), stdlib));
d5047b91 406 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 407 }
408
409 llassert (stdlib != NULL);
410
411 fileloc_reallyFree (g_currentloc);
28bf4b0b 412 g_currentloc = fileloc_createLib (libname);
413
414 DPRINTF (("Loading: %s", fpath));
616915dd 415
80489f0a 416 displayScanOpen (message ("loading standard library %s ", fpath));
417 result = loadLCDFile (stdlib, fpath);
418 displayScanClose ();
616915dd 419
dfd82dce 420 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 421 }
422 }
423
28bf4b0b 424 cstring_free (libname);
616915dd 425 return result;
426}
427
428/*@constant int BUFLEN;@*/
429# define BUFLEN 128
430
431static bool
28bf4b0b 432loadLCDFile (FILE *f, cstring name)
616915dd 433{
434 char buf[BUFLEN];
435
436 /*
1b8ae690 437 ** Check version. Should be >= SPLINT_LIBVERSION
616915dd 438 */
439
28bf4b0b 440 if (reader_readLine (f, buf, BUFLEN) == NULL
11db3170 441 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
616915dd 442 {
11db3170 443 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 444 "to continue without library.", name));
616915dd 445 return FALSE;
446 }
447
28bf4b0b 448 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 449 {
450 if (!mstring_equalPrefix (buf, ";;"))
451 {
11db3170 452 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 453 "to continue without library.", name));
616915dd 454 return FALSE;
455 }
456 else if (mstring_equalPrefix (buf, ";;ctTable"))
457 {
11db3170 458 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
28bf4b0b 459 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 460 "the library with this version of splint.",
28bf4b0b 461 name));
616915dd 462 }
463 else
464 {
465 float version = 0.0;
466
11db3170 467 if (sscanf (buf, ";;Splint %f", &version) != 1
468 && (sscanf (buf, ";;LCLint %f", &version) != 1))
616915dd 469 {
11db3170 470 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
28bf4b0b 471 "number). Attempting "
472 "to continue without library.", name));
616915dd 473 return FALSE;
474 }
475 else
476 {
1b8ae690 477 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 478 {
479 cstring vname;
480 char *nl = strchr (buf, '\n');
481
28bf4b0b 482 *nl = '\0';
616915dd 483
484 vname = cstring_fromChars (buf + 9);
485
1b8ae690 486 loadllmsg (message ("Load library %s is in obsolete Splint library "
e5081f8c 487 "format (version %f (%s), expecting version %f). Attempting "
616915dd 488 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 489 "the library with this version of splint.",
e5081f8c 490 name,
491 version,
492 vname,
493 SPLINT_LIBVERSION));
616915dd 494 }
495 else
496 {
28bf4b0b 497 if (reader_readLine (f, buf, BUFLEN) == NULL)
616915dd 498 {
11db3170 499 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 500 "format (missing library code). Attempting "
501 "to continue without library.", name));
502 return FALSE;
503 }
504 else
505 {
506 int lib;
507
508 if (sscanf (buf, ";;lib:%d", &lib) != 1)
509 {
11db3170 510 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 511 "format (missing library code). Attempting "
512 "to continue without library.", name));
513 return FALSE;
514 }
515 else
516 {
517 flagcode code = (flagcode) lib;
518
519 if (flagcode_isLibraryFlag (code))
520 {
521 if (context_doMerge ())
522 {
523 context_setLibrary (code);
524 }
525 }
526 else
527 {
28bf4b0b 528 loadllmsg (message ("Load library %s has invalid library code (%s). "
616915dd 529 "Attempting to continue without library.",
28bf4b0b 530 name,
531 flagcode_unparse (code)));
616915dd 532
533 return FALSE;
534 }
535 }
536 }
537 }
538 }
539 }
540 }
541 else
542 {
11db3170 543 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
616915dd 544 "Attempting to continue without library.", name));
545 return FALSE;
546 }
547
548 ctype_loadTable (f);
549 printDot ();
550
551 typeIdSet_loadTable (f);
552 printDot ();
553
554 usymtab_load (f);
555 printDot ();
556
557 context_loadModuleAccess (f);
558 printDot ();
559
560 return TRUE;
561}
562
563/*
564** load state from file created by dumpState
565*/
566
567void
568loadState (cstring cfname)
569{
570 FILE *f;
28bf4b0b 571 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 572
d5047b91 573 f = fileTable_openReadFile (context_fileTable (), fname);
616915dd 574
575 if (f == NULL)
576 {
80489f0a 577 displayScanClose ();
28bf4b0b 578 llfatalerror (message ("Cannot open dump file for loading: %s",
579 fname));
616915dd 580 }
581 else
582 {
583 fileloc_reallyFree (g_currentloc);
28bf4b0b 584 g_currentloc = fileloc_createLib (cfname);
616915dd 585
28bf4b0b 586 if (!loadLCDFile (f, cfname))
616915dd 587 {
588 if (!loadStandardState ())
589 {
590 ctype_initTable ();
591 }
592 }
593
dfd82dce 594 check (fileTable_closeFile (context_fileTable (), f));
616915dd 595 }
596
28bf4b0b 597 /* usymtab_printAll (); */
598 cstring_free (fname);
616915dd 599}
600
This page took 1.56126 seconds and 5 git commands to generate.