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 "lclscan.h"
00037 # include "signature.h"
00038 # include "signature2.h"
00039 # include "scan.h"
00040 # include "scanline.h"
00041 # include "syntable.h"
00042 # include "tokentable.h"
00043 # include "lslinit.h"
00044 # include "lslparse.h"
00045 # include "llmain.h"
00046
00047
00048
00049 lslOp g_importedlslOp = NULL;
00050 bool g_lslParsingTraits = FALSE;
00051
00052 static void invokeLSL (char *p_infile, char *p_outfile, bool p_deletep);
00053
00054 int
00055 parseSignatures (cstring infile)
00056 {
00057 char *cinfile = cstring_toCharsSafe (infile);
00058 tsource *sourceFile;
00059 ltoken *id = (ltoken *) dmalloc (sizeof (*id));
00060 int status = 0;
00061
00062
00063 *id = LSLInsertToken (LST_SIMPLEID, lsymbol_fromChars (cinfile), 0, FALSE);
00064 ltoken_setFileName (*id, cinfile);
00065 ltoken_setLine (*id, 0);
00066 ltoken_setCol (*id, 0);
00067
00068 sourceFile = tsource_create (cinfile, "", FALSE);
00069
00070 if (!tsource_getPath (cstring_toCharsSafe (context_getLarchPath ()), sourceFile))
00071 {
00072 lclplainerror
00073 (message ("LSL signature parsing: can't find file %s containing trait",
00074 cstring_fromChars (tsource_fileName (sourceFile))));
00075 status = 1;
00076
00077 sfree (id);
00078 tsource_free (sourceFile);
00079 return status;
00080 }
00081
00082 if (!tsource_open (sourceFile))
00083 {
00084 lclplainerror
00085 (cstring_makeLiteral ("LSL parsing: can't open file containing trait"));
00086 status = 2;
00087 sfree (id);
00088 tsource_free (sourceFile);
00089
00090 return status;
00091 }
00092
00093 lsldebug = 0;
00094 g_lslParsingTraits = TRUE;
00095 LSLScanReset (sourceFile);
00096 LSLReportEolTokens (FALSE);
00097
00098 status = lslparse ();
00099
00100
00101 g_lslParsingTraits = FALSE;
00102
00103 (void) tsource_close (sourceFile);
00104 tsource_free (sourceFile);
00105
00106 sfree (id);
00107
00108
00109 return status;
00110 }
00111
00112 lslOp
00113 parseOpLine (char *fname, char *line)
00114 {
00115 tsource *sourceFile;
00116 bool status;
00117
00118 sourceFile = tsource_fromString (fname, line);
00119
00120 if (check (tsource_open (sourceFile)))
00121 {
00122 LSLScanReset (sourceFile);
00123 LSLReportEolTokens (FALSE);
00124
00125
00126
00127
00128
00129
00130
00131
00132 status = (lslparse () != 0);
00133
00134 if (status)
00135 {
00136 lclplainfatalerror (message ("Error in parsing line: %s",
00137 cstring_fromChars (line)));
00138 }
00139
00140 (void) tsource_close (sourceFile);
00141 }
00142
00143 tsource_free (sourceFile);
00144
00145 llassert (g_importedlslOp != NULL);
00146 return (lslOp_copy (g_importedlslOp));
00147 }
00148
00149 lsymbol
00150 processTraitSortId (lsymbol sortid)
00151 {
00152 lsymbol out = lsymbol_sortFromType (g_symtab, sortid);
00153 if (out == sortid)
00154 {
00155 (void) sort_fromLsymbol (sortid);
00156 }
00157 return out;
00158 }
00159
00160
00161
00162 static cstring
00163 printTypeName2 (typeNameNode n)
00164 {
00165 cstring s = cstring_undefined;
00166 sortNode sn;
00167 lsymbol lclSort;
00168 ltoken err;
00169
00170 if (n != (typeNameNode) 0)
00171 {
00172 if (n->isTypeName)
00173 {
00174
00175
00176 typeNamePack p = n->typename;
00177
00178 llassert (p != NULL);
00179
00180
00181 lclSort = lclTypeSpecNode2sort (p->type);
00182 lclSort = sort_getUnderlying (lclSort);
00183
00184 if (!sort_isValidSort (lclSort))
00185 {
00186 err = lclTypeSpecNode_errorToken (p->type);
00187
00188 lclerror (err, message ("Unrecognized type in uses: %q",
00189 typeNameNode_unparse (n)));
00190 }
00191 else
00192 {
00193
00194
00195
00196
00197
00198
00199
00200 lclSort = typeExpr2ptrSort (lclSort, p->abst);
00201 lclSort = sort_makeVal (lclSort);
00202
00203
00204
00205
00206
00207
00208 if (sort_isHOFSortKind (lclSort))
00209 {
00210 err = lclTypeSpecNode_errorToken (p->type);
00211
00212 lclfatalerror
00213 (err,
00214 cstring_makeLiteral
00215 ("LCL uses cannot handle higher-order types"));
00216 }
00217 if (p->isObj)
00218 lclSort = sort_makeObj (lclSort);
00219
00220
00221
00222
00223
00224 sn = sort_lookup (lclSort);
00225 s = cstring_copy (cstring_fromChars (lsymbol_toChars (sn.name)));
00226
00227 }
00228 }
00229 else
00230 {
00231
00232 if (n->opform != 0)
00233 {
00234 lclfatalerror
00235 (n->opform->tok,
00236 cstring_makeLiteral ("Attempt to rename operator with uses: "
00237 "use LSL includes renaming facility"));
00238 }
00239 else
00240 {
00241 BADEXIT;
00242 }
00243 }
00244 }
00245 return s;
00246 }
00247
00248 static cstring
00249 replaceNode_unparseAlt (replaceNode x)
00250 {
00251 cstring s = cstring_undefined;
00252
00253 if (x != (replaceNode) 0)
00254 {
00255 s = printTypeName2 (x->typename);
00256 s = cstring_concatChars (s, " for ");
00257
00258 if (x->isCType)
00259 {
00260 s = cstring_concatFree1 (s, ltoken_unparse (x->content.ctype));
00261 }
00262 else
00263 {
00264 s = cstring_concatFree (s, nameNode_unparse (x->content.renamesortname.name));
00265 s = cstring_concatFree (s,
00266 sigNode_unparse (x->content.renamesortname.signature));
00267 }
00268 }
00269
00270 return s;
00271 }
00272
00273 static cstring
00274 replaceNodeList_unparseAlt (replaceNodeList x)
00275 {
00276 cstring s = cstring_undefined;
00277 bool first = TRUE;
00278
00279 replaceNodeList_elements (x, i)
00280 {
00281 if (first)
00282 {
00283 s = replaceNode_unparseAlt (i);
00284 first = FALSE;
00285 }
00286 else
00287 {
00288 s = message ("%q, %q", s, replaceNode_unparseAlt (i));
00289 }
00290 } end_replaceNodeList_elements;
00291
00292 return s;
00293 }
00294
00295 static cstring
00296 printNameList2 (typeNameNodeList x)
00297 {
00298
00299 bool first = TRUE;
00300 cstring s = cstring_undefined;
00301
00302 typeNameNodeList_elements (x, i)
00303 {
00304 if (first)
00305 {
00306 s = printTypeName2 (i);
00307 first = FALSE;
00308 }
00309 else
00310 {
00311 s = message ("%q, %q", s, printTypeName2 (i));
00312 }
00313 } end_typeNameNodeList_elements;
00314
00315 return s;
00316 }
00317
00318 static cstring
00319 printRenamingNode2 (renamingNode x)
00320 {
00321 cstring s = cstring_undefined;
00322
00323 if (x != (renamingNode) 0)
00324 {
00325 if (x->is_replace)
00326 {
00327 replaceNodeList r = x->content.replace;
00328 s = replaceNodeList_unparseAlt (r);
00329 }
00330 else
00331 {
00332 nameAndReplaceNode n = x->content.name;
00333 bool printComma = TRUE;
00334 if (typeNameNodeList_size (n->namelist) == 0)
00335 {
00336 printComma = FALSE;
00337 }
00338 s = printNameList2 (n->namelist);
00339 if (printComma)
00340 if (replaceNodeList_isDefined (n->replacelist) &&
00341 replaceNodeList_size (n->replacelist) != 0)
00342 {
00343 s = cstring_appendChar (s, ',');
00344 s = cstring_appendChar (s, ' ');
00345 }
00346 s = cstring_concatFree (s, replaceNodeList_unparseAlt (n->replacelist));
00347 }
00348 }
00349 return s;
00350 }
00351
00352 static cstring
00353 printTraitRefList2 (traitRefNodeList x)
00354 {
00355 cstring s = cstring_undefined;
00356
00357 traitRefNodeList_elements (x, i)
00358 {
00359 s = message ("%qincludes (%q)", s, printRawLeaves2 (i->traitid));
00360
00361 if (i->rename != 0)
00362 {
00363 s = message ("%q(%q)", s, printRenamingNode2 (i->rename));
00364 }
00365 s = message ("%q\n", s);
00366 } end_traitRefNodeList_elements;
00367
00368 return s;
00369 }
00370
00371 void
00372 callLSL ( char *specfile, char *text)
00373 {
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 char *infile, *outfile;
00385 char *tmp1, *tmp2;
00386 FILE *inptr;
00387
00388 infile = cstring_toCharsSafe (fileName (fileTable_addltemp (context_fileTable ())));
00389
00390 inptr = fopen (infile, "w");
00391
00392 if (inptr == NULL)
00393 {
00394
00395 llfatalerror (message ("Unable to write intermediate file: %s",
00396 cstring_fromChars (infile)));
00397 }
00398
00399 tmp1 = removePath (infile);
00400 tmp2 = removeAnyExtension (tmp1);
00401
00402 fprintf (inptr, "%s : trait\n", tmp2);
00403 sfree (tmp1);
00404 sfree (tmp2);
00405
00406 fprintf (inptr, "%s", text);
00407 check (fclose (inptr) == 0);
00408
00409
00410
00411 outfile = cstring_toCharsSafe (fileName (fileTable_addltemp (context_fileTable ())));
00412 invokeLSL (infile, outfile, context_getFlag (FLG_KEEP));
00413 sfree (text);
00414 }
00415
00416 static void invokeLSL (char *infile, char *outfile, bool deletep)
00417 {
00418
00419 FILE *outptr;
00420 filestatus status;
00421 int callstatus;
00422 cstring call;
00423 char *returnPath = NULL;
00424
00425
00426
00427
00428
00429
00430 outptr = fopen (outfile, "w");
00431
00432 if (outptr == NULL)
00433 {
00434
00435 llfatalerror (message ("Unable to write intermediate file: %s",
00436 cstring_fromChars (outfile)));
00437 }
00438
00439 check (fclose (outptr) == 0);
00440
00441
00442 status = osd_getExePath ("PATH", "lsl", &returnPath);
00443
00444
00445 if (status == OSD_FILEFOUND)
00446 {
00447 call = message ("%s -syms %s > %s", cstring_fromChars (returnPath),
00448 cstring_fromChars (infile), cstring_fromChars (outfile));
00449
00450
00451 (void) osd_unlink (outfile);
00452
00453 callstatus = osd_system (cstring_toCharsSafe (call));
00454
00455 cstring_free (call);
00456
00457 if (callstatus != CALL_SUCCESS)
00458 {
00459
00460
00461
00462 cstring syscal = message ("%s %s", cstring_fromChars (returnPath),
00463 cstring_fromChars (infile));
00464
00465 (void) osd_system (cstring_toCharsSafe (syscal));
00466 cstring_free (syscal);
00467
00468 llfatalerror (cstring_makeLiteral ("LSL trait used contains errors."));
00469 }
00470 else
00471 {
00472
00473 callstatus = parseSignatures (cstring_fromChars (outfile));
00474
00475 if (callstatus == 0)
00476 {
00477
00478 if (!context_getFlag (FLG_KEEP))
00479 {
00480
00481 if (deletep)
00482 {
00483 (void) osd_unlink (infile);
00484 }
00485
00486 (void) osd_unlink (outfile);
00487 }
00488 }
00489 }
00490 }
00491 else if (status == OSD_FILENOTFOUND)
00492 {
00493 llfatalerror
00494 (cstring_makeLiteral ("Cannot find LSL checker: check your command search path."));
00495 }
00496 else
00497 {
00498 lclfatalbug ("invokeLSL: lsl plus directory from search path is too long");
00499 }
00500 }
00501
00502
00503
00504 void
00505 readlsignatures (interfaceNode n)
00506 {
00507
00508 char *content;
00509
00510 content = cstring_toCharsSafe (printTraitRefList2 (n->content.uses));
00511 callLSL (cstring_toCharsSafe (g_currentSpec), content);
00512 }