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