]> andersk Git - splint.git/blame_incremental - src/lcllib.c
Fixed problem with assertion checking for negative shifts in
[splint.git] / src / lcllib.c
... / ...
CommitLineData
1/*
2** Splint - annotation-assisted static program checker
3** Copyright (C) 1994-2003 University of Virginia,
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 splint: info@splint.org
21** To report a bug: splint-bug@splint.org
22** For more information: http://www.splint.org
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/*
35 * Herbert 02/17/2002:
36 * - fixed the recognition of Posix headers for OS/2
37 */
38
39# include "splintMacros.nf"
40# include "basic.h"
41# include "osd.h"
42# include "version.h"
43
44# include "gram.h"
45# include "lclscan.h"
46
47# include "lcllib.h"
48# include "llmain.h"
49
50/*@-incondefs@*/ /*@-redecl@*/
51extern /*:open:*/ /*@dependent@*/ FILE *yyin;
52/*@=incondefs@*/ /*@=redecl@*/
53
54/*@constant int NUMLIBS; @*/
55# define NUMLIBS 25
56
57/*@constant int NUMPOSIXLIBS; @*/
58# define NUMPOSIXLIBS 18
59
60static ob_mstring posixlibs[NUMPOSIXLIBS] =
61{
62 "dirent",
63 "fcntl",
64 "grp",
65 "pwd",
66 "regex",
67 "sys/stat",
68 "sys/times",
69 "sys/types",
70 "netdb", /* unix */
71 "netinet/in", /* unix */
72 "sys/resource", /* unix */
73 "sys/socket", /* not posix */
74 "sys/syslog", /* not posix */
75 "sys/utsname",
76 "sys/wait",
77 "termios",
78 "unistd",
79 "utime"
80} ;
81
82static ob_mstring stdlibs[NUMLIBS] =
83{
84 "assert",
85 "complex"
86 "ctype",
87 "errno",
88 "fenv",
89 "float",
90 "inttypes",
91 "iso646",
92 "limits",
93 "locale",
94 "math",
95 "setjmp",
96 "signal",
97 "stdarg",
98 "stdbool",
99 "stddef",
100 "stdint",
101 "stdio",
102 "stdlib",
103 "string",
104 "strings", /* some systems use this...they shouldn't */
105 "tgmath",
106 "time",
107 "wchar",
108 "wctype"
109} ;
110
111static bool loadLCDFile (FILE * p_f, cstring p_name);
112
113bool
114lcllib_isSkipHeader (cstring sname)
115{
116 int i;
117 bool posixlib = FALSE;
118 char *libname;
119 char *matchname;
120 cstring xname;
121
122 llassert (cstring_isDefined (sname));
123 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
124
125 DPRINTF (("Include? %s", sname));
126
127 /*@access cstring@*/
128 llassert (cstring_isDefined (xname));
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
137 libname = strrchr (xname, CONNECTCHAR);
138# endif
139 matchname = libname;
140
141 if (libname == NULL)
142 {
143 libname = xname;
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,
158 message ("Include file <%s.h> is inconsistent with "
159 "ANSI library (should use <stdarg.h>)",
160 cstring_fromChars (libname)),
161 tmp);
162
163 fileloc_free (tmp);
164 cstring_free (xname);
165 return TRUE;
166 }
167
168 if (context_getFlag (FLG_SKIPISOHEADERS)
169 && context_usingAnsiLibrary ())
170 {
171 for (i = 0; i < NUMLIBS; i++)
172 {
173 if (mstring_equal (libname, stdlibs[i]))
174 {
175 sfree (xname);
176 return TRUE;
177 }
178 }
179 }
180
181 for (i = 0; i < NUMPOSIXLIBS; i++)
182 {
183 if (strchr (posixlibs[i], CONNECTCHAR) != NULL
184# if defined (OS2)
185 || strchr (posixlibs[i], ALTCONNECTCHAR) != NULL
186# endif
187 )
188 {
189 char *ptr;
190
191 DPRINTF (("xname: %s, posix: %s", xname, posixlibs[i]));
192 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
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 {
224 cstring_free (xname);
225 /*@-nullstate@*/
226 return TRUE;
227 /*@=nullstate@*/
228
229 /* evans 2002-03-02:
230 the returned reference is possibly null,
231 but this should not change the null state of the parameter
232 */
233 }
234 }
235 else
236 {
237 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
238
239 voptgenerror
240 (FLG_WARNPOSIX,
241 message ("Include file <%s.h> matches the name of a "
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
254 cstring_free (xname);
255 /*@noaccess cstring@*/
256 /*@-nullstate@*/ /* same problem as above */
257 return FALSE;
258 /*@=nullstate@*/
259}
260
261static void printDot (void)
262{
263 displayScanContinue (cstring_makeLiteralTemp ("."));
264}
265
266void
267dumpState (cstring cfname)
268{
269 FILE *f;
270 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
271
272 f = fileTable_openWriteFile (context_fileTable (), fname);
273
274 displayScanOpen (message ("Dumping to %s ", fname));
275
276 if (f == NULL)
277 {
278 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
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
289 /*
290 DPRINTF (("Before prepare dump:"));
291 ctype_printTable ();
292 DPRINTF (("Preparing dump..."));
293 */
294
295 usymtab_prepareDump ();
296
297 /*
298 ** Be careful, these lines must match loadLCDFile checking.
299 */
300
301 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
302 fprintf (f, ";;Splint %f\n", SPLINT_LIBVERSION);
303 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
304 fprintf (f, ";;ctTable\n");
305
306 DPRINTF (("Dumping types..."));
307 printDot ();
308 ctype_dumpTable (f);
309 printDot ();
310
311 DPRINTF (("Dumping type sets..."));
312 fprintf (f, ";;tistable\n");
313 typeIdSet_dumpTable (f);
314 printDot ();
315
316 DPRINTF (("Dumping usymtab..."));
317 fprintf (f, ";;symTable\n");
318 usymtab_dump (f);
319 printDot ();
320
321 DPRINTF (("Dumping modules..."));
322 fprintf (f, ";; Modules access\n");
323 context_dumpModuleAccess (f);
324 fprintf (f, ";;End\n");
325 check (fileTable_closeFile (context_fileTable (), f));
326 }
327
328 displayScanClose ();
329 cstring_free (fname);
330}
331
332bool
333loadStandardState ()
334{
335 cstring fpath;
336 FILE *stdlib;
337 bool result;
338 cstring libname = fileLib_addExtension (context_selectedLibrary (),
339 cstring_makeLiteralTemp (DUMP_SUFFIX));
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 " : "")),
347 libname));
348 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
349 result = FALSE;
350 }
351 else
352 {
353 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
354
355 if (stdlib == NULL)
356 {
357 lldiagmsg (message ("Cannot read standard library: %s",
358 fpath));
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
370 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
371 {
372 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
373 }
374
375 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
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>",
386 fpath));
387 }
388 else
389 {
390 char *tt;
391
392 tt = strrchr (t, '\n');
393 if (tt != NULL)
394 *tt = '\0';
395
396 lldiagmsg (message ("Standard library: %s", fpath));
397 /* evans 2004-01-13: removed this (it is the libversion which is confusing) */
398 /* lldiagmsg (message (" (created using %s)", cstring_fromChars (t))); */
399 }
400
401 sfree (ot);
402
403 check (fileTable_closeFile (context_fileTable (), stdlib));
404 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
405 }
406
407 llassert (stdlib != NULL);
408
409 fileloc_reallyFree (g_currentloc);
410 g_currentloc = fileloc_createLib (libname);
411
412 DPRINTF (("Loading: %s", fpath));
413
414 displayScanOpen (message ("loading standard library %s ", fpath));
415 result = loadLCDFile (stdlib, fpath);
416 displayScanClose ();
417
418 check (fileTable_closeFile (context_fileTable (), stdlib));
419 }
420 }
421
422 cstring_free (libname);
423 return result;
424}
425
426/*@constant int BUFLEN;@*/
427# define BUFLEN 128
428
429static bool
430loadLCDFile (FILE *f, cstring name)
431{
432 char buf[BUFLEN];
433
434 /*
435 ** Check version. Should be >= SPLINT_LIBVERSION
436 */
437
438 if (reader_readLine (f, buf, BUFLEN) == NULL
439 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
440 {
441 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
442 "to continue without library.", name));
443 return FALSE;
444 }
445
446 if (reader_readLine (f, buf, BUFLEN) != NULL)
447 {
448 if (!mstring_equalPrefix (buf, ";;"))
449 {
450 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
451 "to continue without library.", name));
452 return FALSE;
453 }
454 else if (mstring_equalPrefix (buf, ";;ctTable"))
455 {
456 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
457 "to continue anyway, but results may be incorrect. Rebuild "
458 "the library with this version of splint.",
459 name));
460 }
461 else
462 {
463 float version = 0.0;
464
465 if (sscanf (buf, ";;Splint %f", &version) != 1
466 && (sscanf (buf, ";;LCLint %f", &version) != 1))
467 {
468 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
469 "number). Attempting "
470 "to continue without library.", name));
471 return FALSE;
472 }
473 else
474 {
475 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
476 {
477 cstring vname;
478 char *nl = strchr (buf, '\n');
479
480 *nl = '\0';
481
482 vname = cstring_fromChars (buf + 9);
483
484 loadllmsg (message ("Load library %s is in obsolete Splint library "
485 "format (version %f (%s), expecting version %f). Attempting "
486 "to continue anyway, but results may be incorrect. Rebuild "
487 "the library with this version of splint.",
488 name,
489 version,
490 vname,
491 SPLINT_LIBVERSION));
492 }
493 else
494 {
495 if (reader_readLine (f, buf, BUFLEN) == NULL)
496 {
497 loadllmsg (message ("Load library %s is not in Splint library "
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 {
508 loadllmsg (message ("Load library %s is not in Splint library "
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 {
526 loadllmsg (message ("Load library %s has invalid library code (%s). "
527 "Attempting to continue without library.",
528 name,
529 flagcode_unparse (code)));
530
531 return FALSE;
532 }
533 }
534 }
535 }
536 }
537 }
538 }
539 else
540 {
541 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
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;
569 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
570
571 f = fileTable_openReadFile (context_fileTable (), fname);
572
573 if (f == NULL)
574 {
575 displayScanClose ();
576 llfatalerror (message ("Cannot open dump file for loading: %s",
577 fname));
578 }
579 else
580 {
581 fileloc_reallyFree (g_currentloc);
582 g_currentloc = fileloc_createLib (cfname);
583
584 if (!loadLCDFile (f, cfname))
585 {
586 if (!loadStandardState ())
587 {
588 ctype_initTable ();
589 }
590 }
591
592 check (fileTable_closeFile (context_fileTable (), f));
593 }
594
595 /* usymtab_printAll (); */
596 cstring_free (fname);
597}
598
This page took 0.143175 seconds and 5 git commands to generate.