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
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 # include "lclintMacros.nf"
00055 # include "llbasic.h"
00056 # include <string.h>
00057 # include "cpp.h"
00058 # include "cpplib.h"
00059 # include "cpphash.h"
00060
00061 typedef HASHNODE *o_HASHNODE;
00062
00063 static o_HASHNODE hashtab[CPP_HASHSIZE];
00064 static o_HASHNODE ohashtab[CPP_HASHSIZE];
00065
00066 static void HashNode_delete ( HASHNODE *);
00067
00068
00069
00070
00071 # define hashStep(old, c) (((old) << 2) + (unsigned int) (c))
00072
00073
00074 # define makePositive(v) ((v) & 0x7fffffff)
00075
00076 static HASHNODE *
00077 HashNode_copy ( HASHNODE *,
00078 HASHNODE **p_hdr,
00079 HASHNODE *p_prev)
00080 ;
00081
00082 void cppReader_saveHashtab ()
00083 {
00084 int i;
00085
00086 for (i = 0; i < CPP_HASHSIZE; i++)
00087 {
00088 ohashtab[i] = HashNode_copy (hashtab[i], &ohashtab[i], NULL);
00089 }
00090 }
00091
00092 void cppReader_restoreHashtab ()
00093 {
00094 int i;
00095
00096 for (i = 0; i < CPP_HASHSIZE; i++) {
00097
00098 hashtab[i] = HashNode_copy (ohashtab[i], &hashtab[i], NULL);
00099 }
00100 }
00101
00102 static void HashNode_delete ( HASHNODE *node)
00103 {
00104 if (node == NULL)
00105 {
00106 ;
00107 }
00108 else
00109 {
00110 HashNode_delete (node->next);
00111
00112 if (node->type == T_MACRO)
00113 {
00114 DEFINITION *d = node->value.defn;
00115 struct reflist *ap, *nextap;
00116
00117 for (ap = d->pattern; ap != NULL; ap = nextap)
00118 {
00119 nextap = ap->next;
00120 sfree (ap);
00121 }
00122
00123 if (d->nargs >= 0)
00124 {
00125 sfree (d->args.argnames);
00126 }
00127
00128 sfree (d);
00129 }
00130
00131 cstring_free (node->name);
00132 sfree (node);
00133 }
00134 }
00135
00136 HASHNODE *HashNode_copy (HASHNODE *node, HASHNODE **hdr,
00137 HASHNODE *prev)
00138 {
00139 if (node == NULL)
00140 {
00141 return NULL;
00142 }
00143 else
00144 {
00145 HASHNODE *res = dmalloc (sizeof (*res));
00146
00147 res->next = HashNode_copy (node->next, hdr, res);
00148 res->prev = prev;
00149
00150 res->bucket_hdr = hdr;
00151 res->type = node->type;
00152 res->length = node->length;
00153 res->name = cstring_copy (node->name);
00154
00155 if (node->type == T_MACRO)
00156 {
00157 DEFINITION *d = node->value.defn;
00158 DEFINITION *nd = dmalloc (sizeof (*nd));
00159
00160 res->value.defn = nd;
00161 nd->nargs = d->nargs;
00162
00163 nd->length = d->length;
00164 nd->predefined = d->predefined;
00165 nd->expansion = d->expansion;
00166 nd->line = d->line;
00167 nd->file = d->file;
00168
00169 if (d->pattern != NULL)
00170 {
00171 struct reflist *ap, *nextap;
00172 struct reflist **last = &nd->pattern;
00173
00174 for (ap = d->pattern; ap != NULL; ap = nextap)
00175 {
00176 struct reflist *npattern = dmalloc (sizeof (*(nd->pattern)));
00177
00178 nextap = ap->next;
00179
00180 if (ap == d->pattern)
00181 {
00182 *last = npattern;
00183
00184 }
00185
00186 last = &(npattern->next);
00187 npattern->next = NULL;
00188 npattern->stringify = d->pattern->stringify;
00189 npattern->raw_before = d->pattern->raw_before;
00190 npattern->raw_after = d->pattern->raw_after;
00191 npattern->rest_args = d->pattern->rest_args;
00192 npattern->argno = d->pattern->argno;
00193
00194 }
00195
00196 }
00197 else
00198 {
00199 nd->pattern = NULL;
00200 }
00201
00202 if (d->nargs >= 0)
00203 {
00204 llassert (d->args.argnames != NULL);
00205
00206 nd->args.argnames = mstring_copy (d->args.argnames);
00207 }
00208 else
00209 {
00210
00211
00212
00213
00214
00215
00216
00218 nd->args.argnames = mstring_createEmpty ();
00219 }
00220 }
00221 else
00222 {
00223 if (node->type == T_CONST)
00224 {
00225 res->value.ival = node->value.ival;
00226 }
00227 else if (node->type == T_PCSTRING)
00228 {
00229 res->value.cpval = mstring_copy (node->value.cpval);
00230 llassert (res->value.cpval != NULL);
00231 }
00232 else
00233 {
00234 res->value = node->value;
00235 }
00236 }
00237
00238
00239 return res;
00240
00241 }
00242 }
00243
00244
00245
00246
00247 int
00248 hashf (const char *name, int len, int hashsize)
00249 {
00250 unsigned int r = 0;
00251
00252 while (len-- != 0)
00253 {
00254 r = hashStep (r, *name++);
00255 }
00256
00257 return (int) (makePositive (r) % hashsize);
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271 HASHNODE *cppReader_lookup (char *name, int len, int hash)
00272 {
00273 const char *bp;
00274 HASHNODE *bucket;
00275
00276 if (len < 0)
00277 {
00278 for (bp = name; isIdentifierChar (*bp); bp++)
00279 {
00280 ;
00281 }
00282
00283 len = bp - name;
00284 }
00285
00286 if (hash < 0)
00287 {
00288 hash = hashf (name, len, CPP_HASHSIZE);
00289 }
00290
00291 bucket = hashtab[hash];
00292
00293 while (bucket != NULL)
00294 {
00295 if (bucket->length == len &&
00296 cstring_equalLen (bucket->name, cstring_fromChars (name), len))
00297 {
00298 return bucket;
00299 }
00300
00301 bucket = bucket->next;
00302 }
00303
00304 return NULL;
00305 }
00306
00307 HASHNODE *cppReader_lookupExpand (char *name, int len, int hash)
00308 {
00309 HASHNODE *node = cppReader_lookup (name, len, hash);
00310
00311 DPRINTF (("Lookup expand: %s", name));
00312
00313 if (node != NULL)
00314 {
00315 if (node->type == T_MACRO)
00316 {
00317 DEFINITION *defn = (DEFINITION *) node->value.defn;
00318
00319 DPRINTF (("Check macro..."));
00320
00321 if (defn->noExpand) {
00322 DPRINTF (("No expand!"));
00323 return NULL;
00324 }
00325 }
00326 }
00327
00328 return node;
00329 }
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 void
00346 cppReader_deleteMacro (HASHNODE *hp)
00347 {
00348 if (hp->prev != NULL)
00349 {
00350
00351 hp->prev->next = hp->next;
00352
00353
00354 }
00355
00356 if (hp->next != NULL)
00357 {
00358 hp->next->prev = hp->prev;
00359 }
00360
00361
00362
00363 if (hp == *hp->bucket_hdr) {
00364 *hp->bucket_hdr = hp->next;
00365 }
00366
00367 if (hp->type == T_MACRO)
00368 {
00369 DEFINITION *d = hp->value.defn;
00370 struct reflist *ap, *nextap;
00371
00372 for (ap = d->pattern; ap != NULL; ap = nextap)
00373 {
00374 nextap = ap->next;
00375 sfree (ap);
00376 }
00377
00378 if (d->nargs >= 0)
00379 {
00380 sfree (d->args.argnames);
00381 }
00382 }
00383
00384
00385 sfree (hp);
00386
00387 }
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402 HASHNODE *cppReader_install (char *name, int len, enum node_type type,
00403 int ivalue, char *value, int hash)
00404 {
00405 HASHNODE *hp;
00406 int i, bucket;
00407 char *p, *q;
00408
00409 if (len < 0) {
00410 p = name;
00411
00412 while (isIdentifierChar (*p))
00413 {
00414 p++;
00415 }
00416
00417 len = p - name;
00418 }
00419
00420 if (hash < 0)
00421 {
00422 hash = hashf (name, len, CPP_HASHSIZE);
00423 }
00424
00425 i = sizeof (*hp) + len + 1;
00426
00427
00428 hp = (HASHNODE *) dmalloc (size_fromInt (i));
00429 bucket = hash;
00430 hp->bucket_hdr = &hashtab[bucket];
00431
00432 hp->next = hashtab[bucket];
00433 hp->prev = NULL;
00434
00435 if (hp->next != NULL)
00436 {
00437 hp->next->prev = hp;
00438 }
00439
00440 hashtab[bucket] = hp;
00441
00442 hp->type = type;
00443 hp->length = len;
00444
00445 if (hp->type == T_CONST)
00446 {
00447 hp->value.ival = ivalue;
00448 llassert (value == NULL);
00449 }
00450 else
00451 {
00452 hp->value.cpval = value;
00453 }
00454
00455 {
00456 char *tmp = ((char *) hp) + sizeof (*hp);
00457 p = tmp;
00458 q = name;
00459
00460 for (i = 0; i < len; i++)
00461 {
00462 *p++ = *q++;
00463 }
00464
00465 tmp[len] = '\0';
00466 hp->name = cstring_fromChars (tmp);
00467 }
00468
00469
00470 return hp;
00471
00472 }
00473
00474 HASHNODE *cppReader_installMacro (char *name, int len,
00475 struct definition *defn, int hash)
00476 {
00477 return cppReader_install (name, len, T_MACRO, 0, (char *) defn, hash);
00478 }
00479
00480 void
00481 cppReader_hashCleanup (void)
00482 {
00483 int i;
00484
00485 for (i = CPP_HASHSIZE; --i >= 0; )
00486 {
00487 while (hashtab[i] != NULL)
00488 {
00489 cppReader_deleteMacro (hashtab[i]);
00490 }
00491 }
00492 }