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