]> andersk Git - splint.git/blame - src/lcllib.c
Integrated Herbert Martin Dietze's changes for OS/2.
[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
171 if (context_getFlag (FLG_SKIPANSIHEADERS)
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);
616915dd 229 return TRUE;
230 }
231 }
232 else
233 {
234 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
235
236 voptgenerror
237 (FLG_WARNPOSIX,
1d239d69 238 message ("Include file <%s.h> matches the name of a "
616915dd 239 "POSIX library, but the POSIX library is "
240 "not being used. Consider using +posixlib "
241 "or +posixstrictlib to select the POSIX "
242 "library, or -warnposix "
243 "to suppress this message.",
244 cstring_fromChars (matchname)),
245 tmp);
246
247 fileloc_free (tmp);
248 }
249 }
250
28bf4b0b 251 cstring_free (xname);
252 /*@noaccess cstring@*/
616915dd 253 return FALSE;
254}
255
256static void printDot (void)
257{
258 if (context_getFlag (FLG_SHOWSCAN))
259 {
260 (void) fflush (g_msgstream);
261 fprintf (stderr, ".");
262 (void) fflush (stderr);
263 }
264}
265
266void
267dumpState (cstring cfname)
268{
269 FILE *f;
28bf4b0b 270 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 271
dfd82dce 272 f = fileTable_openFile (context_fileTable (), fname, "w");
616915dd 273
274 if (context_getFlag (FLG_SHOWSCAN))
275 {
28bf4b0b 276 fprintf (stderr, "< Dumping to %s ", cstring_toCharsSafe (fname));
616915dd 277 }
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
331 if (context_getFlag (FLG_SHOWSCAN))
332 {
333 fprintf (g_msgstream, " >\n");
334 }
335
28bf4b0b 336 cstring_free (fname);
616915dd 337}
338
339bool
340loadStandardState ()
341{
28bf4b0b 342 cstring fpath;
616915dd 343 FILE *stdlib;
344 bool result;
28bf4b0b 345 cstring libname = fileLib_addExtension (context_selectedLibrary (),
346 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 347
348 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
349 {
350 lldiagmsg (message ("Cannot find %sstandard library: %s",
351 cstring_makeLiteralTemp
352 (context_getFlag (FLG_STRICTLIB) ? "strict "
353 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 354 libname));
616915dd 355 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
356 result = FALSE;
357 }
358 else
359 {
dfd82dce 360 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
616915dd 361
362 if (stdlib == NULL)
363 {
364 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 365 fpath));
616915dd 366 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
367
368 result = FALSE;
369 }
370 else
371 {
372 if (context_getFlag (FLG_WHICHLIB))
373 {
374 char *t = mstring_create (MAX_NAME_LENGTH);
375 char *ot = t;
376
28bf4b0b 377 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 378 {
379 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
380 }
381
28bf4b0b 382 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 383 {
384 if (*t == ';' && *(t + 1) == ';')
385 {
386 t += 2;
387 }
388 }
389
390 if (t == NULL)
391 {
392 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 393 fpath));
616915dd 394 }
395 else
396 {
397 char *tt;
398
399 tt = strrchr (t, '\n');
400 if (tt != NULL)
401 *tt = '\0';
402
28bf4b0b 403 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 404 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
405 }
406
407 sfree (ot);
408
dfd82dce 409 check (fileTable_closeFile (context_fileTable (), stdlib));
410 stdlib = fileTable_openFile (context_fileTable (), fpath, "r");
616915dd 411 }
412
413 llassert (stdlib != NULL);
414
415 fileloc_reallyFree (g_currentloc);
28bf4b0b 416 g_currentloc = fileloc_createLib (libname);
417
418 DPRINTF (("Loading: %s", fpath));
616915dd 419
420 if (context_getDebug (FLG_SHOWSCAN))
421 {
28bf4b0b 422 fprintf (g_msgstream, "< loading standard library %s ",
423 cstring_toCharsSafe (fpath));
424 result = loadLCDFile (stdlib, fpath);
425 fprintf (g_msgstream, " >\n");
616915dd 426 }
427 else
428 {
28bf4b0b 429 result = loadLCDFile (stdlib, fpath);
616915dd 430 }
431
dfd82dce 432 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 433 }
434 }
435
28bf4b0b 436 cstring_free (libname);
616915dd 437 return result;
438}
439
440/*@constant int BUFLEN;@*/
441# define BUFLEN 128
442
443static bool
28bf4b0b 444loadLCDFile (FILE *f, cstring name)
616915dd 445{
446 char buf[BUFLEN];
447
448 /*
1b8ae690 449 ** Check version. Should be >= SPLINT_LIBVERSION
616915dd 450 */
451
28bf4b0b 452 if (reader_readLine (f, buf, BUFLEN) == NULL
11db3170 453 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
616915dd 454 {
11db3170 455 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 456 "to continue without library.", name));
616915dd 457 return FALSE;
458 }
459
28bf4b0b 460 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 461 {
462 if (!mstring_equalPrefix (buf, ";;"))
463 {
11db3170 464 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 465 "to continue without library.", name));
616915dd 466 return FALSE;
467 }
468 else if (mstring_equalPrefix (buf, ";;ctTable"))
469 {
11db3170 470 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
28bf4b0b 471 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 472 "the library with this version of splint.",
28bf4b0b 473 name));
616915dd 474 }
475 else
476 {
477 float version = 0.0;
478
11db3170 479 if (sscanf (buf, ";;Splint %f", &version) != 1
480 && (sscanf (buf, ";;LCLint %f", &version) != 1))
616915dd 481 {
11db3170 482 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
28bf4b0b 483 "number). Attempting "
484 "to continue without library.", name));
616915dd 485 return FALSE;
486 }
487 else
488 {
1b8ae690 489 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 490 {
491 cstring vname;
492 char *nl = strchr (buf, '\n');
493
28bf4b0b 494 *nl = '\0';
616915dd 495
496 vname = cstring_fromChars (buf + 9);
497
1b8ae690 498 loadllmsg (message ("Load library %s is in obsolete Splint library "
616915dd 499 "format (version %s). Attempting "
500 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 501 "the library with this version of splint.",
616915dd 502 name, vname));
503 }
504 else
505 {
28bf4b0b 506 if (reader_readLine (f, buf, BUFLEN) == NULL)
616915dd 507 {
11db3170 508 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 509 "format (missing library code). Attempting "
510 "to continue without library.", name));
511 return FALSE;
512 }
513 else
514 {
515 int lib;
516
517 if (sscanf (buf, ";;lib:%d", &lib) != 1)
518 {
11db3170 519 loadllmsg (message ("Load library %s is not in Splint library "
616915dd 520 "format (missing library code). Attempting "
521 "to continue without library.", name));
522 return FALSE;
523 }
524 else
525 {
526 flagcode code = (flagcode) lib;
527
528 if (flagcode_isLibraryFlag (code))
529 {
530 if (context_doMerge ())
531 {
532 context_setLibrary (code);
533 }
534 }
535 else
536 {
28bf4b0b 537 loadllmsg (message ("Load library %s has invalid library code (%s). "
616915dd 538 "Attempting to continue without library.",
28bf4b0b 539 name,
540 flagcode_unparse (code)));
616915dd 541
542 return FALSE;
543 }
544 }
545 }
546 }
547 }
548 }
549 }
550 else
551 {
11db3170 552 loadllmsg (message ("Load library %s is not in Splint library format (missing lines). "
616915dd 553 "Attempting to continue without library.", name));
554 return FALSE;
555 }
556
557 ctype_loadTable (f);
558 printDot ();
559
560 typeIdSet_loadTable (f);
561 printDot ();
562
563 usymtab_load (f);
564 printDot ();
565
566 context_loadModuleAccess (f);
567 printDot ();
568
569 return TRUE;
570}
571
572/*
573** load state from file created by dumpState
574*/
575
576void
577loadState (cstring cfname)
578{
579 FILE *f;
28bf4b0b 580 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 581
dfd82dce 582 f = fileTable_openFile (context_fileTable (), fname, "r");
616915dd 583
584 if (f == NULL)
585 {
586 if (context_getDebug (FLG_SHOWSCAN))
587 fprintf (g_msgstream, " >\n");
588
28bf4b0b 589 llfatalerror (message ("Cannot open dump file for loading: %s",
590 fname));
616915dd 591 }
592 else
593 {
594 fileloc_reallyFree (g_currentloc);
28bf4b0b 595 g_currentloc = fileloc_createLib (cfname);
616915dd 596
28bf4b0b 597 if (!loadLCDFile (f, cfname))
616915dd 598 {
599 if (!loadStandardState ())
600 {
601 ctype_initTable ();
602 }
603 }
604
dfd82dce 605 check (fileTable_closeFile (context_fileTable (), f));
616915dd 606 }
607
28bf4b0b 608 /* usymtab_printAll (); */
609 cstring_free (fname);
616915dd 610}
611
This page took 0.150788 seconds and 5 git commands to generate.