]> andersk Git - splint.git/blame - src/macrocache.c
Removed /*bee:...*/ comments.
[splint.git] / src / macrocache.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** macrocache.c
26**
27** rep Invariant:
28** no two fileloc's may be equal
29**
30*/
31
1b8ae690 32# include "splintMacros.nf"
616915dd 33# include "llbasic.h"
34# include "llmain.h"
35
36/*@constant int MCEBASESIZE;@*/
37# define MCEBASESIZE 8
38
39/*@constant int DNE;@*/
40# define DNE -1
41
42/*
43** Temporary file used for processing macros.
44*/
45
15b3d2b2 46static /*:open:*/ /*@null@*/ FILE *s_macFile = NULL;
616915dd 47
48/*
49** mcDisable is set to TRUE when a macro is being processed, so
50** its contents are not added to the macrocache again, creating
51** a nasty infinite loop.
52*/
53
54static bool mcDisable = TRUE;
55static void macrocache_grow (macrocache p_s);
56static int macrocache_exists (macrocache p_s, fileloc p_fl);
57static void macrocache_processMacro (macrocache p_m, int p_i);
58
59static /*@only@*/ mce
60 mce_create (/*@only@*/ fileloc fl, /*@only@*/ cstring def, bool comment)
61{
62 mce m = (mce) dmalloc (sizeof (*m));
63 m->fl = fl;
64 m->def = def; /*< had a copy here! check this carefully */
65 m->defined = FALSE;
66 m->scomment = comment;
67 return m;
68}
69
70static void mce_free (/*@only@*/ mce m)
71{
72 fileloc_free (m->fl);
73 cstring_free (m->def);
74 sfree (m);
75}
76
77/*@only@*/ macrocache
78macrocache_create (void)
79{
80 macrocache s = (macrocache) dmalloc (sizeof (*s));
81
82 s->entries = 0;
83 s->nspace = MCEBASESIZE;
84 s->contents = (mce *) dmalloc (sizeof (*s->contents) * MCEBASESIZE);
85
86 mcDisable = FALSE;
87
88 return (s);
89}
90
91void
92macrocache_free (macrocache s)
93{
94 int i;
95
96 llassert (s_macFile == NULL);
97
98 for (i = 0; i < s->entries; i++)
99 {
8fd556fb 100 mce_free (s->contents[i]);
616915dd 101 }
102
103 sfree (s->contents);
104 sfree (s);
105}
106
107static void
108macrocache_grow (macrocache s)
109{
110 int i;
111 o_mce *oldcontents = s->contents;
112
113 s->nspace = MCEBASESIZE;
114 s->contents = (mce *) dmalloc (sizeof (*s->contents) * (s->entries + s->nspace));
115
116 for (i = 0; i < s->entries; i++)
117 {
8fd556fb 118 s->contents[i] = oldcontents[i];
616915dd 119 }
120
121 sfree (oldcontents);
122}
123
124static void
125macrocache_addGenEntry (macrocache s, /*@only@*/ fileloc fl,
126 /*@only@*/ cstring def, bool sup)
127{
128 int i;
129
130 if (mcDisable)
131 {
132 fileloc_free (fl);
133 cstring_free (def);
134 return;
135 }
136
137 if ((i = macrocache_exists (s, fl)) != DNE)
138 {
8fd556fb 139 if (cstring_equal (def, s->contents[i]->def))
616915dd 140 {
141 fileloc_free (fl);
142 cstring_free (def);
143
144 return;
145 }
146 else
147 {
148 /*
149 ** macro definition contained macro that is expanded
150 ** replace with def
151 **
152 ** how do we know which is better??
153 */
154
155 cstring_free (s->contents[i]->def);
8fd556fb 156 s->contents[i]->def = def;
616915dd 157
158 fileloc_free (fl);
159 return;
160 }
161 }
162
163 if (s->nspace <= 0) {
164 macrocache_grow (s);
165 }
166
167 s->nspace--;
8fd556fb 168 s->contents[s->entries] = mce_create (fl, def, sup);
616915dd 169 s->entries++;
170}
171
172void
173macrocache_addEntry (macrocache s, /*@only@*/ fileloc fl, /*@only@*/ cstring def)
174{
175 macrocache_addGenEntry (s, fl, def, FALSE);
176}
177
178
179void
180macrocache_addComment (macrocache s, /*@only@*/ fileloc fl, /*@only@*/ cstring def)
181{
abd7f895 182 DPRINTF (("Macrocache add comment: %s / %s", fileloc_unparse (fl), def));
616915dd 183 macrocache_addGenEntry (s, fl, def, TRUE);
184}
185
186static int
187macrocache_exists (macrocache s, fileloc fl)
188{
189 int i;
190
191 for (i = 0; i < s->entries; i++)
192 {
8fd556fb 193 if (fileloc_equal (s->contents[i]->fl, fl))
616915dd 194 return (i);
195 }
196
197 return (DNE);
198}
199
200/*@only@*/ cstring
201macrocache_unparse (macrocache m)
202{
203 cstring s = cstring_undefined;
204 int i;
205
206 for (i = 0; i < m->entries; i++)
207 {
8fd556fb 208 fileloc fl = m->contents[i]->fl;
616915dd 209 cstring def = m->contents[i]->def;
210 bool defined = m->contents[i]->defined;
211
212 s = message ("%q%q: %s [%s]\n", s, fileloc_unparse (fl), def,
213 bool_unparse (defined));
214 }
215
216 return (s);
217}
218
219/*
220** needs to call lex by hand...yuk!
221**
222** modifies gc fileloc!
223*/
224
225/*
226** there's gotta be a better way of doing this!
227*/
228
229static void pushString (/*@only@*/ cstring s)
230{
231 static fileId mtid = fileId_invalid;
232 long floc;
233
234 if (s_macFile == NULL)
235 {
236 cstring fname;
237 mtid = fileTable_addMacrosFile (context_fileTable ());
238
4dd72714 239 fname = fileTable_fileName (mtid);
d5047b91 240 s_macFile = fileTable_createMacrosFile (context_fileTable (), fname); /* , "wb+"); ? **/
616915dd 241
242 if (s_macFile == NULL)
243 {
244 llcontbug (message ("Cannot open tmp file %s needed to process macro: %s",
245 fname, s));
246 cstring_free (s);
247 return;
248 }
249 }
250
251 llassert (s_macFile != NULL);
252
253 /* SunOS, others? don't define SEEK_CUR and SEEK_SET */
254# ifndef SEEK_CUR
255# define SEEK_CUR 1
256# endif
257 check (fseek (s_macFile, 0, SEEK_CUR) == 0);
258
259 floc = ftell (s_macFile);
260
261 if (cstring_length (s) > 0) {
262 check (fputs (cstring_toCharsSafe (s), s_macFile) != EOF);
263 }
264
265 check (fputc ('\n', s_macFile) == (int) '\n');
266
267# ifndef SEEK_SET
268# define SEEK_SET 0
269# endif
270 check (fseek (s_macFile, floc, SEEK_SET) == 0);
271
272 yyin = s_macFile;
273 (void) yyrestart (yyin);
274 cstring_free (s);
275}
276
277static void
278macrocache_processMacro (macrocache m, int i)
279{
8fd556fb 280 fileloc fl = m->contents[i]->fl;
616915dd 281
8fd556fb 282 m->contents[i]->defined = TRUE;
616915dd 283
284 if (!fileId_equal (currentFile (), fileloc_fileId (fl)))
285 {
286 g_currentloc = fileloc_update (g_currentloc, fl);
287 context_enterMacroFile ();
288 }
289 else
290 {
291 setLine (fileloc_lineno (fl));
292 }
293
294 beginLine ();
295
296 DPRINTF (("Process macro: %s", m->contents[i]->def));
297
298 if (m->contents[i]->scomment)
299 {
300 pushString (message ("%s%s%s",
301 cstring_fromChars (BEFORE_COMMENT_MARKER),
302 m->contents[i]->def,
303 cstring_fromChars (AFTER_COMMENT_MARKER)));
304 (void) yyparse ();
305 }
306 else
307 {
308 bool insup = context_inSuppressRegion ();
309
310 pushString (message ("%s %s",
311 cstring_makeLiteralTemp (PPMRCODE),
312 m->contents[i]->def));
313 (void) yyparse ();
314
315 if (context_inSuppressRegion () && !insup)
316 {
28bf4b0b 317 voptgenerror
318 (FLG_SYNTAX,
319 message ("Macro ends in ignore region: %s", m->contents[i]->def),
320 fl);
616915dd 321 }
322 }
323
324 incLine ();
28bf4b0b 325 context_exitAllClauses ();
616915dd 326 context_exitMacroCache ();
327}
328
329extern void macrocache_processUndefinedElements (macrocache m)
330{
331 fileloc lastfl = fileloc_undefined;
332 int i;
333
334 mcDisable = TRUE;
335
336 DPRINTF (("Processing undefined elements"));
337
338 if (!context_getFlag (FLG_PARTIAL))
339 {
340 for (i = 0; i < m->entries; i++)
341 {
8fd556fb 342 if (m->contents[i]->defined)
616915dd 343 {
344 ;
345 }
346 else
347 {
348 fileloc fl = m->contents[i]->fl;
349
350 if (fileloc_isDefined (lastfl) && fileloc_sameFile (fl, lastfl))
351 {
352 ;
353 }
354 else
355 {
80489f0a 356 if (!fileloc_isLib (fl))
616915dd 357 {
80489f0a 358 displayScan (message ("checking macros %q",
359 fileloc_outputFilename (fl)));
616915dd 360 }
361
362 lastfl = fl;
363 cleanupMessages ();
364 }
365
366 macrocache_processMacro (m, i);
367 }
368 }
369 }
370
371 mcDisable = FALSE;
372}
373
374extern /*@observer@*/ fileloc macrocache_processFileElements (macrocache m, cstring base)
375{
376 fileloc lastfl = fileloc_undefined;
377 int i;
378
379 mcDisable = TRUE;
380
381 for (i = 0; i < m->entries; i++)
382 {
8fd556fb 383 if (m->contents[i]->defined)
616915dd 384 {
385 ;
386 }
387 else
388 {
389 fileloc fl = m->contents[i]->fl; /* should be dependent! */
390 cstring fb = fileloc_getBase (fl);
391
392 if (cstring_equal (fb, base))
393 {
394 lastfl = fl;
395 macrocache_processMacro (m, i);
396 }
397 }
398 }
399
400 mcDisable = FALSE;
401 return lastfl;
402}
403
404void macrocache_finalize (void)
405{
406 if (s_macFile != NULL)
407 {
dfd82dce 408 check (fileTable_closeFile (context_fileTable (), s_macFile));
616915dd 409 s_macFile = NULL;
410 }
411}
This page took 0.118579 seconds and 5 git commands to generate.