]> andersk Git - splint.git/blame - src/lcllib.c
Changed library version constant.\a
[splint.git] / src / lcllib.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
77d37419 3** Copyright (C) 1994-2002 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"
42
43# ifndef NOLCL
44# include "gram.h"
45
46# include "lclscan.h"
47# endif
48
616915dd 49# include "lcllib.h"
50# include "llmain.h"
51# include "portab.h"
52
53/*@-incondefs@*/ /*@-redecl@*/
15b3d2b2 54extern /*:open:*/ /*@dependent@*/ FILE *yyin;
616915dd 55/*@=incondefs@*/ /*@=redecl@*/
56
57/*@constant int NUMLIBS; @*/
45569d72 58# define NUMLIBS 25
616915dd 59
60/*@constant int NUMPOSIXLIBS; @*/
d1eb0f0f 61# define NUMPOSIXLIBS 18
616915dd 62
63static ob_mstring posixlibs[NUMPOSIXLIBS] =
64{
616915dd 65 "dirent",
66 "fcntl",
67 "grp",
68 "pwd",
b072092f 69 "regex",
d1eb0f0f 70 "sys/stat",
616915dd 71 "sys/times",
d1eb0f0f 72 "sys/types",
73 "netdb", /* unix */
74 "netinet/in", /* unix */
75 "sys/resource", /* unix */
76 "sys/socket", /* not posix */
77 "sys/syslog", /* not posix */
616915dd 78 "sys/utsname",
79 "sys/wait",
80 "termios",
81 "unistd",
82 "utime"
83} ;
84
85static ob_mstring stdlibs[NUMLIBS] =
86{
87 "assert",
45569d72 88 "complex"
616915dd 89 "ctype",
90 "errno",
45569d72 91 "fenv",
92 "float",
93 "inttypes",
94 "iso646",
616915dd 95 "limits",
96 "locale",
97 "math",
98 "setjmp",
99 "signal",
100 "stdarg",
45569d72 101 "stdbool",
616915dd 102 "stddef",
45569d72 103 "stdint",
616915dd 104 "stdio",
105 "stdlib",
616915dd 106 "string",
45569d72 107 "strings", /* some systems use this...they shouldn't */
108 "tgmath",
616915dd 109 "time",
45569d72 110 "wchar",
111 "wctype"
616915dd 112} ;
113
28bf4b0b 114static bool loadLCDFile (FILE * p_f, cstring p_name);
616915dd 115
116bool
117lcllib_isSkipHeader (cstring sname)
118{
119 int i;
120 bool posixlib = FALSE;
121 char *libname;
616915dd 122 char *matchname;
28bf4b0b 123 cstring xname;
616915dd 124
125 llassert (cstring_isDefined (sname));
28bf4b0b 126 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
616915dd 127
d1eb0f0f 128 DPRINTF (("Include? %s", sname));
129
28bf4b0b 130 /*@access cstring@*/
131 llassert (cstring_isDefined (xname));
7ac543fa 132# if defined (OS2)
133 {
134 /* Posixlibs use forward slashes, so we use them here, too */
135 cstring_replaceAll (xname, '\\', '/');
136 libname = strrchr (xname, '/');
137 DPRINTF (("libname: %s", libname));
138 }
139# else
28bf4b0b 140 libname = strrchr (xname, CONNECTCHAR);
7ac543fa 141# endif
616915dd 142 matchname = libname;
143
144 if (libname == NULL)
145 {
28bf4b0b 146 libname = xname;
616915dd 147 }
148 else
149 {
150 libname++;
151 /*@-branchstate@*/
152 }
153 /*@=branchstate@*/
154
155 if (mstring_equal (libname, "varargs"))
156 {
157 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
158
159 voptgenerror
160 (FLG_USEVARARGS,
1d239d69 161 message ("Include file <%s.h> is inconsistent with "
616915dd 162 "ANSI library (should use <stdarg.h>)",
163 cstring_fromChars (libname)),
164 tmp);
165
166 fileloc_free (tmp);
7ebcc5bb 167 cstring_free (xname);
616915dd 168 return TRUE;
169 }
170
abd7f895 171 if (context_getFlag (FLG_SKIPISOHEADERS)
616915dd 172 && context_usingAnsiLibrary ())
173 {
174
175 for (i = 0; i < NUMLIBS; i++)
176 {
177 if (mstring_equal (libname, stdlibs[i]))
178 {
28bf4b0b 179 sfree (xname);
616915dd 180 return TRUE;
181 }
182 }
183 }
184
185 for (i = 0; i < NUMPOSIXLIBS; i++)
186 {
7ac543fa 187 if (strchr (posixlibs[i], CONNECTCHAR) != NULL
188# if defined (OS2)
189 || strchr (posixlibs[i], ALTCONNECTCHAR) != NULL
190# endif
191 )
616915dd 192 {
193 char *ptr;
194
7ac543fa 195 DPRINTF (("xname: %s, posix: %s", xname, posixlibs[i]));
28bf4b0b 196 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
616915dd 197 {
198 if (ptr[strlen (posixlibs[i])] == '\0')
199 {
200 posixlib = TRUE;
201 matchname = ptr;
202 break;
203 }
204 else
205 {
206 ; /* no match */
207 }
208 }
209 }
210 else
211 {
212 if (mstring_equal (libname, posixlibs[i]))
213 {
214 posixlib = TRUE;
215 matchname = libname;
216 break;
217 }
218 /*@-branchstate@*/
219 }
220 } /*@=branchstate@*/
221
222 if (posixlib)
223 {
224 if (context_usingPosixLibrary ())
225 {
226 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
227 {
7ebcc5bb 228 cstring_free (xname);
393e573f 229 /*@-nullstate@*/
230 return TRUE;
231 /*@=nullstate@*/
232 /*@i233@*/
233 /* evans 2002-03-02:
234 the returned reference is possibly null,
235 but this should not change the null state of the parameter
236 investigate this warning
237 */
616915dd 238 }
239 }
240 else
241 {
242 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
243
244 voptgenerror
245 (FLG_WARNPOSIX,
1d239d69 246 message ("Include file <%s.h> matches the name of a "
616915dd 247 "POSIX library, but the POSIX library is "
248 "not being used. Consider using +posixlib "
249 "or +posixstrictlib to select the POSIX "
250 "library, or -warnposix "
251 "to suppress this message.",
252 cstring_fromChars (matchname)),
253 tmp);
254
255 fileloc_free (tmp);
256 }
257 }
258
28bf4b0b 259 cstring_free (xname);
260 /*@noaccess cstring@*/
393e573f 261 /*@-nullstate@*/ /*@i233@*/ /* same problem as above */
616915dd 262 return FALSE;
393e573f 263 /*@=nullstate@*/
616915dd 264}
265
266static void printDot (void)
267{
80489f0a 268 displayScanContinue (cstring_makeLiteralTemp ("."));
616915dd 269}
270
271void
272dumpState (cstring cfname)
273{
274 FILE *f;
28bf4b0b 275 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 276
d5047b91 277 f = fileTable_openWriteFile (context_fileTable (), fname);
616915dd 278
80489f0a 279 displayScanOpen (message ("Dumping to %s ", fname));
616915dd 280
281 if (f == NULL)
282 {
efd360a3 283 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 284 }
285 else
286 {
287 /*
288 ** sequence is convulted --- must call usymtab_prepareDump before
289 ** dumping ctype table to convert type uid's
290 */
291
292 printDot ();
293
28bf4b0b 294 /*
295 DPRINTF (("Before prepare dump:"));
296 ctype_printTable ();
297 DPRINTF (("Preparing dump..."));
298 */
299
616915dd 300 usymtab_prepareDump ();
301
302 /*
28bf4b0b 303 ** Be careful, these lines must match loadLCDFile checking.
616915dd 304 */
305
11db3170 306 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
60868d40 307 fprintf (f, ";;%s\n", SPLINT_VERSION);
616915dd 308 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
309 fprintf (f, ";;ctTable\n");
28bf4b0b 310
311 DPRINTF (("Dumping types..."));
616915dd 312 printDot ();
28bf4b0b 313 ctype_dumpTable (f);
616915dd 314 printDot ();
28bf4b0b 315
316 DPRINTF (("Dumping type sets..."));
616915dd 317 fprintf (f, ";;tistable\n");
318 typeIdSet_dumpTable (f);
319 printDot ();
28bf4b0b 320
321 DPRINTF (("Dumping usymtab..."));
322 fprintf (f, ";;symTable\n");
616915dd 323 usymtab_dump (f);
324 printDot ();
325
28bf4b0b 326 DPRINTF (("Dumping modules..."));
616915dd 327 fprintf (f, ";; Modules access\n");
328 context_dumpModuleAccess (f);
329 fprintf (f, ";;End\n");
dfd82dce 330 check (fileTable_closeFile (context_fileTable (), f));
616915dd 331 }
332
80489f0a 333 displayScanClose ();
28bf4b0b 334 cstring_free (fname);
616915dd 335}
336
337bool
338loadStandardState ()
339{
28bf4b0b 340 cstring fpath;
616915dd 341 FILE *stdlib;
342 bool result;
28bf4b0b 343 cstring libname = fileLib_addExtension (context_selectedLibrary (),
344 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 345
346 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
347 {
348 lldiagmsg (message ("Cannot find %sstandard library: %s",
349 cstring_makeLiteralTemp
350 (context_getFlag (FLG_STRICTLIB) ? "strict "
351 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 352 libname));
616915dd 353 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
354 result = FALSE;
355 }
356 else
357 {
d5047b91 358 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 359
360 if (stdlib == NULL)
361 {
362 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 363 fpath));
616915dd 364 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
365
366 result = FALSE;
367 }
368 else
369 {
370 if (context_getFlag (FLG_WHICHLIB))
371 {
372 char *t = mstring_create (MAX_NAME_LENGTH);
373 char *ot = t;
374
28bf4b0b 375 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 376 {
377 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
378 }
379
28bf4b0b 380 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 381 {
382 if (*t == ';' && *(t + 1) == ';')
383 {
384 t += 2;
385 }
386 }
387
388 if (t == NULL)
389 {
390 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 391 fpath));
616915dd 392 }
393 else
394 {
395 char *tt;
396
397 tt = strrchr (t, '\n');
398 if (tt != NULL)
399 *tt = '\0';
400
28bf4b0b 401 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 402 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
403 }
404
405 sfree (ot);
406
dfd82dce 407 check (fileTable_closeFile (context_fileTable (), stdlib));
d5047b91 408 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 409 }
410
411 llassert (stdlib != NULL);
412
413 fileloc_reallyFree (g_currentloc);
28bf4b0b 414 g_currentloc = fileloc_createLib (libname);
415
416 DPRINTF (("Loading: %s", fpath));
616915dd 417
80489f0a 418 displayScanOpen (message ("loading standard library %s ", fpath));
419 result = loadLCDFile (stdlib, fpath);
420 displayScanClose ();
616915dd 421
dfd82dce 422 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 423 }
424 }
425
28bf4b0b 426 cstring_free (libname);
616915dd 427 return result;
428}
429
430/*@constant int BUFLEN;@*/
431# define BUFLEN 128
432
433static bool
28bf4b0b 434loadLCDFile (FILE *f, cstring name)
616915dd 435{
436 char buf[BUFLEN];
437
438 /*
1b8ae690 439 ** Check version. Should be >= SPLINT_LIBVERSION
616915dd 440 */
441
28bf4b0b 442 if (reader_readLine (f, buf, BUFLEN) == NULL
11db3170 443 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
616915dd 444 {
11db3170 445 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 446 "to continue without library.", name));
616915dd 447 return FALSE;
448 }
449
28bf4b0b 450 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 451 {
452 if (!mstring_equalPrefix (buf, ";;"))
453 {
11db3170 454 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 455 "to continue without library.", name));
616915dd 456 return FALSE;
457 }
458 else if (mstring_equalPrefix (buf, ";;ctTable"))
459 {
11db3170 460 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
28bf4b0b 461 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 462 "the library with this version of splint.",
28bf4b0b 463 name));
616915dd 464 }
465 else
466 {
467 float version = 0.0;
468
11db3170 469 if (sscanf (buf, ";;Splint %f", &version) != 1
470 && (sscanf (buf, ";;LCLint %f", &version) != 1))
616915dd 471 {
11db3170 472 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
28bf4b0b 473 "number). Attempting "
474 "to continue without library.", name));
616915dd 475 return FALSE;
476 }
477 else
478 {
1b8ae690 479 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 480 {
481 cstring vname;
482 char *nl = strchr (buf, '\n');
483
28bf4b0b 484 *nl = '\0';
616915dd 485
486 vname = cstring_fromChars (buf + 9);
487
1b8ae690 488 loadllmsg (message ("Load library %s is in obsolete Splint library "
616915dd 489 "format (version %s). Attempting "
490 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 491 "the library with this version of splint.",
616915dd 492 name, vname));
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 1.228375 seconds and 5 git commands to generate.