aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2006-03-15 19:33:01 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2006-03-15 19:33:01 +0000
commit79d36e31afc3d1a7d8f6246b7b2407f5fc22dbb8 (patch)
treea7ca8cfaa55fd03ea1ff1d66ef36298ee5d46d63 /src
parentd554d1c146acc8cce076669a1e42abd4b2352a4a (diff)
downloadcflow-79d36e31afc3d1a7d8f6246b7b2407f5fc22dbb8.tar.gz
cflow-79d36e31afc3d1a7d8f6246b7b2407f5fc22dbb8.tar.bz2
Change organization of the symbol table: the
table entry contains struct table_entry, which contains a pointer to the head of the symbol list associated with the entry. Thus, deletions from the table can be handled in a more natural manner. All functions changed to reflect the change. (unlink_symbol): New function. (delete_symbol): Rewritten using unlink_symbol (delete_statics): always call static_processor
Diffstat (limited to 'src')
-rw-r--r--src/symbol.c187
1 files changed, 119 insertions, 68 deletions
diff --git a/src/symbol.c b/src/symbol.c
index dab0d29..c31a323 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -1,5 +1,5 @@
/* This file is part of GNU cflow
- Copyright (C) 1997,2005 Sergey Poznyakoff
+ Copyright (C) 1997, 2005, 2006 Sergey Poznyakoff
GNU cflow is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -20,45 +20,59 @@
#include <parser.h>
#include <hash.h>
-Hash_table *symbol_table;
+static Hash_table *symbol_table;
+
+struct table_entry {
+ Symbol *sym;
+};
/* Calculate the hash of a string. */
-static unsigned
+static size_t
hash_symbol_hasher(void const *data, unsigned n_buckets)
{
- Symbol const *sym = data;
- return hash_string(sym->name, n_buckets);
+ struct table_entry const *t = data;
+ if (!t->sym)
+ return ((size_t) data) % n_buckets;
+ return hash_string(t->sym->name, n_buckets);
}
/* Compare two strings for equality. */
static bool
hash_symbol_compare(void const *data1, void const *data2)
{
- Symbol const *s1 = data1;
- Symbol const *s2 = data2;
- return strcmp(s1->name, s2->name) == 0;
+ struct table_entry const *t1 = data1;
+ struct table_entry const *t2 = data2;
+ return t1->sym && t2->sym && strcmp(t1->sym->name, t2->sym->name) == 0;
}
Symbol *
lookup(char *name)
{
Symbol s;
+ struct table_entry t, *tp;
+
if (!symbol_table)
return NULL;
s.name = name;
- return hash_lookup(symbol_table, &s);
+ t.sym = &s;
+ tp = hash_lookup(symbol_table, &t);
+ return tp ? tp->sym : NULL;
}
Symbol *
install(char *name)
{
- Symbol *sym, *s;
-
+ Symbol *sym;
+ struct table_entry *tp, *ret;
+
sym = xmalloc(sizeof(*sym));
memset(sym, 0, sizeof(*sym));
sym->type = SymUndefined;
sym->name = name;
+ tp = xmalloc(sizeof(*tp));
+ tp->sym = sym;
+
if (canonical_filename && strcmp(filename, canonical_filename))
sym->flag = symbol_temp;
else
@@ -68,37 +82,42 @@ install(char *name)
|| (symbol_table = hash_initialize (0, 0,
hash_symbol_hasher,
hash_symbol_compare, 0)))
- && (s = hash_insert (symbol_table, sym))))
+ && (ret = hash_insert (symbol_table, tp))))
xalloc_die ();
- if (s != sym) {
- if (s->type == SymUndefined) {
- *s = *sym;
- free(sym);
- } else {
- Symbol tmp = *s;
- *s = *sym;
- *sym = tmp;
- s->next = sym;
- }
+ if (ret != tp) {
+ if (ret->sym->type != SymUndefined)
+ sym->next = ret->sym;
+ ret->sym = sym;
}
- return s;
+ return sym;
}
+/* Unlink the first symbol from the table entry */
+static Symbol *
+unlink_symbol(struct table_entry *tp)
+{
+ Symbol *s = tp->sym;
+ if (s)
+ tp->sym = s->next;
+ return s;
+}
+
+/* Unlink and free the first symbol from the table entry */
static void
-delete_symbol(Symbol *s)
+delete_symbol(struct table_entry *tp)
{
- Symbol *next = s->next;
- if (next) {
- *s = *next;
- free(next);
- } else {
- s->type = SymUndefined;
- }
+ free(unlink_symbol(tp));
}
+static void cleanup_symbol_refs(Symbol *sym);
+
/* Delete from the symbol table all static symbols defined in the current
source.
+ If the user requested static symbols in the listing, the symbol is
+ not deleted, as it may have been referenced by other symbols. Instead,
+ it is unlinked from its table entry and cleanup_symbol_refs() is
+ called, so that its reference tables become usable.
NOTE: This takes advantage of the fact that install() uses LIFO strategy,
so we don't have to check the name of the source where the symbol was
defined. */
@@ -106,28 +125,33 @@ delete_symbol(Symbol *s)
static bool
static_processor(void *data, void *proc_data)
{
- Symbol *s = data;
-
- if (s->type == SymIdentifier && s->storage == StaticStorage)
- delete_symbol(s);
+ struct table_entry *t = data;
+
+ if (t->sym
+ && t->sym->type == SymIdentifier
+ && t->sym->storage == StaticStorage) {
+ if (globals_only())
+ delete_symbol(t);
+ else
+ cleanup_symbol_refs(unlink_symbol(t));
+ }
return true;
}
static bool
temp_processor(void *data, void *proc_data)
{
- Symbol *s = data;
+ struct table_entry *t = data;
- if (s->flag == symbol_temp)
- delete_symbol(s);
+ if (t->sym && t->sym->flag == symbol_temp)
+ delete_symbol(t);
return true;
}
void
delete_statics()
{
- if (globals_only())
- hash_do_for_each (symbol_table, static_processor, NULL);
+ hash_do_for_each (symbol_table, static_processor, NULL);
hash_do_for_each (symbol_table, temp_processor, NULL);
}
@@ -135,11 +159,25 @@ delete_statics()
bool
auto_processor(void *data, void *proc_data)
{
- Symbol *s = data;
- int *level = proc_data;
- if (s->type == SymIdentifier && s->storage == AutoStorage
- && s->level == *level)
- delete_symbol(s);
+ struct table_entry *t = data;
+ Symbol *s = t->sym;
+ if (s) {
+ int *level = proc_data;
+ if (s->type == SymIdentifier && s->level == *level) {
+ switch (s->storage) {
+ case AutoStorage:
+ delete_symbol(t);
+ break;
+
+ case StaticStorage:
+ cleanup_symbol_refs(unlink_symbol(t));
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
return true;
}
@@ -159,20 +197,26 @@ delete_autos(int level)
*
* TODO: The memory is not reclaimed
*/
+static void
+cleanup_symbol_refs(Symbol *sym)
+{
+ if (sym && sym->type == SymIdentifier) {
+ if (sym->ref_line)
+ sym->ref_line = CAR(sym->ref_line);
+ if (sym->caller)
+ sym->caller = CAR(sym->caller);
+ if (sym->callee)
+ sym->callee = CAR(sym->callee);
+ }
+}
+
static bool
cleanup_processor(void *data, void *proc_data)
{
+ struct table_entry *t = data;
Symbol *sym;
-
- for (sym = data; sym; sym = sym->next) {
- if (sym->type == SymIdentifier) {
- if (sym->ref_line)
- sym->ref_line = CAR(sym->ref_line);
- if (sym->caller)
- sym->caller = CAR(sym->caller);
- if (sym->callee)
- sym->callee = CAR(sym->callee);
- }
+ for (sym = t->sym; sym; sym = sym->next) {
+ cleanup_symbol_refs(sym);
}
return true;
}
@@ -196,9 +240,10 @@ struct collect_data {
static bool
collect_processor(void *data, void *proc_data)
{
- Symbol *s;
+ struct table_entry *t = data;
struct collect_data *cd = proc_data;
- for (s = data; s; s = s->next) {
+ Symbol *s;
+ for (s = t->sym; s; s = s->next) {
if (cd->sel(s)) {
if (cd->sym)
cd->sym[cd->index] = s;
@@ -232,11 +277,14 @@ collect_symbols(Symbol ***return_sym, int (*sel)(Symbol *p))
static bool
delete_parm_processor(void *data, void *proc_data)
{
- Symbol *s = data;
- int *level = proc_data;
- if (s->type == SymIdentifier && s->storage == AutoStorage
- && s->flag == symbol_parm && s->level > *level)
- delete_symbol(s);
+ struct table_entry *t = data;
+ Symbol *s = t->sym;
+ if (s) {
+ int *level = proc_data;
+ if (s->type == SymIdentifier && s->storage == AutoStorage
+ && s->flag == symbol_parm && s->level > *level)
+ delete_symbol(t);
+ }
return true;
}
@@ -250,12 +298,15 @@ delete_parms(int level)
static bool
move_parm_processor(void *data, void *proc_data)
{
- Symbol *s = data;
- int level = *(int*)proc_data;
- if (s->type == SymIdentifier && s->storage == AutoStorage
- && s->flag == symbol_parm) {
- s->level = level;
- s->flag = symbol_none;
+ struct table_entry *t = data;
+ Symbol *s = t->sym;
+ if (s) {
+ int level = *(int*)proc_data;
+ if (s->type == SymIdentifier && s->storage == AutoStorage
+ && s->flag == symbol_parm) {
+ s->level = level;
+ s->flag = symbol_none;
+ }
}
return true;
}

Return to:

Send suggestions and report system problems to the System administrator.