version 1.23, 2014/05/12 19:11:19 |
version 1.24, 2014/12/21 09:33:12 |
|
|
static void *element_alloc(size_t, void *); |
static void *element_alloc(size_t, void *); |
static void setup_definition(struct macro_definition *, const char *, |
static void setup_definition(struct macro_definition *, const char *, |
const char *); |
const char *); |
|
static void free_definition(char *); |
|
static void keep(char *); |
|
static int string_in_use(const char *); |
|
|
static struct ohash_info macro_info = { |
static struct ohash_info macro_info = { |
offsetof(struct ndblock, name), |
offsetof(struct ndblock, name), |
|
|
ndptr n = create_entry(name); |
ndptr n = create_entry(name); |
if (n->d != NULL) { |
if (n->d != NULL) { |
if (n->d->defn != null) |
if (n->d->defn != null) |
free(n->d->defn); |
free_definition(n->d->defn); |
} else { |
} else { |
n->d = xalloc(sizeof(struct macro_definition), NULL); |
n->d = xalloc(sizeof(struct macro_definition), NULL); |
n->d->next = NULL; |
n->d->next = NULL; |
|
|
else |
else |
return p; |
return p; |
} |
} |
|
|
|
/* XXX things are slightly more complicated than they seem. |
|
* a macro may actually be "live" (in the middle of an expansion |
|
* on the stack. |
|
* So we actually may need to place it in an array for later... |
|
*/ |
|
|
|
static int kept_capacity = 0; |
|
static int kept_size = 0; |
|
static char **kept = NULL; |
|
|
|
static void |
|
keep(char *ptr) |
|
{ |
|
if (kept_capacity <= kept_size) { |
|
if (kept_capacity) |
|
kept_capacity *= 2; |
|
else |
|
kept_capacity = 50; |
|
kept = xreallocarray(kept, kept_capacity, |
|
sizeof(char *), "Out of memory while saving %d strings\n", |
|
kept_capacity); |
|
} |
|
kept[kept_size++] = ptr; |
|
} |
|
|
|
static int |
|
string_in_use(const char *ptr) |
|
{ |
|
int i; |
|
for (i = 0; i <= sp; i++) { |
|
if (sstack[i] == STORAGE_MACRO && mstack[i].sstr == ptr) |
|
return 1; |
|
} |
|
return 0; |
|
} |
|
|
|
|
|
static void |
|
free_definition(char *ptr) |
|
{ |
|
int i; |
|
|
|
/* first try to free old strings */ |
|
for (i = 0; i < kept_size; i++) { |
|
if (!string_in_use(kept[i])) { |
|
kept_size--; |
|
free(kept[i]); |
|
if (i != kept_size) |
|
kept[i] = kept[kept_size]; |
|
i--; |
|
} |
|
} |
|
|
|
/* then deal with us */ |
|
if (string_in_use(ptr)) |
|
keep(ptr); |
|
else |
|
free(ptr); |
|
} |
|
|