]> andersk Git - splint.git/blame - src/lcllib.c
This file is updated. And is no longer used to determine Splint's version number.
[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"
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@*/
230 /*@i233@*/
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 investigate this warning
235 */
616915dd 236 }
237 }
238 else
239 {
240 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
241
242 voptgenerror
243 (FLG_WARNPOSIX,
1d239d69 244 message ("Include file <%s.h> matches the name of a "
616915dd 245 "POSIX library, but the POSIX library is "
246 "not being used. Consider using +posixlib "
247 "or +posixstrictlib to select the POSIX "
248 "library, or -warnposix "
249 "to suppress this message.",
250 cstring_fromChars (matchname)),
251 tmp);
252
253 fileloc_free (tmp);
254 }
255 }
256
28bf4b0b 257 cstring_free (xname);
258 /*@noaccess cstring@*/
393e573f 259 /*@-nullstate@*/ /*@i233@*/ /* same problem as above */
616915dd 260 return FALSE;
393e573f 261 /*@=nullstate@*/
616915dd 262}
263
264static void printDot (void)
265{
80489f0a 266 displayScanContinue (cstring_makeLiteralTemp ("."));
616915dd 267}
268
269void
270dumpState (cstring cfname)
271{
272 FILE *f;
28bf4b0b 273 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 274
d5047b91 275 f = fileTable_openWriteFile (context_fileTable (), fname);
616915dd 276
80489f0a 277 displayScanOpen (message ("Dumping to %s ", fname));
616915dd 278
279 if (f == NULL)
280 {
efd360a3 281 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 282 }
283 else
284 {
285 /*
286 ** sequence is convulted --- must call usymtab_prepareDump before
287 ** dumping ctype table to convert type uid's
288 */
289
290 printDot ();
291
28bf4b0b 292 /*
293 DPRINTF (("Before prepare dump:"));
294 ctype_printTable ();
295 DPRINTF (("Preparing dump..."));
296 */
297
616915dd 298 usymtab_prepareDump ();
299
300 /*
28bf4b0b 301 ** Be careful, these lines must match loadLCDFile checking.
616915dd 302 */
303
11db3170 304 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
60868d40 305 fprintf (f, ";;%s\n", SPLINT_VERSION);
616915dd 306 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
307 fprintf (f, ";;ctTable\n");
28bf4b0b 308
309 DPRINTF (("Dumping types..."));
616915dd 310 printDot ();
28bf4b0b 311 ctype_dumpTable (f);
616915dd 312 printDot ();
28bf4b0b 313
314 DPRINTF (("Dumping type sets..."));
616915dd 315 fprintf (f, ";;tistable\n");
316 typeIdSet_dumpTable (f);
317 printDot ();
28bf4b0b 318
319 DPRINTF (("Dumping usymtab..."));
320 fprintf (f, ";;symTable\n");
616915dd 321 usymtab_dump (f);
322 printDot ();
323
28bf4b0b 324 DPRINTF (("Dumping modules..."));
616915dd 325 fprintf (f, ";; Modules access\n");
326 context_dumpModuleAccess (f);
327 fprintf (f, ";;End\n");
dfd82dce 328 check (fileTable_closeFile (context_fileTable (), f));
616915dd 329 }
330
80489f0a 331 displayScanClose ();
28bf4b0b 332 cstring_free (fname);
616915dd 333}
334
335bool
336loadStandardState ()
337{
28bf4b0b 338 cstring fpath;
616915dd 339 FILE *stdlib;
340 bool result;
28bf4b0b 341 cstring libname = fileLib_addExtension (context_selectedLibrary (),
342 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 343
344 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
345 {
346 lldiagmsg (message ("Cannot find %sstandard library: %s",
347 cstring_makeLiteralTemp
348 (context_getFlag (FLG_STRICTLIB) ? "strict "
349 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 350 libname));
616915dd 351 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
352 result = FALSE;
353 }
354 else
355 {
d5047b91 356 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 357
358 if (stdlib == NULL)
359 {
360 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 361 fpath));
616915dd 362 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
363
364 result = FALSE;
365 }
366 else
367 {
368 if (context_getFlag (FLG_WHICHLIB))
369 {
370 char *t = mstring_create (MAX_NAME_LENGTH);
371 char *ot = t;
372
28bf4b0b 373 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 374 {
375 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
376 }
377
28bf4b0b 378 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 379 {
380 if (*t == ';' && *(t + 1) == ';')
381 {
382 t += 2;
383 }
384 }
385
386 if (t == NULL)
387 {
388 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 389 fpath));
616915dd 390 }
391 else
392 {
393 char *tt;
394
395 tt = strrchr (t, '\n');
396 if (tt != NULL)
397 *tt = '\0';
398
28bf4b0b 399 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 400 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
401 }
402
403 sfree (ot);
404
dfd82dce 405 check (fileTable_closeFile (context_fileTable (), stdlib));
d5047b91 406 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 407 }
408
409 llassert (stdlib != NULL);
410
411 fileloc_reallyFree (g_currentloc);
28bf4b0b 412 g_currentloc = fileloc_createLib (libname);
413
414 DPRINTF (("Loading: %s", fpath));
616915dd 415
80489f0a 416 displayScanOpen (message ("loading standard library %s ", fpath));
417 result = loadLCDFile (stdlib, fpath);
418 displayScanClose ();
616915dd 419
dfd82dce 420 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 421 }
422 }
423
28bf4b0b 424 cstring_free (libname);
616915dd 425 return result;
426}
427
428/*@constant int BUFLEN;@*/
429# define BUFLEN 128
430
431static bool
28bf4b0b 432loadLCDFile (FILE *f, cstring name)
616915dd 433{
434 char buf[BUFLEN];
435
436 /*
1b8ae690 437 ** Check version. Should be >= SPLINT_LIBVERSION
616915dd 438 */
439
28bf4b0b 440 if (reader_readLine (f, buf, BUFLEN) == NULL
11db3170 441 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
616915dd 442 {
11db3170 443 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 444 "to continue without library.", name));
616915dd 445 return FALSE;
446 }
447
28bf4b0b 448 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 449 {
450 if (!mstring_equalPrefix (buf, ";;"))
451 {
11db3170 452 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 453 "to continue without library.", name));
616915dd 454 return FALSE;
455 }
456 else if (mstring_equalPrefix (buf, ";;ctTable"))
457 {
11db3170 458 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
28bf4b0b 459 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 460 "the library with this version of splint.",
28bf4b0b 461 name));
616915dd 462 }
463 else
464 {
465 float version = 0.0;
466
11db3170 467 if (sscanf (buf, ";;Splint %f", &version) != 1
468 && (sscanf (buf, ";;LCLint %f", &version) != 1))
616915dd 469 {
11db3170 470 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
28bf4b0b 471 "number). Attempting "
472 "to continue without library.", name));
616915dd 473 return FALSE;
474 }
475 else
476 {
1b8ae690 477 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 478 {
479 cstring vname;
480 char *nl = strchr (buf, '\n');
481
28bf4b0b 482 *nl = '\0';
616915dd 483
484 vname = cstring_fromChars (buf + 9);
485
1b8ae690 486 loadllmsg (message ("Load library %s is in obsolete Splint library "
616915dd 487 "format (version %s). Attempting "
488 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 489 "the library with this version of splint.",
616915dd 490 name, vname));
491 }
492 else
493 {
28bf4b0b 494 if (reader_readLine (f, buf, BUFLEN) == NULL)
616915dd 495 {
11db3170 496 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 497 "format (missing library code). Attempting "
498 "to continue without library.", name));
499 return FALSE;
500 }
501 else
502 {
503 int lib;
504
505 if (sscanf (buf, ";;lib:%d", &lib) != 1)
506 {
11db3170 507 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 508 "format (missing library code). Attempting "
509 "to continue without library.", name));
510 return FALSE;
511 }
512 else
513 {
514 flagcode code = (flagcode) lib;
515
516 if (flagcode_isLibraryFlag (code))
517 {
518 if (context_doMerge ())
519 {
520 context_setLibrary (code);
521 }
522 }
523 else
524 {
28bf4b0b 525 loadllmsg (message ("Load library %s has invalid library code (%s). "
616915dd 526 "Attempting to continue without library.",
28bf4b0b 527 name,
528 flagcode_unparse (code)));
616915dd 529
530 return FALSE;
531 }
532 }
533 }
534 }
535 }
536 }
537 }
538 else
539 {
11db3170 540 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
616915dd 541 "Attempting to continue without library.", name));
542 return FALSE;
543 }
544
545 ctype_loadTable (f);
546 printDot ();
547
548 typeIdSet_loadTable (f);
549 printDot ();
550
551 usymtab_load (f);
552 printDot ();
553
554 context_loadModuleAccess (f);
555 printDot ();
556
557 return TRUE;
558}
559
560/*
561** load state from file created by dumpState
562*/
563
564void
565loadState (cstring cfname)
566{
567 FILE *f;
28bf4b0b 568 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 569
d5047b91 570 f = fileTable_openReadFile (context_fileTable (), fname);
616915dd 571
572 if (f == NULL)
573 {
80489f0a 574 displayScanClose ();
28bf4b0b 575 llfatalerror (message ("Cannot open dump file for loading: %s",
576 fname));
616915dd 577 }
578 else
579 {
580 fileloc_reallyFree (g_currentloc);
28bf4b0b 581 g_currentloc = fileloc_createLib (cfname);
616915dd 582
28bf4b0b 583 if (!loadLCDFile (f, cfname))
616915dd 584 {
585 if (!loadStandardState ())
586 {
587 ctype_initTable ();
588 }
589 }
590
dfd82dce 591 check (fileTable_closeFile (context_fileTable (), f));
616915dd 592 }
593
28bf4b0b 594 /* usymtab_printAll (); */
595 cstring_free (fname);
616915dd 596}
597
This page took 0.183299 seconds and 5 git commands to generate.