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