]> andersk Git - splint.git/blame - src/lcllib.c
Fixed all /*@i...@*/ tags (except 1).
[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"
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@*/
b73d1009 230
393e573f 231 /* evans 2002-03-02:
b73d1009 232 the returned reference is possibly null,
233 but this should not change the null state of the parameter
393e573f 234 */
616915dd 235 }
236 }
237 else
238 {
239 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
240
241 voptgenerror
242 (FLG_WARNPOSIX,
1d239d69 243 message ("Include file <%s.h> matches the name of a "
616915dd 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
28bf4b0b 256 cstring_free (xname);
257 /*@noaccess cstring@*/
b73d1009 258 /*@-nullstate@*/ /* same problem as above */
616915dd 259 return FALSE;
393e573f 260 /*@=nullstate@*/
616915dd 261}
262
263static void printDot (void)
264{
80489f0a 265 displayScanContinue (cstring_makeLiteralTemp ("."));
616915dd 266}
267
268void
269dumpState (cstring cfname)
270{
271 FILE *f;
28bf4b0b 272 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 273
d5047b91 274 f = fileTable_openWriteFile (context_fileTable (), fname);
616915dd 275
80489f0a 276 displayScanOpen (message ("Dumping to %s ", fname));
616915dd 277
278 if (f == NULL)
279 {
efd360a3 280 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 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
28bf4b0b 291 /*
292 DPRINTF (("Before prepare dump:"));
293 ctype_printTable ();
294 DPRINTF (("Preparing dump..."));
295 */
296
616915dd 297 usymtab_prepareDump ();
298
299 /*
28bf4b0b 300 ** Be careful, these lines must match loadLCDFile checking.
616915dd 301 */
302
11db3170 303 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
e5081f8c 304 fprintf (f, ";;Splint %f\n", SPLINT_LIBVERSION);
616915dd 305 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
306 fprintf (f, ";;ctTable\n");
28bf4b0b 307
308 DPRINTF (("Dumping types..."));
616915dd 309 printDot ();
28bf4b0b 310 ctype_dumpTable (f);
616915dd 311 printDot ();
28bf4b0b 312
313 DPRINTF (("Dumping type sets..."));
616915dd 314 fprintf (f, ";;tistable\n");
315 typeIdSet_dumpTable (f);
316 printDot ();
28bf4b0b 317
318 DPRINTF (("Dumping usymtab..."));
319 fprintf (f, ";;symTable\n");
616915dd 320 usymtab_dump (f);
321 printDot ();
322
28bf4b0b 323 DPRINTF (("Dumping modules..."));
616915dd 324 fprintf (f, ";; Modules access\n");
325 context_dumpModuleAccess (f);
326 fprintf (f, ";;End\n");
dfd82dce 327 check (fileTable_closeFile (context_fileTable (), f));
616915dd 328 }
329
80489f0a 330 displayScanClose ();
28bf4b0b 331 cstring_free (fname);
616915dd 332}
333
334bool
335loadStandardState ()
336{
28bf4b0b 337 cstring fpath;
616915dd 338 FILE *stdlib;
339 bool result;
28bf4b0b 340 cstring libname = fileLib_addExtension (context_selectedLibrary (),
341 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 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 " : "")),
28bf4b0b 349 libname));
616915dd 350 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
351 result = FALSE;
352 }
353 else
354 {
d5047b91 355 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 356
357 if (stdlib == NULL)
358 {
359 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 360 fpath));
616915dd 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
28bf4b0b 372 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 373 {
374 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
375 }
376
28bf4b0b 377 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 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>",
28bf4b0b 388 fpath));
616915dd 389 }
390 else
391 {
392 char *tt;
393
394 tt = strrchr (t, '\n');
395 if (tt != NULL)
396 *tt = '\0';
397
28bf4b0b 398 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 399 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
400 }
401
402 sfree (ot);
403
dfd82dce 404 check (fileTable_closeFile (context_fileTable (), stdlib));
d5047b91 405 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 406 }
407
408 llassert (stdlib != NULL);
409
410 fileloc_reallyFree (g_currentloc);
28bf4b0b 411 g_currentloc = fileloc_createLib (libname);
412
413 DPRINTF (("Loading: %s", fpath));
616915dd 414
80489f0a 415 displayScanOpen (message ("loading standard library %s ", fpath));
416 result = loadLCDFile (stdlib, fpath);
417 displayScanClose ();
616915dd 418
dfd82dce 419 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 420 }
421 }
422
28bf4b0b 423 cstring_free (libname);
616915dd 424 return result;
425}
426
427/*@constant int BUFLEN;@*/
428# define BUFLEN 128
429
430static bool
28bf4b0b 431loadLCDFile (FILE *f, cstring name)
616915dd 432{
433 char buf[BUFLEN];
434
435 /*
1b8ae690 436 ** Check version. Should be >= SPLINT_LIBVERSION
616915dd 437 */
438
28bf4b0b 439 if (reader_readLine (f, buf, BUFLEN) == NULL
11db3170 440 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
616915dd 441 {
11db3170 442 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 443 "to continue without library.", name));
616915dd 444 return FALSE;
445 }
446
28bf4b0b 447 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 448 {
449 if (!mstring_equalPrefix (buf, ";;"))
450 {
11db3170 451 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 452 "to continue without library.", name));
616915dd 453 return FALSE;
454 }
455 else if (mstring_equalPrefix (buf, ";;ctTable"))
456 {
11db3170 457 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
28bf4b0b 458 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 459 "the library with this version of splint.",
28bf4b0b 460 name));
616915dd 461 }
462 else
463 {
464 float version = 0.0;
465
11db3170 466 if (sscanf (buf, ";;Splint %f", &version) != 1
467 && (sscanf (buf, ";;LCLint %f", &version) != 1))
616915dd 468 {
11db3170 469 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
28bf4b0b 470 "number). Attempting "
471 "to continue without library.", name));
616915dd 472 return FALSE;
473 }
474 else
475 {
1b8ae690 476 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 477 {
478 cstring vname;
479 char *nl = strchr (buf, '\n');
480
28bf4b0b 481 *nl = '\0';
616915dd 482
483 vname = cstring_fromChars (buf + 9);
484
1b8ae690 485 loadllmsg (message ("Load library %s is in obsolete Splint library "
e5081f8c 486 "format (version %f (%s), expecting version %f). Attempting "
616915dd 487 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 488 "the library with this version of splint.",
e5081f8c 489 name,
490 version,
491 vname,
492 SPLINT_LIBVERSION));
616915dd 493 }
494 else
495 {
28bf4b0b 496 if (reader_readLine (f, buf, BUFLEN) == NULL)
616915dd 497 {
11db3170 498 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 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 {
11db3170 509 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 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 {
28bf4b0b 527 loadllmsg (message ("Load library %s has invalid library code (%s). "
616915dd 528 "Attempting to continue without library.",
28bf4b0b 529 name,
530 flagcode_unparse (code)));
616915dd 531
532 return FALSE;
533 }
534 }
535 }
536 }
537 }
538 }
539 }
540 else
541 {
11db3170 542 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
616915dd 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;
28bf4b0b 570 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 571
d5047b91 572 f = fileTable_openReadFile (context_fileTable (), fname);
616915dd 573
574 if (f == NULL)
575 {
80489f0a 576 displayScanClose ();
28bf4b0b 577 llfatalerror (message ("Cannot open dump file for loading: %s",
578 fname));
616915dd 579 }
580 else
581 {
582 fileloc_reallyFree (g_currentloc);
28bf4b0b 583 g_currentloc = fileloc_createLib (cfname);
616915dd 584
28bf4b0b 585 if (!loadLCDFile (f, cfname))
616915dd 586 {
587 if (!loadStandardState ())
588 {
589 ctype_initTable ();
590 }
591 }
592
dfd82dce 593 check (fileTable_closeFile (context_fileTable (), f));
616915dd 594 }
595
28bf4b0b 596 /* usymtab_printAll (); */
597 cstring_free (fname);
616915dd 598}
599
This page took 0.174002 seconds and 5 git commands to generate.