]> andersk Git - splint.git/blame - src/imports.c
Making fixes for Microsoft Visual C++ compiler.
[splint.git] / src / imports.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** imports.c
26**
27** module for importing LCL specs.
28**
29** AUTHOR:
30** Yang Meng Tan,
31** Massachusetts Institute of Technology
32*/
33
1b8ae690 34# include "splintMacros.nf"
b73d1009 35# include "basic.h"
616915dd 36# include "osd.h"
37# include "llgrammar.h" /* need simpleOp, MULOP and logicalOp in makeInfixTermNode */
38# include "lclscan.h"
39# include "checking.h"
40# include "imports.h"
41# include "lslparse.h"
42# include "lh.h"
43# include "llmain.h"
616915dd 44
45void
46outputLCSFile (char *path, char *msg, char *specname)
47{
48 static bool haserror = FALSE;
49 char *sfile = mstring_concat (specname, ".lcs");
50 char *outfile = mstring_concat (path, sfile);
51 char *s;
d5047b91 52 FILE *outfptr = fileTable_openWriteFile (context_fileTable (), cstring_fromChars (outfile));
616915dd 53 sfree (sfile);
54
55 DPRINTF (("Output lcl file: %s / %s / %s", path, specname, outfile));
56
57 /* check write permission */
58
dfd82dce 59 if (outfptr == NULL) /* Cannot open file */
60 {
616915dd 61 if (!haserror)
62 {
63 lclplainerror (message ("Cannot write to output file: %s",
64 cstring_fromChars (outfile)));
65 haserror = TRUE;
66 }
67 sfree (outfile);
68 return;
69 }
70
28bf4b0b 71 fprintf (outfptr, "%s", msg);
616915dd 72 fprintf (outfptr, "%s\n", LCL_PARSE_VERSION);
73
74 /* output line %LCLimports foo bar ... */
75 fprintf (outfptr, "%%LCLimports ");
76
77 lsymbolSet_elements (g_currentImports, sym)
78 {
79 s = lsymbol_toChars (sym);
80
81 if (s != NULL && !mstring_equal (s, specname))
82 {
83 fprintf (outfptr, "%s ", s);
84 }
85 } end_lsymbolSet_elements;
86
87 fprintf (outfptr, "\n");
88
89 sort_dump (outfptr, TRUE);
90 symtable_dump (g_symtab, outfptr, TRUE);
91
dfd82dce 92 check (fileTable_closeFile (context_fileTable (), outfptr));
616915dd 93 sfree (outfile);
94}
95
96void
97importCTrait (void)
98{
28bf4b0b 99 cstring infile = cstring_undefined;
100 filestatus status = osd_findOnLarchPath (cstring_makeLiteralTemp (CTRAITSYMSNAME),
101 &infile);
616915dd 102
616915dd 103 switch (status)
104 {
105 case OSD_FILEFOUND:
106 /*
107 ** This line was missing before version 2.3f. Bug fix by Mike Smith.
108 ** This looks like a bug - infile is already fully qualified path
109 ** parseSignatures() adds another path to the front and fails to
110 ** open the file.
111 */
112
28bf4b0b 113 (void) parseSignatures (cstring_fromCharsNew (CTRAITSYMSNAME));
114 (void) parseSignatures (infile);
616915dd 115 break;
116 case OSD_FILENOTFOUND:
117 /* try spec name */
28bf4b0b 118 status = osd_findOnLarchPath (cstring_makeLiteralTemp (CTRAITSPECNAME),
119 &infile);
616915dd 120
121 if (status == OSD_FILEFOUND)
122 {
28bf4b0b 123 callLSL (cstring_makeLiteralTemp (CTRAITSPECNAME),
124 message ("includes %s (%s for String)",
125 cstring_fromChars (CTRAITFILENAMEN),
2a6e9c30 126 cstring_fromChars (sort_getName (g_sortCstring))));
28bf4b0b 127 cstring_free (infile);
616915dd 128 break;
129 }
130 else
131 {
132 lldiagmsg
133 (message ("Unable to find %s or %s. Check LARCH_PATH environment variable.",
134 cstring_fromChars (CTRAITSYMSNAME),
135 cstring_fromChars (CTRAITSPECNAME)));
28bf4b0b 136 cstring_free (infile);
137 llexit (LLFAILURE);
616915dd 138 }
139 case OSD_PATHTOOLONG:
140 lclbug (message ("importCTrait: the concatenated directory and file "
141 "name are too long: %s: "
142 "continuing without it",
143 cstring_fromChars (CTRAITSPECNAME)));
28bf4b0b 144 cstring_free (infile);
616915dd 145 break;
146 }
616915dd 147}
148
149/*
150** processImport --- load imports from file
151**
152** impkind: IMPPLAIN file on SPEC_PATH
153** # include "./file.h" if it exists,
154** # include "<directory where spec was found>/file.h" if not.
155** (warn if neither exists)
156** IMPBRACKET file in default LCL imports directory
157** # include <file.h>
158** IMPQUOTE file directly
159** # include "file.h"
160*/
161
162void
163processImport (lsymbol importSymbol, ltoken tok, impkind kind)
164{
165 bool readableP, oldexporting;
28bf4b0b 166 bool compressedFormat = FALSE;
167 inputStream imported, imported2, lclsource;
168 char *bufptr;
169 char *tmpbufptr;
170 char *cptr;
171 cstring name;
616915dd 172 lsymbol sym;
28bf4b0b 173 char importName[MAX_NAME_LENGTH + 1];
174 cstring importFileName;
175 cstring path = cstring_undefined;
176 cstring fpath, fpath2;
177 mapping map;
616915dd 178 filestatus ret;
179
28bf4b0b 180 importFileName = lsymbol_toString (importSymbol);
181 name = cstring_concat (importFileName, cstring_makeLiteralTemp (IO_SUFFIX));
616915dd 182
183 /*
184 ** find .lcs file
185 */
186
187 switch (kind)
188 {
189 case IMPPLAIN:
7272a1c1 190 path = message ("%s%c%s", cstring_fromChars (g_localSpecPath), PATH_SEPARATOR,
28bf4b0b 191 context_getLarchPath ());
192
616915dd 193 break;
194 case IMPBRACKET:
28bf4b0b 195 path = cstring_copy (context_getLCLImportDir ());
616915dd 196 break;
197 case IMPQUOTE:
28bf4b0b 198 path = cstring_fromCharsNew (g_localSpecPath);
616915dd 199 break;
200 default:
616915dd 201 llbuglit ("bad imports case\n");
202 }
203
28bf4b0b 204 if ((ret = osd_getPath (path, name, &fpath)) != OSD_FILEFOUND)
616915dd 205 {
28bf4b0b 206 cstring fname2;
616915dd 207
208 if (ret == OSD_PATHTOOLONG)
209 {
210 llfatalerrorLoc (cstring_makeLiteral ("Path too long"));
211 }
212
28bf4b0b 213 imported2 = inputStream_create (cstring_copy (importFileName),
214 LCL_EXTENSION, FALSE);
215 fname2 = inputStream_fileName (imported2);
616915dd 216
217 if (osd_getPath (path, fname2, &fpath2) == OSD_FILEFOUND)
218 {
219 llfatalerrorLoc
220 (message ("Specs must be processed before it can be imported: %s",
28bf4b0b 221 fpath2));
616915dd 222 }
223 else
224 {
225 if (kind == IMPPLAIN || kind == IMPQUOTE)
28bf4b0b 226 {
227 llfatalerrorLoc (message ("Cannot find file to import: %s", name));
228 }
616915dd 229 else
28bf4b0b 230 {
231 llfatalerrorLoc (message ("Cannot find standard import file: %s", name));
232 }
616915dd 233 }
234 }
235
236
28bf4b0b 237 imported = inputStream_create (fpath, cstring_makeLiteralTemp (IO_SUFFIX), FALSE);
238
239 readableP = inputStream_open (imported);
616915dd 240
241 if (!readableP)
242 { /* can't read ? */
243 llfatalerrorLoc (message ("Cannot open import file for reading: %s",
28bf4b0b 244 inputStream_fileName (imported)));
616915dd 245 }
246
28bf4b0b 247 bufptr = inputStream_nextLine (imported);
616915dd 248
249 if (bufptr == 0)
250 {
251 llerror (FLG_SYNTAX, message ("Import file is empty: %s",
28bf4b0b 252 inputStream_fileName (imported)));
253 cstring_free (name);
254 (void) inputStream_close (imported);
255 inputStream_free (imported);
616915dd 256
28bf4b0b 257 cstring_free (path);
616915dd 258 return;
259 }
260
261 /* was it processed successfully ? */
262 if (firstWord (bufptr, "%FAILED"))
263 {
264 llfatalerrorLoc
28bf4b0b 265 (message ("Imported file was not checked successfully: %s.", name));
616915dd 266 }
267
28bf4b0b 268 /*
269 ** Is it generated by the right version of the checker?
270 **
271 ** Uncompressed .lcs files start with %PASSED
272 ** Compressed files start with %LCS
273 */
616915dd 274
275 if (firstWord (bufptr, "%PASSED"))
276 {
277 /* %PASSED Output from LCP Version 2.* and 3.* */
278 /* 1234567890123*/
279 /* +*/
280
281 cptr = strstr (bufptr, "LCP Version");
282
283 if (cptr != NULL)
284 {
28bf4b0b 285 /*
286 ** Only really old files start this way!
287 */
288
616915dd 289 cptr += 12;
290 if (*cptr != '2' && *cptr != '3')
291 {
28bf4b0b 292 llfatalerrorLoc (message ("Imported file %s is obsolete: %s.",
293 inputStream_fileName (imported),
294 cstring_fromChars (bufptr)));
616915dd 295 }
296 }
28bf4b0b 297
298 compressedFormat = FALSE;
616915dd 299 }
300 else
301 {
302 if (!firstWord (bufptr, "%LCS"))
303 {
28bf4b0b 304 llfatalerrorLoc (message ("Imported file %s is not in correct format: %s",
305 inputStream_fileName (imported),
616915dd 306 cstring_fromChars (bufptr)));
307 }
28bf4b0b 308
309 compressedFormat = TRUE;
616915dd 310 }
311
312 /* push the imported LCL spec onto g_currentImports */
313
314 context_enterImport ();
315
28bf4b0b 316 bufptr = inputStream_nextLine (imported);
616915dd 317 llassert (bufptr != NULL);
318
319 tmpbufptr = bufptr;
320
321 /* expect %LCLimports foo bar ... */
322 if (firstWord (bufptr, "%LCLimports "))
323 {
324 bufptr = bufptr + strlen ("%LCLimports ");
325 while (sscanf (bufptr, "%s", importName) == 1)
326 {
327 bufptr = bufptr + strlen (importName) + 1; /* 1 for space */
328 sym = lsymbol_fromChars (importName);
329 if (sym == importSymbol ||
330 lsymbolSet_member (g_currentImports, sym))
331 {
332 /* ensure that the import list does not contain itself: an
333 invariant useful for checking imports cycles. */
334 lclsource = LCLScanSource ();
335 lclfatalerror (tok,
28bf4b0b 336 message ("Imports cycle: %s%s imports %s",
337 importFileName,
338 LCL_EXTENSION,
616915dd 339 cstring_fromChars (importName)));
340 }
341 /* push them onto g_currentImports */
342 /* evs - 94 Apr 3: I don't think it should do this! */
343 /* (void) lsymbolSet_insert (g_currentImports, sym); */
344 }
345 }
346 else
347 {
348 lclsource = LCLScanSource ();
349 lclfatalerror (tok, message ("Unexpected line in imported file %s: %s",
28bf4b0b 350 name,
616915dd 351 cstring_fromChars (bufptr)));
352 }
353
354 /* read in the imported info */
355 oldexporting = sort_setExporting (TRUE);
356
357 map = mapping_create ();
358
359 /* tok for error line numbering */
360
28bf4b0b 361 if (!compressedFormat)
616915dd 362 {
28bf4b0b 363 sort_import (imported, tok, map);
616915dd 364 }
28bf4b0b 365
616915dd 366 (void) sort_setExporting (oldexporting);
28bf4b0b 367
616915dd 368 /* sort_import updates a mapping of old anonymous sorts to new
369 anonymous sort that is needed in symtable_import */
370 /* mapping_print (map); */
371
28bf4b0b 372 if (!compressedFormat)
616915dd 373 {
374 symtable_import (imported, tok, map);
375 }
376 else
377 {
378 /* symtable_loadImport (imported, tok, map); */
379 }
380
28bf4b0b 381 check (inputStream_close (imported));
382 inputStream_free (imported);
383
384 mapping_free (map);
385 cstring_free (name);
386 cstring_free (path);
616915dd 387
388 context_leaveImport ();
389}
390
391
392
This page took 0.460751 seconds and 5 git commands to generate.