hash.h (hash_table_key): New type.

* hash.h (hash_table_key): New type.
	(hash_entry): Change `string' field to generic `key'.
	(hash_table): Add `comp' and `hash' functions.
	(hash_table_init): Take them as input.
	(hash_table_init_n): Likewise.
	(hash_lookup): Modify for generic keys.
	(hash_newfunc): Likewise.
	(hash_traverse): Likewise.
	(string_hash): New function.
	(string_compare): Likewise.
	(string_copy): Likewise.
	* hash.c (hash_table_init_n): Modify for generic keys.
	(hash_table_init): Likewise.
	(hash_lookup): Likewise.
	(hash_newfunc): Likewise.
	(hash_traverse): Likewise.
	(string_hash): Split out from hash_lookup.
	(string_compare): New function.
	(string_copy): Split out from hash_lookup.
	* tlink.c (symbol_hash_newfunc): Modify for new interfaces to hash
	tables.
	(symbol_hash_lookup): Likewise.
	(file_hash_newfunc): Likewise.
	(file_hash_lookup): Likewise.
	(demangled_hash_newfunc): Likewise.
	(demangled_hash_lookup): Likewise.
	(tlink_int): Likewise.
	(read_repo_file): Likewise.
	(recompile_files): Likewise.
	(demangle_new_symbols): Likewise.
	(scan_linker_output): Likewise.

From-SVN: r23683
This commit is contained in:
Mark Mitchell 1998-11-17 11:50:24 +00:00 committed by Mark Mitchell
parent e398aa8062
commit a87ec9e655
4 changed files with 185 additions and 75 deletions

View File

@ -1,3 +1,37 @@
Tue Nov 17 11:51:16 1998 Mark Mitchell <mark@markmitchell.com>
* hash.h (hash_table_key): New type.
(hash_entry): Change `string' field to generic `key'.
(hash_table): Add `comp' and `hash' functions.
(hash_table_init): Take them as input.
(hash_table_init_n): Likewise.
(hash_lookup): Modify for generic keys.
(hash_newfunc): Likewise.
(hash_traverse): Likewise.
(string_hash): New function.
(string_compare): Likewise.
(string_copy): Likewise.
* hash.c (hash_table_init_n): Modify for generic keys.
(hash_table_init): Likewise.
(hash_lookup): Likewise.
(hash_newfunc): Likewise.
(hash_traverse): Likewise.
(string_hash): Split out from hash_lookup.
(string_compare): New function.
(string_copy): Split out from hash_lookup.
* tlink.c (symbol_hash_newfunc): Modify for new interfaces to hash
tables.
(symbol_hash_lookup): Likewise.
(file_hash_newfunc): Likewise.
(file_hash_lookup): Likewise.
(demangled_hash_newfunc): Likewise.
(demangled_hash_lookup): Likewise.
(tlink_int): Likewise.
(read_repo_file): Likewise.
(recompile_files): Likewise.
(demangle_new_symbols): Likewise.
(scan_linker_output): Likewise.
Tue Nov 17 17:13:53 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* flow.c (insn_dead_p): New argument NOTES. Changed all callers.

View File

