]> andersk Git - splint.git/blame - src/lcllib.c
Making fixes for Microsoft Visual C++ compiler.
[splint.git] / src / lcllib.c
CommitLineData
616915dd 1/*
11db3170 2** Splint - annotation-assisted static program checker
c59f5181 3** Copyright (C) 1994-2003 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"
b73d1009 40# include "basic.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"
616915dd 49
50/*@-incondefs@*/ /*@-redecl@*/
15b3d2b2 51extern /*:open:*/ /*@dependent@*/ FILE *yyin;
616915dd 52/*@=incondefs@*/ /*@=redecl@*/
53
54/*@constant int NUMLIBS; @*/
45569d72 55# define NUMLIBS 25
616915dd 56
57/*@constant int NUMPOSIXLIBS; @*/
d1eb0f0f 58# define NUMPOSIXLIBS 18
616915dd 59
60static ob_mstring posixlibs[NUMPOSIXLIBS] =
61{
616915dd 62 "dirent",
63 "fcntl",
64 "grp",
65 "pwd",
b072092f 66 "regex",
d1eb0f0f 67 "sys/stat",
616915dd 68 "sys/times",
d1eb0f0f 69 "sys/types",
70 "netdb", /* unix */
71 "netinet/in", /* unix */
72 "sys/resource", /* unix */
73 "sys/socket", /* not posix */
74 "sys/syslog", /* not posix */
616915dd 75 "sys/utsname",
76 "sys/wait",
77 "termios",
78 "unistd",
79 "utime"
80} ;
81
82static ob_mstring stdlibs[NUMLIBS] =
83{
84 "assert",
45569d72 85 "complex"
616915dd 86 "ctype",
87 "errno",
45569d72 88 "fenv",
89 "float",
90 "inttypes",
91 "iso646",
616915dd 92 "limits",
93 "locale",
94 "math",
95 "setjmp",
96 "signal",
97 "stdarg",
45569d72 98 "stdbool",
616915dd 99 "stddef",
45569d72 100 "stdint",
616915dd 101 "stdio",
102 "stdlib",
616915dd 103 "string",
45569d72 104 "strings", /* some systems use this...they shouldn't */
105 "tgmath",
616915dd 106 "time",
45569d72 107 "wchar",
108 "wctype"
616915dd 109} ;
110
28bf4b0b 111static bool loadLCDFile (FILE * p_f, cstring p_name);
616915dd 112
113bool
114lcllib_isSkipHeader (cstring sname)
115{
116 int i;
117 bool posixlib = FALSE;
118 char *libname;
616915dd 119 char *matchname;
28bf4b0b 120 cstring xname;
616915dd 121
122 llassert (cstring_isDefined (sname));
28bf4b0b 123 xname = fileLib_withoutExtension (sname, cstring_makeLiteralTemp (".h"));
616915dd 124
d1eb0f0f 125 DPRINTF (("Include? %s", sname));
126
28bf4b0b 127 /*@access cstring@*/
128 llassert (cstring_isDefined (xname));
7ac543fa 129# if defined (OS2)
130 {
131 /* Posixlibs use forward slashes, so we use them here, too */
132 cstring_replaceAll (xname, '\\', '/');
133 libname = strrchr (xname, '/');
134 DPRINTF (("libname: %s", libname));
135 }
136# else
28bf4b0b 137 libname = strrchr (xname, CONNECTCHAR);
7ac543fa 138# endif
616915dd 139 matchname = libname;
140
141 if (libname == NULL)
142 {
28bf4b0b 143 libname = xname;
616915dd 144 }
145 else
146 {
147 libname++;
148 /*@-branchstate@*/
149 }
150 /*@=branchstate@*/
151
152 if (mstring_equal (libname, "varargs"))
153 {
154 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
155
156 voptgenerror
157 (FLG_USEVARARGS,
1d239d69 158 message ("Include file <%s.h> is inconsistent with "
616915dd 159 "ANSI library (should use <stdarg.h>)",
160 cstring_fromChars (libname)),
161 tmp);
162
163 fileloc_free (tmp);
7ebcc5bb 164 cstring_free (xname);
616915dd 165 return TRUE;
166 }
167
abd7f895 168 if (context_getFlag (FLG_SKIPISOHEADERS)
616915dd 169 && context_usingAnsiLibrary ())
170 {
616915dd 171 for (i = 0; i < NUMLIBS; i++)
172 {
173 if (mstring_equal (libname, stdlibs[i]))
174 {
28bf4b0b 175 sfree (xname);
616915dd 176 return TRUE;
177 }
178 }
179 }
180
181 for (i = 0; i < NUMPOSIXLIBS; i++)
182 {
7ac543fa 183 if (strchr (posixlibs[i], CONNECTCHAR) != NULL
184# if defined (OS2)
185 || strchr (posixlibs[i], ALTCONNECTCHAR) != NULL
186# endif
187 )
616915dd 188 {
189 char *ptr;
190
7ac543fa 191 DPRINTF (("xname: %s, posix: %s", xname, posixlibs[i]));
28bf4b0b 192 if ((ptr = strstr (xname, posixlibs[i])) != NULL)
616915dd 193 {
194 if (ptr[strlen (posixlibs[i])] == '\0')
195 {
196 posixlib = TRUE;
197 matchname = ptr;
198 break;
199 }
200 else
201 {
202 ; /* no match */
203 }
204 }
205 }
206 else
207 {
208 if (mstring_equal (libname, posixlibs[i]))
209 {
210 posixlib = TRUE;
211 matchname = libname;
212 break;
213 }
214 /*@-branchstate@*/
215 }
216 } /*@=branchstate@*/
217
218 if (posixlib)
219 {
220 if (context_usingPosixLibrary ())
221 {
222 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
223 {
7ebcc5bb 224 cstring_free (xname);
393e573f 225 /*@-nullstate@*/
226 return TRUE;
227 /*@=nullstate@*/
b73d1009 228
393e573f 229 /* evans 2002-03-02:
b73d1009 230 the returned reference is possibly null,
231 but this should not change the null state of the parameter
393e573f 232 */
616915dd 233 }
234 }
235 else
236 {
237 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
238
239 voptgenerror
240 (FLG_WARNPOSIX,
1d239d69 241 message ("Include file <%s.h> matches the name of a "
616915dd 242 "POSIX library, but the POSIX library is "
243 "not being used. Consider using +posixlib "
244 "or +posixstrictlib to select the POSIX "
245 "library, or -warnposix "
246 "to suppress this message.",
247 cstring_fromChars (matchname)),
248 tmp);
249
250 fileloc_free (tmp);
251 }
252 }
253
28bf4b0b 254 cstring_free (xname);
255 /*@noaccess cstring@*/
b73d1009 256 /*@-nullstate@*/ /* same problem as above */
616915dd 257 return FALSE;
393e573f 258 /*@=nullstate@*/
616915dd 259}
260
261static void printDot (void)
262{
80489f0a 263 displayScanContinue (cstring_makeLiteralTemp ("."));
616915dd 264}
265
266void
267dumpState (cstring cfname)
268{
269 FILE *f;
28bf4b0b 270 cstring fname = fileLib_addExtension (cfname, cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 271
d5047b91 272 f = fileTable_openWriteFile (context_fileTable (), fname);
616915dd 273
80489f0a 274 displayScanOpen (message ("Dumping to %s ", fname));
616915dd 275
276 if (f == NULL)
277 {
efd360a3 278 lldiagmsg (message ("Cannot open dump file for writing: %s", fname));
616915dd 279 }
280 else
281 {
282 /*
283 ** sequence is convulted --- must call usymtab_prepareDump before
284 ** dumping ctype table to convert type uid's
285 */
286
287 printDot ();
288
28bf4b0b 289 /*
290 DPRINTF (("Before prepare dump:"));
291 ctype_printTable ();
292 DPRINTF (("Preparing dump..."));
293 */
294
616915dd 295 usymtab_prepareDump ();
296
297 /*
28bf4b0b 298 ** Be careful, these lines must match loadLCDFile checking.
616915dd 299 */
300
11db3170 301 fprintf (f, "%s %s\n", LIBRARY_MARKER, cstring_toCharsSafe (fname));
e5081f8c 302 fprintf (f, ";;Splint %f\n", SPLINT_LIBVERSION);
616915dd 303 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
304 fprintf (f, ";;ctTable\n");
28bf4b0b 305
306 DPRINTF (("Dumping types..."));
616915dd 307 printDot ();
28bf4b0b 308 ctype_dumpTable (f);
616915dd 309 printDot ();
28bf4b0b 310
311 DPRINTF (("Dumping type sets..."));
616915dd 312 fprintf (f, ";;tistable\n");
313 typeIdSet_dumpTable (f);
314 printDot ();
28bf4b0b 315
316 DPRINTF (("Dumping usymtab..."));
317 fprintf (f, ";;symTable\n");
616915dd 318 usymtab_dump (f);
319 printDot ();
320
28bf4b0b 321 DPRINTF (("Dumping modules..."));
616915dd 322 fprintf (f, ";; Modules access\n");
323 context_dumpModuleAccess (f);
324 fprintf (f, ";;End\n");
dfd82dce 325 check (fileTable_closeFile (context_fileTable (), f));
616915dd 326 }
327
80489f0a 328 displayScanClose ();
28bf4b0b 329 cstring_free (fname);
616915dd 330}
331
332bool
333loadStandardState ()
334{
28bf4b0b 335 cstring fpath;
616915dd 336 FILE *stdlib;
337 bool result;
28bf4b0b 338 cstring libname = fileLib_addExtension (context_selectedLibrary (),
339 cstring_makeLiteralTemp (DUMP_SUFFIX));
616915dd 340
341 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
342 {
343 lldiagmsg (message ("Cannot find %sstandard library: %s",
344 cstring_makeLiteralTemp
345 (context_getFlag (FLG_STRICTLIB) ? "strict "
346 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
28bf4b0b 347 libname));
616915dd 348 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
349 result = FALSE;
350 }
351 else
352 {
d5047b91 353 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 354
355 if (stdlib == NULL)
356 {
357 lldiagmsg (message ("Cannot read standard library: %s",
28bf4b0b 358 fpath));
616915dd 359 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
360
361 result = FALSE;
362 }
363 else
364 {
365 if (context_getFlag (FLG_WHICHLIB))
366 {
367 char *t = mstring_create (MAX_NAME_LENGTH);
368 char *ot = t;
369
28bf4b0b 370 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) == NULL)
616915dd 371 {
372 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
373 }
374
28bf4b0b 375 if ((t = reader_readLine (stdlib, t, MAX_NAME_LENGTH)) != NULL)
616915dd 376 {
377 if (*t == ';' && *(t + 1) == ';')
378 {
379 t += 2;
380 }
381 }
382
383 if (t == NULL)
384 {
385 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
28bf4b0b 386 fpath));
616915dd 387 }
388 else
389 {
390 char *tt;
391
392 tt = strrchr (t, '\n');
393 if (tt != NULL)
394 *tt = '\0';
395
28bf4b0b 396 lldiagmsg (message ("Standard library: %s", fpath));
616915dd 397 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
398 }
399
400 sfree (ot);
401
dfd82dce 402 check (fileTable_closeFile (context_fileTable (), stdlib));
d5047b91 403 stdlib = fileTable_openReadFile (context_fileTable (), fpath);
616915dd 404 }
405
406 llassert (stdlib != NULL);
407
408 fileloc_reallyFree (g_currentloc);
28bf4b0b 409 g_currentloc = fileloc_createLib (libname);
410
411 DPRINTF (("Loading: %s", fpath));
616915dd 412
80489f0a 413 displayScanOpen (message ("loading standard library %s ", fpath));
414 result = loadLCDFile (stdlib, fpath);
415 displayScanClose ();
616915dd 416
dfd82dce 417 check (fileTable_closeFile (context_fileTable (), stdlib));
616915dd 418 }
419 }
420
28bf4b0b 421 cstring_free (libname);
616915dd 422 return result;
423}
424
425/*@constant int BUFLEN;@*/
426# define BUFLEN 128
427
428static bool
28bf4b0b 429loadLCDFile (FILE *f, cstring name)
616915dd 430{
431 char buf[BUFLEN];
432
433 /*
1b8ae690 434 ** Check version. Should be >= SPLINT_LIBVERSION
616915dd 435 */
436
28bf4b0b 437 if (reader_readLine (f, buf, BUFLEN) == NULL
11db3170 438 || !mstring_equalPrefix (buf, LIBRARY_MARKER))
616915dd 439 {
11db3170 440 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 441 "to continue without library.", name));
616915dd 442 return FALSE;
443 }
444
28bf4b0b 445 if (reader_readLine (f, buf, BUFLEN) != NULL)
616915dd 446 {
447 if (!mstring_equalPrefix (buf, ";;"))
448 {
11db3170 449 loadllmsg (message ("Load library %s is not in Splint library format. Attempting "
28bf4b0b 450 "to continue without library.", name));
616915dd 451 return FALSE;
452 }
453 else if (mstring_equalPrefix (buf, ";;ctTable"))
454 {
11db3170 455 loadllmsg (message ("Load library %s is in obsolete Splint library format. Attempting "
28bf4b0b 456 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 457 "the library with this version of splint.",
28bf4b0b 458 name));
616915dd 459 }
460 else
461 {
462 float version = 0.0;
463
11db3170 464 if (sscanf (buf, ";;Splint %f", &version) != 1
465 && (sscanf (buf, ";;LCLint %f", &version) != 1))
616915dd 466 {
11db3170 467 loadllmsg (message ("Load library %s is not in Splint library format (missing version "
28bf4b0b 468 "number). Attempting "
469 "to continue without library.", name));
616915dd 470 return FALSE;
471 }
472 else
473 {
1b8ae690 474 if ((SPLINT_LIBVERSION - version) >= FLT_EPSILON)
616915dd 475 {
476 cstring vname;
477 char *nl = strchr (buf, '\n');
478
28bf4b0b 479 *nl = '\0';
616915dd 480
481 vname = cstring_fromChars (buf + 9);
482
1b8ae690 483 loadllmsg (message ("Load library %s is in obsolete Splint library "
e5081f8c 484 "format (version %f (%s), expecting version %f). Attempting "
616915dd 485 "to continue anyway, but results may be incorrect. Rebuild "
1b8ae690 486 "the library with this version of splint.",
e5081f8c 487 name,
488 version,
489 vname,
490 SPLINT_LIBVERSION));
616915dd 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.222557 seconds and 5 git commands to generate.