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