00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 # include "lclintMacros.nf"
00035 # include "llbasic.h"
00036
00037 # include "osd.h"
00038
00039 # ifndef NOLCL
00040 # include "gram.h"
00041
00042 # include "lclscan.h"
00043 # endif
00044
00045
00046 # include "herald.h"
00047 # include "lcllib.h"
00048 # include "llmain.h"
00049 # include "portab.h"
00050
00051
00052 extern FILE *yyin;
00053
00054
00055
00056 # define NUMLIBS 17
00057
00058
00059 # define NUMPOSIXLIBS 12
00060
00061 static ob_mstring posixlibs[NUMPOSIXLIBS] =
00062 {
00063 "sys/stat",
00064 "sys/types",
00065 "dirent",
00066 "fcntl",
00067 "grp",
00068 "pwd",
00069 "sys/times",
00070 "sys/utsname",
00071 "sys/wait",
00072 "termios",
00073 "unistd",
00074 "utime"
00075 } ;
00076
00077 static ob_mstring stdlibs[NUMLIBS] =
00078 {
00079 "assert",
00080 "ctype",
00081 "errno",
00082 "float",
00083 "limits",
00084 "locale",
00085 "math",
00086 "setjmp",
00087 "signal",
00088 "stdarg",
00089 "stddef",
00090 "stdio",
00091 "stdlib",
00092 "strings",
00093 "string",
00094 "time",
00095 "wchar"
00096 } ;
00097
00098 static bool loadStateFile (FILE * p_f, cstring p_name);
00099
00100 bool
00101 lcllib_isSkipHeader (cstring sname)
00102 {
00103 int i;
00104 bool posixlib = FALSE;
00105 char *libname;
00106 char *name = cstring_toCharsSafe (sname);
00107 char *matchname;
00108
00109 llassert (cstring_isDefined (sname));
00110 name = removeExtension (name, ".h");
00111
00112 libname = strrchr (name, CONNECTCHAR);
00113 matchname = libname;
00114
00115 if (libname == NULL)
00116 {
00117 libname = name;
00118 }
00119 else
00120 {
00121 libname++;
00122
00123 }
00124
00125
00126 if (mstring_equal (libname, "varargs"))
00127 {
00128 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
00129
00130 voptgenerror
00131 (FLG_USEVARARGS,
00132 message ("Include file <%s> is inconsistent with "
00133 "ANSI library (should use <stdarg.h>)",
00134 cstring_fromChars (libname)),
00135 tmp);
00136
00137 fileloc_free (tmp);
00138 sfree (name);
00139 return TRUE;
00140 }
00141
00142 if (context_getFlag (FLG_SKIPANSIHEADERS)
00143 && context_usingAnsiLibrary ())
00144 {
00145
00146 for (i = 0; i < NUMLIBS; i++)
00147 {
00148 if (mstring_equal (libname, stdlibs[i]))
00149 {
00150 sfree (name);
00151 return TRUE;
00152 }
00153 }
00154 }
00155
00156 for (i = 0; i < NUMPOSIXLIBS; i++)
00157 {
00158 if (strchr (posixlibs[i], CONNECTCHAR) != NULL)
00159 {
00160 char *ptr;
00161
00162 if ((ptr = strstr (name, posixlibs[i])) != NULL)
00163 {
00164 if (ptr[strlen (posixlibs[i])] == '\0')
00165 {
00166 posixlib = TRUE;
00167 matchname = ptr;
00168 break;
00169 }
00170 else
00171 {
00172 ;
00173 }
00174 }
00175 }
00176 else
00177 {
00178 if (mstring_equal (libname, posixlibs[i]))
00179 {
00180 posixlib = TRUE;
00181 matchname = libname;
00182 break;
00183 }
00184
00185 }
00186 }
00187
00188 if (posixlib)
00189 {
00190 if (context_usingPosixLibrary ())
00191 {
00192 if (context_getFlag (FLG_SKIPPOSIXHEADERS))
00193 {
00194 sfree (name);
00195 return TRUE;
00196 }
00197 }
00198 else
00199 {
00200 fileloc tmp = fileloc_makePreprocPrevious (g_currentloc);
00201
00202 voptgenerror
00203 (FLG_WARNPOSIX,
00204 message ("Include file <%s> matches the name of a "
00205 "POSIX library, but the POSIX library is "
00206 "not being used. Consider using +posixlib "
00207 "or +posixstrictlib to select the POSIX "
00208 "library, or -warnposix "
00209 "to suppress this message.",
00210 cstring_fromChars (matchname)),
00211 tmp);
00212
00213 fileloc_free (tmp);
00214 }
00215 }
00216
00217 sfree (name);
00218 return FALSE;
00219 }
00220
00221 static void printDot (void)
00222 {
00223 if (context_getFlag (FLG_SHOWSCAN))
00224 {
00225 (void) fflush (g_msgstream);
00226 fprintf (stderr, ".");
00227 (void) fflush (stderr);
00228 }
00229 }
00230
00231 void
00232 dumpState (cstring cfname)
00233 {
00234 FILE *f;
00235 char *fname = cstring_toCharsSafe (cfname);
00236
00237 fname = addExtension (fname, DUMP_SUFFIX);
00238
00239 f = fopen (fname, "w");
00240
00241 if (context_getFlag (FLG_SHOWSCAN))
00242 {
00243 fprintf (stderr, "< Dumping to %s ", fname);
00244 }
00245
00246 if (f == NULL)
00247 {
00248 llgloberror (message ("Cannot open dump file for writing: %s", cfname));
00249 }
00250 else
00251 {
00252
00253
00254
00255
00256
00257 printDot ();
00258
00259 usymtab_prepareDump ();
00260
00261
00262
00263
00264
00265 fprintf (f, ";;LCLint Dump: %s\n", fname);
00266 fprintf (f, ";;%s\n", LCL_VERSION);
00267 fprintf (f, ";;lib:%d\n", (int) context_getLibrary ());
00268 fprintf (f, ";;ctTable\n");
00269
00270 printDot ();
00271 ctype_dumpTable (f);
00272 printDot ();
00273
00274 fprintf (f, ";;tistable\n");
00275 typeIdSet_dumpTable (f);
00276 printDot ();
00277
00278 fprintf (f, ";;symTable\n");
00279 usymtab_dump (f);
00280 printDot ();
00281
00282 fprintf (f, ";; Modules access\n");
00283 context_dumpModuleAccess (f);
00284 fprintf (f, ";;End\n");
00285 check (fclose (f) == 0);
00286 }
00287
00288 if (context_getFlag (FLG_SHOWSCAN))
00289 {
00290 fprintf (g_msgstream, " >\n");
00291 }
00292
00293 sfree (fname);
00294 }
00295
00296 bool
00297 loadStandardState ()
00298 {
00299 char *fpath;
00300 FILE *stdlib;
00301 bool result;
00302 char *libname = addExtension (context_selectedLibrary (), DUMP_SUFFIX);
00303
00304
00305 if (osd_findOnLarchPath (libname, &fpath) != OSD_FILEFOUND)
00306 {
00307 lldiagmsg (message ("Cannot find %sstandard library: %s",
00308 cstring_makeLiteralTemp
00309 (context_getFlag (FLG_STRICTLIB) ? "strict "
00310 : (context_getFlag (FLG_UNIXLIB) ? "unix " : "")),
00311 cstring_makeLiteralTemp (libname)));
00312 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
00313 result = FALSE;
00314 }
00315 else
00316 {
00317 stdlib = fopen (fpath, "r");
00318
00319 if (stdlib == NULL)
00320 {
00321 lldiagmsg (message ("Cannot read standard library: %s",
00322 cstring_fromChars (fpath)));
00323 lldiagmsg (cstring_makeLiteral (" Check LARCH_PATH environment variable."));
00324
00325 result = FALSE;
00326 }
00327 else
00328 {
00329 if (context_getFlag (FLG_WHICHLIB))
00330 {
00331 char *t = mstring_create (MAX_NAME_LENGTH);
00332 char *ot = t;
00333
00334 if (fgets (t, MAX_NAME_LENGTH, stdlib) == NULL)
00335 {
00336 llfatalerror (cstring_makeLiteral ("Standard library format invalid"));
00337 }
00338
00339 if (fgets (t, MAX_NAME_LENGTH, stdlib) != NULL)
00340 {
00341 if (*t == ';' && *(t + 1) == ';')
00342 {
00343 t += 2;
00344 }
00345 }
00346
00347 if (t == NULL)
00348 {
00349 lldiagmsg (message ("Standard library: %s <cannot read creation information>",
00350 cstring_fromChars (fpath)));
00351 }
00352 else
00353 {
00354 char *tt;
00355
00356 tt = strrchr (t, '\n');
00357 if (tt != NULL)
00358 *tt = '\0';
00359
00360 lldiagmsg (message ("Standard library: %s", cstring_fromChars (fpath)));
00361 lldiagmsg (message (" (created using %s)", cstring_fromChars (t)));
00362 }
00363
00364 sfree (ot);
00365
00366 check (fclose (stdlib) == 0);
00367 stdlib = fopen (fpath, "r");
00368 }
00369
00370 llassert (stdlib != NULL);
00371
00372 fileloc_reallyFree (g_currentloc);
00373 g_currentloc = fileloc_createLib (cstring_makeLiteralTemp (libname));
00374
00375 if (context_getDebug (FLG_SHOWSCAN))
00376 {
00377 context_hideShowscan ();
00378 result = loadStateFile (stdlib, cstring_fromChars (fpath));
00379 context_unhideShowscan ();
00380 }
00381 else
00382 {
00383 result = loadStateFile (stdlib, cstring_fromChars (fpath));
00384 }
00385
00386 check (fclose (stdlib) == 0);
00387 }
00388 }
00389
00390 sfree (libname);
00391 return result;
00392 }
00393
00394
00395 # define BUFLEN 128
00396
00397 static bool
00398 loadStateFile (FILE *f, cstring name)
00399 {
00400 char buf[BUFLEN];
00401
00402
00403
00404
00405
00406 if ((fgets (buf, BUFLEN, f) == NULL)
00407 || !mstring_equalPrefix (buf, ";;LCLint Dump:"))
00408 {
00409 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
00410 "to continue without library.", name));
00411 return FALSE;
00412 }
00413
00414 if (fgets (buf, BUFLEN, f) != NULL)
00415 {
00416 if (!mstring_equalPrefix (buf, ";;"))
00417 {
00418 loadllmsg (message ("Load library %s is not in LCLint library format. Attempting "
00419 "to continue without library.", name));
00420 return FALSE;
00421 }
00422 else if (mstring_equalPrefix (buf, ";;ctTable"))
00423 {
00424 loadllmsg (message ("Load library %s is in obsolete LCLint library format. Attempting "
00425 "to continue anyway, but results may be incorrect. Rebuild "
00426 "the library with this version of lclint.",
00427 name));
00428 }
00429 else
00430 {
00431 float version = 0.0;
00432
00433 if (sscanf (buf, ";;LCLint %f", &version) != 1)
00434 {
00435 loadllmsg (message ("Load library %s is not in LCLint library format (missing version "
00436 "number). Attempting "
00437 "to continue without library.", name));
00438 return FALSE;
00439 }
00440 else
00441 {
00442 if ((LCL_MIN_VERSION - version) >= FLT_EPSILON)
00443 {
00444 cstring vname;
00445 char *nl = strchr (buf, '\n');
00446
00447 *nl = '\0';
00448
00449 vname = cstring_fromChars (buf + 9);
00450
00451 loadllmsg (message ("Load library %s is in obsolete LCLint library "
00452 "format (version %s). Attempting "
00453 "to continue anyway, but results may be incorrect. Rebuild "
00454 "the library with this version of lclint.",
00455 name, vname));
00456 }
00457 else
00458 {
00459 if ((fgets (buf, BUFLEN, f) == NULL))
00460 {
00461 loadllmsg (message ("Load library %s is not in LCLint library "
00462 "format (missing library code). Attempting "
00463 "to continue without library.", name));
00464 return FALSE;
00465 }
00466 else
00467 {
00468 int lib;
00469
00470 if (sscanf (buf, ";;lib:%d", &lib) != 1)
00471 {
00472 loadllmsg (message ("Load library %s is not in LCLint library "
00473 "format (missing library code). Attempting "
00474 "to continue without library.", name));
00475 return FALSE;
00476 }
00477 else
00478 {
00479 flagcode code = (flagcode) lib;
00480
00481 if (flagcode_isLibraryFlag (code))
00482 {
00483 if (context_doMerge ())
00484 {
00485 context_setLibrary (code);
00486 }
00487 }
00488 else
00489 {
00490 loadllmsg (message ("Load library %s has invalid library code. "
00491 "Attempting to continue without library.",
00492 name));
00493
00494 return FALSE;
00495 }
00496 }
00497 }
00498 }
00499 }
00500 }
00501 }
00502 else
00503 {
00504 loadllmsg (message ("Load library %s is not in LCLint library format (missing lines). "
00505 "Attempting to continue without library.", name));
00506 return FALSE;
00507 }
00508
00509 ctype_loadTable (f);
00510 printDot ();
00511
00512 typeIdSet_loadTable (f);
00513 printDot ();
00514
00515 usymtab_load (f);
00516 printDot ();
00517
00518 context_loadModuleAccess (f);
00519 printDot ();
00520
00521 return TRUE;
00522 }
00523
00524
00525
00526
00527
00528 void
00529 loadState (cstring cfname)
00530 {
00531 FILE *f;
00532 char *fname = cstring_toCharsSafe (cfname);
00533 cstring ofname = cstring_copy (cfname);
00534
00535 fname = addExtension (fname, DUMP_SUFFIX);
00536
00537 f = fopen (fname, "r");
00538
00539 if (f == NULL)
00540 {
00541 if (context_getDebug (FLG_SHOWSCAN))
00542 fprintf (g_msgstream, " >\n");
00543
00544 llfatalerror (message ("Cannot open dump file for loading: %s", cfname));
00545 }
00546 else
00547 {
00548 fileloc_reallyFree (g_currentloc);
00549 g_currentloc = fileloc_createLib (ofname);
00550
00551 if (!loadStateFile (f, ofname))
00552 {
00553 if (!loadStandardState ())
00554 {
00555 ctype_initTable ();
00556 }
00557 }
00558
00559 check (fclose (f) == 0);
00560 }
00561
00562 cstring_free (ofname);
00563 sfree (fname);
00564 }
00565