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 # include "osd.h"
00037 # include "llgrammar.h"
00038 # include "lclscan.h"
00039 # include "checking.h"
00040 # include "imports.h"
00041 # include "lslparse.h"
00042 # include "lh.h"
00043 # include "llmain.h"
00044 # include "portab.h"
00045 # include "herald.h"
00046
00047 void
00048 outputLCSFile (char *path, char *msg, char *specname)
00049 {
00050 static bool haserror = FALSE;
00051 char *sfile = mstring_concat (specname, ".lcs");
00052 char *outfile = mstring_concat (path, sfile);
00053 char *s;
00054 FILE *outfptr = fopen (outfile, "w");
00055 sfree (sfile);
00056
00057 DPRINTF (("Output lcl file: %s / %s / %s", path, specname, outfile));
00058
00059
00060
00061 if (outfptr == 0)
00062 {
00063 if (!haserror)
00064 {
00065 lclplainerror (message ("Cannot write to output file: %s",
00066 cstring_fromChars (outfile)));
00067 haserror = TRUE;
00068 }
00069 sfree (outfile);
00070 return;
00071 }
00072
00073 fprintf (outfptr, msg);
00074 fprintf (outfptr, "%s\n", LCL_PARSE_VERSION);
00075
00076
00077 fprintf (outfptr, "%%LCLimports ");
00078
00079 lsymbolSet_elements (g_currentImports, sym)
00080 {
00081 s = lsymbol_toChars (sym);
00082
00083 if (s != NULL && !mstring_equal (s, specname))
00084 {
00085 fprintf (outfptr, "%s ", s);
00086 }
00087 } end_lsymbolSet_elements;
00088
00089 fprintf (outfptr, "\n");
00090
00091 sort_dump (outfptr, TRUE);
00092 symtable_dump (g_symtab, outfptr, TRUE);
00093
00094 check (fclose (outfptr) == 0);
00095 sfree (outfile);
00096 }
00097
00098 void
00099 importCTrait (void)
00100 {
00101 char **infile = (char **) dmalloc (sizeof (*infile));
00102 filestatus status = osd_findOnLarchPath (CTRAITSYMSNAME, infile);
00103
00104
00105 switch (status)
00106 {
00107 case OSD_FILEFOUND:
00108
00109
00110
00111
00112
00113
00114
00115 (void) parseSignatures (cstring_fromChars (CTRAITSYMSNAME));
00116 (void) parseSignatures (cstring_fromChars (*infile));
00117 break;
00118 case OSD_FILENOTFOUND:
00119
00120 status = osd_findOnLarchPath (CTRAITSPECNAME, infile);
00121
00122 if (status == OSD_FILEFOUND)
00123 {
00124 callLSL (CTRAITSPECNAME,
00125 cstring_toCharsSafe
00126 (message ("includes %s (%s for String)",
00127 cstring_fromChars (CTRAITFILENAMEN),
00128 cstring_fromChars (sort_getName (sort_cstring)))));
00129 break;
00130 }
00131 else
00132 {
00133 lldiagmsg
00134 (message ("Unable to find %s or %s. Check LARCH_PATH environment variable.",
00135 cstring_fromChars (CTRAITSYMSNAME),
00136 cstring_fromChars (CTRAITSPECNAME)));
00137 llexit (LLFAILURE);
00138 }
00139 case OSD_PATHTOOLONG:
00140 lclbug (message ("importCTrait: the concatenated directory and file "
00141 "name are too long: %s: "
00142 "continuing without it",
00143 cstring_fromChars (CTRAITSPECNAME)));
00144 break;
00145 }
00146
00147 sfree (*infile);
00148 sfree (infile);
00149 }
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 void
00165 processImport (lsymbol importSymbol, ltoken tok, impkind kind)
00166 {
00167 bool readableP, oldexporting;
00168 bool oldFormat = FALSE;
00169 tsource *imported, *imported2, *lclsource;
00170 char *bufptr, *tmpbufptr, *cptr;
00171 char *name;
00172 lsymbol sym;
00173 char importName[MAX_NAME_LENGTH + 1], *importFileName, *realfname;
00174 char *path;
00175 char *fpath, *fpath2;
00176 mapping *map;
00177 filestatus ret;
00178
00179 importFileName = lsymbol_toCharsSafe (importSymbol);
00180 name = mstring_concat (importFileName, IO_SUFFIX);
00181 realfname = name;
00182
00183
00184
00185
00186
00187 switch (kind)
00188 {
00189 case IMPPLAIN:
00190 path = cstring_toCharsSafe
00191 (message ("%s%c%s", cstring_fromChars (g_localSpecPath), SEPCHAR, context_getLarchPath ()));
00192
00193 break;
00194 case IMPBRACKET:
00195 path = mstring_copy (cstring_toCharsSafe (context_getLCLImportDir ()));
00196 break;
00197 case IMPQUOTE:
00198 path = mstring_copy (g_localSpecPath);
00199 break;
00200 default:
00201 path = mstring_createEmpty ();
00202 llbuglit ("bad imports case\n");
00203 }
00204
00205 if ((ret = osd_getPath (path, realfname, &fpath)) != OSD_FILEFOUND)
00206 {
00207 char *fname2;
00208
00209 if (ret == OSD_PATHTOOLONG)
00210 {
00211 llfatalerrorLoc (cstring_makeLiteral ("Path too long"));
00212 }
00213
00214 imported2 = tsource_create (importFileName, LCL_SUFFIX, FALSE);
00215 fname2 = tsource_fileName (imported2);
00216
00217
00218
00219 if (osd_getPath (path, fname2, &fpath2) == OSD_FILEFOUND)
00220 {
00221 llfatalerrorLoc
00222 (message ("Specs must be processed before it can be imported: %s",
00223 cstring_fromChars (fpath2)));
00224 }
00225 else
00226 {
00227 if (kind == IMPPLAIN || kind == IMPQUOTE)
00228 llfatalerrorLoc (message ("Cannot find file to import: %s",
00229 cstring_fromChars (realfname)));
00230 else
00231 llfatalerrorLoc (message ("Cannot find standard import file: %s",
00232 cstring_fromChars (realfname)));
00233 }
00234 }
00235
00236
00237 imported = tsource_create (fpath, IO_SUFFIX, FALSE);
00238
00239
00240 readableP = tsource_open (imported);
00241
00242 if (!readableP)
00243 {
00244 llfatalerrorLoc (message ("Cannot open import file for reading: %s",
00245 cstring_fromChars (tsource_fileName (imported))));
00246 }
00247
00248 bufptr = tsource_nextLine (imported);
00249
00250 if (bufptr == 0)
00251 {
00252 llerror (FLG_SYNTAX, message ("Import file is empty: %s",
00253 cstring_fromChars (tsource_fileName (imported))));
00254 sfree (name);
00255 (void) tsource_close (imported);
00256 tsource_free (imported);
00257
00258 sfree (path);
00259 return;
00260 }
00261
00262
00263 if (firstWord (bufptr, "%FAILED"))
00264 {
00265 llfatalerrorLoc
00266 (message ("Imported file was not checked successfully: %s.",
00267 cstring_fromChars (name)));
00268 }
00269
00276 if (firstWord (bufptr, "%PASSED"))
00277 {
00278
00279
00280
00281
00282 cptr = strstr (bufptr, "LCP Version");
00283
00284 if (cptr != NULL)
00285 {
00286 cptr += 12;
00287 if (*cptr != '2' && *cptr != '3')
00288 {
00289 llfatalerrorLoc (message ("Imported file is obsolete: %s.",
00290 cstring_fromChars (bufptr)));
00291 }
00292 }
00293 oldFormat = TRUE;
00294 }
00295 else
00296 {
00297 if (!firstWord (bufptr, "%LCS"))
00298 {
00299 llfatalerrorLoc (message ("Imported file is not in correct format: %s.",
00300 cstring_fromChars (bufptr)));
00301 }
00302 }
00303
00304
00305
00306 context_enterImport ();
00307
00308 bufptr = tsource_nextLine (imported);
00309 llassert (bufptr != NULL);
00310
00311 tmpbufptr = bufptr;
00312
00313
00314 if (firstWord (bufptr, "%LCLimports "))
00315 {
00316 bufptr = bufptr + strlen ("%LCLimports ");
00317 while (sscanf (bufptr, "%s", importName) == 1)
00318 {
00319 bufptr = bufptr + strlen (importName) + 1;
00320 sym = lsymbol_fromChars (importName);
00321 if (sym == importSymbol ||
00322 lsymbolSet_member (g_currentImports, sym))
00323 {
00324
00325
00326 lclsource = LCLScanSource ();
00327 lclfatalerror (tok,
00328 message ("Imports cycle: %s.lcl imports %s",
00329 cstring_fromChars (importFileName),
00330 cstring_fromChars (importName)));
00331 }
00332
00333
00334
00335 }
00336 }
00337 else
00338 {
00339 lclsource = LCLScanSource ();
00340 lclfatalerror (tok, message ("Unexpected line in imported file %s: %s",
00341 cstring_fromChars (name),
00342 cstring_fromChars (bufptr)));
00343 }
00344
00345
00346 oldexporting = sort_setExporting (TRUE);
00347
00348 map = mapping_create ();
00349
00350
00351
00352 if (oldFormat)
00353 {
00354 sort_import (imported, tok, map);
00355 }
00356
00357 (void) sort_setExporting (oldexporting);
00358
00359
00360
00361
00362
00363 if (oldFormat)
00364 {
00365 symtable_import (imported, tok, map);
00366 }
00367 else
00368 {
00369
00370 }
00371
00372 check (tsource_close (imported));
00373 tsource_free (imported);
00374
00375 sfree (map);
00376 sfree (name);
00377 sfree (path);
00378
00379 context_leaveImport ();
00380 }
00381
00382
00383