]> andersk Git - splint.git/blame - src/lcllib.c
*** empty log message ***
[splint.git] / src / lcllib.c
CommitLineData
616915dd 1/*
2** LCLint - annotation-assisted static program checker
28bf4b0b 3** Copyright (C) 1994-2001 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**
20** For information on lclint: lclint-request@cs.virginia.edu
21** To report a bug: lclint-bug@cs.virginia.edu
22** For more information: http://lclint.cs.virginia.edu
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# include "lclintMacros.nf"
35# include "llbasic.h"
36
37# include "osd.h"
38
39# ifndef NOLCL
40# include "gram.h"
41
42# include "lclscan.h"
43# endif
44
45
46# include "herald.h"
47# include "lcllib.h"
48# include "llmain.h"
49# include "portab.h"
50
51/*@-incondefs@*/ /*@-redecl@*/
28bf4b0b 52extern /*@open@*/ /*@dependent@*/ FILE *yyin;
616915dd 53/*@=incondefs@*/ /*@=redecl@*/
54
55/*@constant int NUMLIBS; @*/
56# define NUMLIBS 17
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",
86 "ctype",
87 "errno",
88 "float",
89 "limits",
90 "locale",
91 "math",
92 "setjmp",
93 "signal",
94 "stdarg",
95 "stddef",
96 "stdio",
97 "stdlib",
98 "strings",
99 "string",
100 "time",
101 "wchar"
102} ;
103
28bf4b0b 104static bool loadLCDFile (FILE * p_f, cstring p_name);
616915dd 105
106bool
107lcllib_isSkipHeader (cstring sname)
108{
109 int i;
110 bool posixlib = FALSE;
111 char *libname;
616915dd 112 char *matchname;
28bf4b0b 113 cstring xname;
616915dd 114
115 llassert (cstring_isDefined (sname));
28bf4b0b 116 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
616915dd 117
d1eb0f0f 118 DPRINTF (("Include? %s", sname));
119
28bf4b0b 120 /*@access cstring@*/
121 llassert (cstring_isDefined (xname));
122 libname = strrchr (xname, CONNECTCHAR);
616915dd 123 matchname = libname;
124
125 if (libname == NULL)
126 {
28bf4b0b 127 libname = xname;
616915dd 128 }
129 else
130 {
131 libname++;
132 /*@-branchstate@*/
133 }
134 /*@=branchstate@*/
135
136 if (mstring_equal (libname, "varargs"))
137 {
138 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
139
140 voptgenerror
141 (FLG_USEVARARGS,
142 message ("Include file <%s> is inconsistent with "
143 "ANSI library (should use <stdarg.h>)",
144 cstring_fromChars (libname)),
145 tmp);
146
147 fileloc_free (tmp);
28bf4b0b 148 sfree (xname);
616915dd 149 return TRUE;
150 }
151
152 if (context_getFlag (FLG_SKIPANSIHEADERS)
153 && context_usingAnsiLibrary ())
154 {
155
156 for (i = 0; i < NUMLIBS; i++)
157 {
158 if (mstring_equal (libname, stdlibs[i]))
159 {
28bf4b0b 160 sfree (xname);
616915dd 161 return TRUE;
162 }
163 }
164 }
165
166 for (i = 0; i < NUMPOSIXLIBS; i++)
167 {
168 if (strchr (posixlibs[i], CONNECTCHAR) != NULL)
169 {
170 char *ptr;
171
28bf4b0b 172 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
616915dd 173 {
174 if (ptr[strlen (posixlibs[i])] == '\0')
175 {
176 posixlib = TRUE;
177 matchname = ptr;
d1eb0f0f 178 DPRINTF (("Found match: %s", matchname));
616915dd 179 break;
180 }
181 else
182 {
183 ; /* no match */
184 }
185 }
186 }
187 else
188 {
189 if (mstring_equal (libname, posixlibs[i]))
190 {
191 posixlib = TRUE;
192 matchname = libname;
193 break;
194 }
195 /*@-branchstate@*/
196 }
197 } /*@=branchstate@*/
198
199 if (posixlib)
200 {
201 if (context_usingPosixLibrary ())
202 {
203 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
204 {
d1eb0f0f 205 DPRINTF (("Skipping: %s", xname));
28bf4b0b 206 sfree (xname);
616915dd 207 return TRUE;
208 }
209 }
210 else
211 {
212 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
213
214 voptgenerror
215 (FLG_WARNPOSIX,
216 message ("Include file <%s> matches the name of a "
217 "POSIX library, but the POSIX library is "
218 "not being used. Consider using +posixlib "
219 "or +posixstrictlib to select the POSIX "
220 "library, or -warnposix "
221 "to suppress this message.",
222 cstring_fromChars (matchname)),
223 tmp);
224
225 fileloc_free (tmp);
226 }
227 }
228
28bf4b0b 229 cstring_free (xname);
230 /*@noaccess cstring@*/
616915dd 231 return FALSE;
232}
233
234static void printDot (void)
235{
236 if (context_getFlag (FLG_SHOWSCAN))
237 {
238 (void) fflush (g_msgstream);
239 fprintf (stderr, ".");
240 (void) fflush (stderr);
241 }
242}
243
244void
245dumpState (cstring cfname)
246{
247 FILE *f;
28bf4b0b 248 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 249
28bf4b0b 250 f = fopen (cstring_toCharsSafe (fname), "w");
616915dd 251
252 if (context_getFlag (FLG_SHOWSCAN))
253 {
28bf4b0b 254 fprintf (stderr, "< Dumping to %s ", cstring_toCharsSafe (fname));
616915dd 255 }
256
257 if (f == NULL)
258 {
efd360a3 259 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 260 }
261 else
262 {
263 /*
264 ** sequence is convulted --- must call usymtab_prepareDump before
265 ** dumping ctype table to convert type uid's
266 */
267
268 printDot ();
269
28bf4b0b 270 /*
271 DPRINTF (("Before prepare dump:"));
272 ctype_printTable ();
273 DPRINTF (("Preparing dump..."));
274 */
275
616915dd 276 usymtab_prepareDump ();
277
278 /*
28bf4b0b 279 ** Be careful, these lines must match loadLCDFile checking.
616915dd 280 */
281
28bf4b0b 282 fprintf (f, ";;LCLint Dump: %s\n", cstring_toCharsSafe (fname));
616915dd 283 fprintf (f, ";;%s\n", LCL_VERSION);
284 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
285 fprintf (f, ";;ctTable\n");
28bf4b0b 286
287 DPRINTF (("Dumping types..."));
616915dd 288 printDot ();
28bf4b0b 289 ctype_dumpTable (f);
616915dd 290 printDot ();
28bf4b0b 291
292 DPRINTF (("Dumping type sets..."));
616915dd 293 fprintf (f, ";;tistable\n");
294 typeIdSet_dumpTable (f);
295 printDot ();
28bf4b0b 296
297 DPRINTF (("Dumping usymtab..."));
298 fprintf (f, ";;symTable\n");
616915dd 299 usymtab_dump (f);
300 printDot ();
301
28bf4b0b 302 DPRINTF (("Dumping modules..."));
616915dd 303 fprintf (f, ";; Modules access\n");
304 context_dumpModuleAccess (f);
305 fprintf (f, ";;End\n");
306 check (fclose (f) == 0);
307 }
308
309 if (context_getFlag (FLG_SHOWSCAN))
310 {
311 fprintf (g_msgstream, " >\n");
312 }
313
28bf4b0b 314 cstring_free (fname);
616915dd 315}
316
317bool
318loadStandardState ()
319{
28bf4b0b 320 cstring fpath;
616915dd 321 FILE *stdlib;
322 bool result;
28bf4b0b 323 cstring libname = fileLib_addExtension (context_selectedLibrary (),
324 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 325
326 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
327 {
328 lldiagmsg (message ("Cannot find %sstandard library: %s",
329 cstring_makeLiteralTemp
330 (context_getFlag (FLG_STRICTLIB) ? "strict "
331 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 332 libname));
616915dd 333 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
334 result = FALSE;
335 }
336 else
337 {
28bf4b0b 338 stdlib = fopen (cstring_toCharsSafe (fpath), "r");
616915dd 339
340 if (stdlib == NULL)
341 {
342 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 343 fpath));
616915dd 344 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
345
346 result = FALSE;
347 }
348 else
349 {
350 if (context_getFlag (FLG_WHICHLIB))
351 {
352 char *t = mstring_create (MAX_NAME_LENGTH);
353 char *ot = t;
354
28bf4b0b 355 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 356 {
357 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
358 }
359
28bf4b0b 360 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 361 {
362 if (*t == ';' && *(t + 1) == ';')
363 {
364 t += 2;
365 }
366 }
367
368 if (t == NULL)
369 {
370 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 371 fpath));
616915dd 372 }
373 else
374 {
375 char *tt;
376
377 tt = strrchr (t, '\n');
378 if (tt != NULL)
379 *tt = '\0';
380
28bf4b0b 381 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 382 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
383 }
384
385 sfree (ot);
386
387 check (fclose (stdlib) == 0);
28bf4b0b 388 stdlib = fopen (cstring_toCharsSafe (fpath), "r");
616915dd 389 }
390
391 llassert (stdlib != NULL);
392
393 fileloc_reallyFree (g_currentloc);
28bf4b0b 394 g_currentloc = fileloc_createLib (libname);
395
396 DPRINTF (("Loading: %s", fpath));
616915dd 397
398 if (context_getDebug (FLG_SHOWSCAN))
399 {
28bf4b0b 400 fprintf (g_msgstream, "< loading standard library %s ",
401 cstring_toCharsSafe (fpath));
402 result = loadLCDFile (stdlib, fpath);
403 fprintf (g_msgstream, " >\n");
616915dd 404 }
405 else
406 {
28bf4b0b 407 result = loadLCDFile (stdlib, fpath);
616915dd 408 }
409
410 check (fclose (stdlib) == 0);
411 }
412 }
413
28bf4b0b 414 cstring_free (libname);
616915dd 415 return result;
416}
417
418/*@constant int BUFLEN;@*/
419# define BUFLEN 128
420
421static bool
28bf4b0b 422loadLCDFile (FILE *f, cstring name)
616915dd 423{
424 char buf[BUFLEN];
425
426 /*
28bf4b0b 427 ** Check version. Should be >= LCLINT_LIBVERSION
616915dd 428 */
429
28bf4b0b 430 if (reader_readLine (f, buf, BUFLEN) == NULL
616915dd 431 || !mstring_equalPrefix (buf, ";;LCLint Dump:"))
432 {
433 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
28bf4b0b 434 "to continue without library.", name));
616915dd 435 return FALSE;
436 }
437
28bf4b0b 438 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 439 {
440 if (!mstring_equalPrefix (buf, ";;"))
441 {
442 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
28bf4b0b 443 "to continue without library.", name));
616915dd 444 return FALSE;
445 }
446 else if (mstring_equalPrefix (buf, ";;ctTable"))
447 {
448 loadllmsg (message ("Load library %s is in obsolete LCLint library format. Attempting "
28bf4b0b 449 "to continue anyway, but results may be incorrect. Rebuild "
450 "the library with this version of lclint.",
451 name));
616915dd 452 }
453 else
454 {
455 float version = 0.0;
456
457 if (sscanf (buf, ";;LCLint %f", &version) != 1)
458 {
459 loadllmsg (message ("Load library %s is not in LCLint library format (missing version "
28bf4b0b 460 "number). Attempting "
461 "to continue without library.", name));
616915dd 462 return FALSE;
463 }
464 else
465 {
28bf4b0b 466 if ((LCLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 467 {
468 cstring vname;
469 char *nl = strchr (buf, '\n');
470
28bf4b0b 471 *nl = '\0';
616915dd 472
473 vname = cstring_fromChars (buf + 9);
474
475 loadllmsg (message ("Load library %s is in obsolete LCLint library "
476 "format (version %s). Attempting "
477 "to continue anyway, but results may be incorrect. Rebuild "
478 "the library with this version of lclint.",
479 name, vname));
480 }
481 else
482 {
28bf4b0b 483 if (reader_readLine (f, buf, BUFLEN) == NULL)
616915dd 484 {
485 loadllmsg (message ("Load library %s is not in LCLint library "
486 "format (missing library code). Attempting "
487 "to continue without library.", name));
488 return FALSE;
489 }
490 else
491 {
492 int lib;
493
494 if (sscanf (buf, ";;lib:%d", &lib) != 1)
495 {
496 loadllmsg (message ("Load library %s is not in LCLint library "
497 "format (missing library code). Attempting "
498 "to continue without library.", name));
499 return FALSE;
500 }
501 else
502 {
503 flagcode code = (flagcode) lib;
504
505 if (flagcode_isLibraryFlag (code))
506 {
507 if (context_doMerge ())
508 {
509 context_setLibrary (code);
510 }
511 }
512 else
513 {
28bf4b0b 514 loadllmsg (message ("Load library %s has invalid library code (%s). "
616915dd 515 "Attempting to continue without library.",
28bf4b0b 516 name,
517 flagcode_unparse (code)));
616915dd 518
519 return FALSE;
520 }
521 }
522 }
523 }
524 }
525 }
526 }
527 else
528 {
529 loadllmsg (message ("Load library %s is not in LCLint library format (missing lines). "
530 "Attempting to continue without library.", name));
531 return FALSE;
532 }
533
534 ctype_loadTable (f);
535 printDot ();
536
537 typeIdSet_loadTable (f);
538 printDot ();
539
540 usymtab_load (f);
541 printDot ();
542
543 context_loadModuleAccess (f);
544 printDot ();
545
546 return TRUE;
547}
548
549/*
550** load state from file created by dumpState
551*/
552
553void
554loadState (cstring cfname)
555{
556 FILE *f;
28bf4b0b 557 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 558
28bf4b0b 559 f = fopen (cstring_toCharsSafe (fname), "r");
616915dd 560
561 if (f == NULL)
562 {
563 if (context_getDebug (FLG_SHOWSCAN))
564 fprintf (g_msgstream, " >\n");
565
28bf4b0b 566 llfatalerror (message ("Cannot open dump file for loading: %s",
567 fname));
616915dd 568 }
569 else
570 {
571 fileloc_reallyFree (g_currentloc);
28bf4b0b 572 g_currentloc = fileloc_createLib (cfname);
616915dd 573
28bf4b0b 574 if (!loadLCDFile (f, cfname))
616915dd 575 {
576 if (!loadStandardState ())
577 {
578 ctype_initTable ();
579 }
580 }
581
582 check (fclose (f) == 0);
583 }
584
28bf4b0b 585 /* usymtab_printAll (); */
586 cstring_free (fname);
616915dd 587}
588
This page took 0.142804 seconds and 5 git commands to generate.