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 # include "lclintMacros.nf"
00033 # include "llbasic.h"
00034 # include "llmain.h"
00035
00036
00037 # define MCEBASESIZE 8
00038
00039
00040 # define DNE -1
00041
00042
00043
00044
00045
00046 static FILE *s_macFile = NULL;
00047
00048
00049
00050
00051
00052
00053
00054 static bool mcDisable = TRUE;
00055 static void macrocache_grow (macrocache p_s);
00056 static int macrocache_exists (macrocache p_s, fileloc p_fl);
00057 static void macrocache_processMacro (macrocache p_m, int p_i);
00058
00059 static mce
00060 mce_create ( fileloc fl, cstring def, bool comment)
00061 {
00062 mce m = (mce) dmalloc (sizeof (*m));
00063 m->fl = fl;
00064 m->def = def;
00065 m->defined = FALSE;
00066 m->scomment = comment;
00067 return m;
00068 }
00069
00070 static void mce_free ( mce m)
00071 {
00072 fileloc_free (m->fl);
00073 cstring_free (m->def);
00074 sfree (m);
00075 }
00076
00077 macrocache
00078 macrocache_create (void)
00079 {
00080 macrocache s = (macrocache) dmalloc (sizeof (*s));
00081
00082 s->entries = 0;
00083 s->nspace = MCEBASESIZE;
00084 s->contents = (mce *) dmalloc (sizeof (*s->contents) * MCEBASESIZE);
00085
00086 mcDisable = FALSE;
00087
00088 return (s);
00089 }
00090
00091 void
00092 macrocache_free (macrocache s)
00093 {
00094 int i;
00095
00096 llassert (s_macFile == NULL);
00097
00098 for (i = 0; i < s->entries; i++)
00099 {
00100 mce_free (s->contents[i]);
00101 }
00102
00103 sfree (s->contents);
00104 sfree (s);
00105 }
00106
00107 static void
00108 macrocache_grow (macrocache s)
00109 {
00110 int i;
00111 o_mce *oldcontents = s->contents;
00112
00113 s->nspace = MCEBASESIZE;
00114 s->contents = (mce *) dmalloc (sizeof (*s->contents) * (s->entries + s->nspace));
00115
00116 for (i = 0; i < s->entries; i++)
00117 {
00118 s->contents[i] = oldcontents[i];
00119 }
00120
00121 sfree (oldcontents);
00122 }
00123
00124 static void
00125 macrocache_addGenEntry (macrocache s, fileloc fl,
00126 cstring def, bool sup)
00127 {
00128 int i;
00129
00130 if (mcDisable)
00131 {
00132 fileloc_free (fl);
00133 cstring_free (def);
00134 return;
00135 }
00136
00137 if ((i = macrocache_exists (s, fl)) != DNE)
00138 {
00139 if (cstring_equal (def, s->contents[i]->def))
00140 {
00141 fileloc_free (fl);
00142 cstring_free (def);
00143
00144 return;
00145 }
00146 else
00147 {
00148
00149
00150
00151
00152
00153
00154
00155 cstring_free (s->contents[i]->def);
00156 s->contents[i]->def = def;
00157
00158 fileloc_free (fl);
00159 return;
00160 }
00161 }
00162
00163 if (s->nspace <= 0) {
00164 macrocache_grow (s);
00165 }
00166
00167 s->nspace--;
00168 s->contents[s->entries] = mce_create (fl, def, sup);
00169 s->entries++;
00170 }
00171
00172 void
00173 macrocache_addEntry (macrocache s, fileloc fl, cstring def)
00174 {
00175 macrocache_addGenEntry (s, fl, def, FALSE);
00176 }
00177
00178
00179 void
00180 macrocache_addComment (macrocache s, fileloc fl, cstring def)
00181 {
00182 macrocache_addGenEntry (s, fl, def, TRUE);
00183 }
00184
00185 static int
00186 macrocache_exists (macrocache s, fileloc fl)
00187 {
00188 int i;
00189
00190 for (i = 0; i < s->entries; i++)
00191 {
00192 if (fileloc_equal (s->contents[i]->fl, fl))
00193 return (i);
00194 }
00195
00196 return (DNE);
00197 }
00198
00199 cstring
00200 macrocache_unparse (macrocache m)
00201 {
00202 cstring s = cstring_undefined;
00203 int i;
00204
00205 for (i = 0; i < m->entries; i++)
00206 {
00207 fileloc fl = m->contents[i]->fl;
00208 cstring def = m->contents[i]->def;
00209 bool defined = m->contents[i]->defined;
00210
00211 s = message ("%q%q: %s [%s]\n", s, fileloc_unparse (fl), def,
00212 bool_unparse (defined));
00213 }
00214
00215 return (s);
00216 }
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228 static void pushString ( cstring s)
00229 {
00230 static fileId mtid = fileId_invalid;
00231 long floc;
00232
00233 if (s_macFile == NULL)
00234 {
00235 cstring fname;
00236 mtid = fileTable_addMacrosFile (context_fileTable ());
00237
00238 fname = fileName (mtid);
00239 s_macFile = fopen (cstring_toCharsSafe (fname), "wb+");
00240
00241 if (s_macFile == NULL)
00242 {
00243 llcontbug (message ("Cannot open tmp file %s needed to process macro: %s",
00244 fname, s));
00245 cstring_free (s);
00246 return;
00247 }
00248 }
00249
00250 llassert (s_macFile != NULL);
00251
00252
00253 # ifndef SEEK_CUR
00254 # define SEEK_CUR 1
00255 # endif
00256 check (fseek (s_macFile, 0, SEEK_CUR) == 0);
00257
00258 floc = ftell (s_macFile);
00259
00260 if (cstring_length (s) > 0) {
00261 check (fputs (cstring_toCharsSafe (s), s_macFile) != EOF);
00262 }
00263
00264 check (fputc ('\n', s_macFile) == (int) '\n');
00265
00266 # ifndef SEEK_SET
00267 # define SEEK_SET 0
00268 # endif
00269 check (fseek (s_macFile, floc, SEEK_SET) == 0);
00270
00271 yyin = s_macFile;
00272 (void) yyrestart (yyin);
00273 cstring_free (s);
00274 }
00275
00276 static void
00277 macrocache_processMacro (macrocache m, int i)
00278 {
00279 fileloc fl = m->contents[i]->fl;
00280
00281 m->contents[i]->defined = TRUE;
00282
00283 if (!fileId_equal (currentFile (), fileloc_fileId (fl)))
00284 {
00285 g_currentloc = fileloc_update (g_currentloc, fl);
00286 context_enterMacroFile ();
00287 }
00288 else
00289 {
00290 setLine (fileloc_lineno (fl));
00291 }
00292
00293 beginLine ();
00294
00295 DPRINTF (("Process macro: %s", m->contents[i]->def));
00296
00297 if (m->contents[i]->scomment)
00298 {
00299 pushString (message ("%s%s%s",
00300 cstring_fromChars (BEFORE_COMMENT_MARKER),
00301 m->contents[i]->def,
00302 cstring_fromChars (AFTER_COMMENT_MARKER)));
00303 (void) yyparse ();
00304 }
00305 else
00306 {
00307 bool insup = context_inSuppressRegion ();
00308
00309 pushString (message ("%s %s",
00310 cstring_makeLiteralTemp (PPMRCODE),
00311 m->contents[i]->def));
00312 (void) yyparse ();
00313
00314 if (context_inSuppressRegion () && !insup)
00315 {
00316 llerrorlit (FLG_SYNTAX, "Macro ends in ignore region");
00317 }
00318 }
00319
00320 incLine ();
00321 context_exitMacroCache ();
00322 }
00323
00324 extern void macrocache_processUndefinedElements (macrocache m)
00325 {
00326 fileloc lastfl = fileloc_undefined;
00327 int i;
00328
00329 mcDisable = TRUE;
00330
00331 DPRINTF (("Processing undefined elements"));
00332
00333 if (!context_getFlag (FLG_PARTIAL))
00334 {
00335 for (i = 0; i < m->entries; i++)
00336 {
00337 if (m->contents[i]->defined)
00338 {
00339 ;
00340 }
00341 else
00342 {
00343 fileloc fl = m->contents[i]->fl;
00344
00345 if (fileloc_isDefined (lastfl) && fileloc_sameFile (fl, lastfl))
00346 {
00347 ;
00348 }
00349 else
00350 {
00351 if (context_getFlag (FLG_SHOWSCAN))
00352 {
00353 if (!fileloc_isLib (fl))
00354 {
00355 lldiagmsg (message ("< checking macros %s >", fileloc_filename (fl)));
00356 }
00357 }
00358
00359 lastfl = fl;
00360 cleanupMessages ();
00361 }
00362
00363 macrocache_processMacro (m, i);
00364 }
00365 }
00366 }
00367
00368 mcDisable = FALSE;
00369 }
00370
00371 extern fileloc macrocache_processFileElements (macrocache m, cstring base)
00372 {
00373 fileloc lastfl = fileloc_undefined;
00374 int i;
00375
00376 mcDisable = TRUE;
00377
00378 for (i = 0; i < m->entries; i++)
00379 {
00380 if (m->contents[i]->defined)
00381 {
00382 ;
00383 }
00384 else
00385 {
00386 fileloc fl = m->contents[i]->fl;
00387 cstring fb = fileloc_getBase (fl);
00388
00389 if (cstring_equal (fb, base))
00390 {
00391 lastfl = fl;
00392 macrocache_processMacro (m, i);
00393 }
00394 }
00395 }
00396
00397 mcDisable = FALSE;
00398 return lastfl;
00399 }
00400
00401 void macrocache_finalize (void)
00402 {
00403 if (s_macFile != NULL)
00404 {
00405 check (fclose (s_macFile) == 0);
00406 s_macFile = NULL;
00407 }
00408 }