@ -36,11 +36,13 @@ extern char * xmalloc ();
/* Create a new hash table, given a number of entries. */
boolean
hash_table_init_n (table, newfunc, size)
hash_table_init_n (table, newfunc, hash, comp, size)
struct hash_table *table;
struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
struct hash_table *,
const char *));
struct hash_table *,
hash_table_key));
unsigned long (*hash) (hash_table_key);
boolean (*comp) (hash_table_key, hash_table_key);
unsigned int size;
{
unsigned int alloc;
@ -61,19 +63,23 @@ hash_table_init_n (table, newfunc, size)
memset ((PTR) table->table, 0, alloc);
table->size = size;
table->newfunc = newfunc;
table->hash = hash;
table->comp = comp;
return true;
}
/* Create a new hash table with the default number of entries. */
boolean
hash_table_init (table, newfunc)
hash_table_init (table, newfunc, hash, comp)
struct hash_table *table;
struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
struct hash_table *,
const char *));
struct hash_table *,
hash_table_key));
unsigned long (*hash) PARAMS ((hash_table_key));
boolean (*comp) PARAMS ((hash_table_key, hash_table_key));
{
return hash_table_init_n (table, newfunc, DEFAULT_SIZE);
return hash_table_init_n (table, newfunc, hash, comp, DEFAULT_SIZE);
}
/* Free a hash table. */
@ -85,33 +91,22 @@ hash_table_free (table)
obstack_free (&table->memory, (PTR) NULL);
}
/* Look up a string in a hash table. */
/* Look up KEY in TABLE. If CREATE is non-NULL a new entry is
created if one does not previously exist. */
struct hash_entry *
hash_lookup (table, string, create, copy)
hash_lookup (table, key, create, copy)
struct hash_table *table;
const char *string;
hash_table_key key;
boolean create;
boolean copy;
hash_table_key (*copy) PARAMS ((struct obstack* memory,
hash_table_key key));
{
register const unsigned char *s;
register unsigned long hash;
register unsigned int c;
struct hash_entry *hashp;
unsigned int len;
unsigned int index;
hash = 0;
len = 0;
s = (const unsigned char *) string;
while ((c = *s++) != '\0')
{
hash += c + (c << 17);
hash ^= hash >> 2;
++len;
}
hash += len + (len << 17);
hash ^= hash >> 2;
hash = (*table->hash)(key);
index = hash % table->size;
for (hashp = table->table[index];
@ -119,30 +114,19 @@ hash_lookup (table, string, create, copy)
hashp = hashp->next)
{
if (hashp->hash == hash
&& strcmp (hashp->string, string) == 0)
&& (*table->comp)(hashp->key, key))
return hashp;
}
if (! create)
return (struct hash_entry *) NULL;
hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, string);
hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, key);
if (hashp == (struct hash_entry *) NULL)
return (struct hash_entry *) NULL;
if (copy)
{
char *new;
new = (char *) obstack_alloc (&table->memory, len + 1);
if (!new)
{
error ("no memory");
return (struct hash_entry *) NULL;
}
strcpy (new, string);
string = new;
}
hashp->string = string;
key = (*copy) (&table->memory, key);
hashp->key = key;
hashp->hash = hash;
hashp->next = table->table[index];
table->table[index] = hashp;
@ -154,10 +138,10 @@ hash_lookup (table, string, create, copy)
/*ARGSUSED*/
struct hash_entry *
hash_newfunc (entry, table, string)
hash_newfunc (entry, table, p)
struct hash_entry *entry;
struct hash_table *table;
const char *string;
hash_table_key p;
{
if (entry == (struct hash_entry *) NULL)
entry = ((struct hash_entry *)
@ -185,7 +169,7 @@ hash_allocate (table, size)
void
hash_traverse (table, func, info)
struct hash_table *table;
boolean (*func) PARAMS ((struct hash_entry *, PTR));
boolean (*func) PARAMS ((struct hash_entry *, hash_table_key));
PTR info;
{
unsigned int i;
@ -201,3 +185,62 @@ hash_traverse (table, func, info)
}
}
}
/* Hash a string. Return a hash-code for the string. */
unsigned long
string_hash (k)
hash_table_key k;
{
const unsigned char *s;
unsigned long hash;
unsigned char c;
unsigned int len;
s = (const unsigned char *) k;
hash = 0;
len = 0;
while ((c = *s++) != '\0')
{
hash += c + (c << 17);
hash ^= hash >> 2;
++len;
}
hash += len + (len << 17);
hash ^= hash >> 2;
return hash;
}
/* Compare two strings. Return non-zero iff the two strings are
the same. */
boolean
string_compare (k1, k2)
hash_table_key k1;
hash_table_key k2;
{
return (strcmp ((char*) k1, (char*) k2) == 0);
}
/* Copy K to OBSTACK. */
hash_table_key
string_copy (memory, k)
struct obstack* memory;
hash_table_key k;
{
char *new;
char *string = (char*) k;
new = (char *) obstack_alloc (memory, strlen (string) + 1);
if (!new)
{
error ("no memory");
return NULL;
}
strcpy (new, string);
return new;
}

View File

