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