@ -26,6 +26,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
typedef enum {false, true} boolean;
typedef PTR hash_table_key;
/* Hash table routines. There is no way to free up a hash table. */
/* An element in the hash table. Most uses will actually use a larger
@ -35,8 +37,8 @@ struct hash_entry
{
/* Next entry for this hash code. */
struct hash_entry *next;
/* String being hashed. */
const char *string;
/* The thing being hashed. */
hash_table_key key;
/* Hash code. This is the full hash code, not the index into the
table. */
unsigned long hash;
@ -59,7 +61,11 @@ struct hash_table
only if the argument is NULL. */
struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *,
struct hash_table *,
const char *));
hash_table_key));
/* A function to compute the hash code for a key in the hash table. */
unsigned long (*hash) PARAMS ((hash_table_key));
/* A function to compare two keys. */
boolean (*comp) PARAMS ((hash_table_key, hash_table_key));
/* An obstack for this hash table. */
struct obstack memory;
};
@ -69,31 +75,35 @@ extern boolean hash_table_init
PARAMS ((struct hash_table *,
struct hash_entry *(*) (struct hash_entry *,
struct hash_table *,
const char *)));
hash_table_key),
unsigned long (*hash) (hash_table_key),
boolean (*comp) (hash_table_key, hash_table_key)));
/* Initialize a hash table specifying a size. */
extern boolean hash_table_init_n
PARAMS ((struct hash_table *,
struct hash_entry *(*) (struct hash_entry *,
struct hash_table *,
const char *),
hash_table_key),
unsigned long (*hash) (hash_table_key),
boolean (*comp) (hash_table_key, hash_table_key),
unsigned int size));
/* Free up a hash table. */
extern void hash_table_free PARAMS ((struct hash_table *));
/* Look up a string in a hash table. If CREATE is true, a new entry
will be created for this string if one does not already exist. The
COPY argument must be true if this routine should copy the string
into newly allocated memory when adding an entry. */
/* Look up KEY in a hash table. If CREATE is true, a new entry
will be created for this KEY if one does not already exist. If
COPY is non-NULL, it is used to copy the KEY before storing it in
the hash table. */
extern struct hash_entry *hash_lookup
PARAMS ((struct hash_table *, const char *, boolean create,
boolean copy));
PARAMS ((struct hash_table *, hash_table_key key, boolean create,
hash_table_key (*copy)(struct obstack*, hash_table_key)));
/* Base method for creating a hash table entry. */
extern struct hash_entry *hash_newfunc
PARAMS ((struct hash_entry *, struct hash_table *,
const char *));
PARAMS ((struct hash_entry *, struct hash_table *,
hash_table_key key));
/* Grab some space for a hash table entry. */
extern PTR hash_allocate PARAMS ((struct hash_table *,
@ -104,5 +114,17 @@ extern PTR hash_allocate PARAMS ((struct hash_table *,
INFO argument is passed to the function. */
extern void hash_traverse PARAMS ((struct hash_table *,
boolean (*) (struct hash_entry *,
PTR),
PTR info));
hash_table_key),
hash_table_key info));
/* Hash a string K, which is really of type `char*'. */
extern unsigned long string_hash PARAMS ((hash_table_key k));
/* Compare two strings K1, K2 which are really of type `char*'. */
extern boolean string_compare PARAMS ((hash_table_key k1,
hash_table_key k2));
/* Copy a string K, which is really of type `char*'. */
extern hash_table_key string_copy PARAMS ((struct obstack* memory,
hash_table_key k));

View File

@ -90,7 +90,8 @@ symbol_hash_newfunc (entry, table, string)
return NULL;
}
ret = ((struct symbol_hash_entry *)
hash_newfunc ((struct hash_entry *) ret, table, string));
hash_newfunc ((struct hash_entry *) ret, table,
(hash_table_key) string));
ret->file = NULL;
ret->chosen = 0;
ret->tweaking = 0;
@ -104,7 +105,8 @@ symbol_hash_lookup (string, create)
boolean create;
{
return ((struct symbol_hash_entry *)
hash_lookup (&symbol_table, string, create, true));
hash_lookup (&symbol_table, (hash_table_key) string,
create, &string_copy));
}
static struct hash_table file_table;
@ -124,7 +126,8 @@ file_hash_newfunc (entry, table, string)
return NULL;
}
ret = ((struct file_hash_entry *)
hash_newfunc ((struct hash_entry *) ret, table, string));
hash_newfunc ((struct hash_entry *) ret, table,
(hash_table_key) string));
ret->args = NULL;
ret->dir = NULL;
ret->main = NULL;
@ -137,7 +140,8 @@ file_hash_lookup (string)
const char *string;
{
return ((struct file_hash_entry *)
hash_lookup (&file_table, string, true, true));
hash_lookup (&file_table, (hash_table_key) string, true,
&string_copy));
}
static struct hash_table demangled_table;
@ -157,7 +161,8 @@ demangled_hash_newfunc (entry, table, string)
return NULL;
}
ret = ((struct demangled_hash_entry *)
hash_newfunc ((struct hash_entry *) ret, table, string));
hash_newfunc ((struct hash_entry *) ret, table,
(hash_table_key) string));
ret->mangled = NULL;
return (struct hash_entry *) ret;
}
@ -168,7 +173,8 @@ demangled_hash_lookup (string, create)
boolean create;
{
return ((struct demangled_hash_entry *)
hash_lookup (&demangled_table, string, create, true));
hash_lookup (&demangled_table, (hash_table_key) string,
create, &string_copy));
}
/* Stack code. */
@ -251,9 +257,12 @@ tlink_init ()
{
char *p;
hash_table_init (&symbol_table, symbol_hash_newfunc);
hash_table_init (&file_table, file_hash_newfunc);
hash_table_init (&demangled_table, demangled_hash_newfunc);
hash_table_init (&symbol_table, symbol_hash_newfunc, &string_hash,
&string_compare);
hash_table_init (&file_table, file_hash_newfunc, &string_hash,
&string_compare);
hash_table_init (&demangled_table, demangled_hash_newfunc,
&string_hash, &string_compare);
obstack_begin (&symbol_stack_obstack, 0);
obstack_begin (&file_stack_obstack, 0);
@ -367,10 +376,11 @@ read_repo_file (f)
file *f;
{
char c;
FILE *stream = fopen (f->root.string, "r");
FILE *stream = fopen ((char*) f->root.key, "r");
if (tlink_verbose >= 2)
fprintf (stderr, "collect: reading %s\n", f->root.string);
fprintf (stderr, "collect: reading %s\n",
(char*) f->root.key);
while (fscanf (stream, "%c ", &c) == 1)
{
@ -432,8 +442,8 @@ recompile_files ()
while ((f = file_pop ()) != NULL)
{
char *line, *command;
FILE *stream = fopen (f->root.string, "r");
char *outname = frob_extension (f->root.string, ".rnw");
FILE *stream = fopen ((char*) f->root.key, "r");
char *outname = frob_extension ((char*) f->root.key, ".rnw");
FILE *output = fopen (outname, "w");
while ((line = tfgets (stream)) != NULL)
@ -448,7 +458,7 @@ recompile_files ()
}
fclose (stream);
fclose (output);
rename (outname, f->root.string);
rename (outname, (char*) f->root.key);
obstack_grow (&temporary_obstack, "cd ", 3);
obstack_grow (&temporary_obstack, f->dir, strlen (f->dir));
@ -507,13 +517,14 @@ demangle_new_symbols ()
while ((sym = symbol_pop ()) != NULL)
{
demangled *dem;
char *p = cplus_demangle (sym->root.string, DMGL_PARAMS | DMGL_ANSI);
char *p = cplus_demangle ((char*) sym->root.key,
DMGL_PARAMS | DMGL_ANSI);
if (! p)
continue;
dem = demangled_hash_lookup (p, true);
dem->mangled = sym->root.string;
dem->mangled = (char*) sym->root.key;
}
}
@ -584,7 +595,7 @@ scan_linker_output (fname)
{
if (tlink_verbose >= 2)
fprintf (stderr, "collect: tweaking %s in %s\n",
sym->root.string, sym->file->root.string);
(char*) sym->root.key, (char*) sym->file->root.key);
sym->tweaking = 1;
file_push (sym->file);
}