diff options
author | Marc Espie <espie@cvs.openbsd.org> | 1999-05-26 13:38:57 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 1999-05-26 13:38:57 +0000 |
commit | 0126e157b87f137fc08dc7f46f6c291b9d06ac5d (patch) | |
tree | f8555e3e504eb82b4cd3cba5cec20ae4ce8124ff /gnu/egcs/gcc/hash.c | |
parent | ff8e9a4356e55ed142306c3a375fa280800abc86 (diff) |
egcs projects compiler system
Exact copy of the snapshot, except for the removal of
texinfo/
gcc/ch/
libchill/
Diffstat (limited to 'gnu/egcs/gcc/hash.c')
-rw-r--r-- | gnu/egcs/gcc/hash.c | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/gnu/egcs/gcc/hash.c b/gnu/egcs/gcc/hash.c new file mode 100644 index 00000000000..f333c6c4d70 --- /dev/null +++ b/gnu/egcs/gcc/hash.c @@ -0,0 +1,245 @@ +/* hash.c -- hash table routines + Copyright (C) 1993, 1994, 1998 Free Software Foundation, Inc. + Written by Steve Chamberlain <sac@cygnus.com> + +This file was lifted from BFD, the Binary File Descriptor library. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +#include "config.h" +#include "system.h" +#include "hash.h" +#include "obstack.h" +#include "toplev.h" + +/* Obstack allocation and deallocation routines. */ +#define obstack_chunk_alloc xmalloc +#define obstack_chunk_free free + +/* The default number of entries to use when creating a hash table. */ +#define DEFAULT_SIZE (1009) + +/* Create a new hash table, given a number of entries. */ + +boolean +hash_table_init_n (table, newfunc, hash, comp, size) + struct hash_table *table; + struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *, + struct hash_table *, + hash_table_key)); + unsigned long (*hash) PARAMS ((hash_table_key)); + boolean (*comp) PARAMS ((hash_table_key, hash_table_key)); + unsigned int size; +{ + unsigned int alloc; + + alloc = size * sizeof (struct hash_entry *); + if (!obstack_begin (&table->memory, alloc)) + { + error ("no memory"); + return false; + } + table->table = ((struct hash_entry **) + obstack_alloc (&table->memory, alloc)); + if (!table->table) + { + error ("no memory"); + return false; + } + 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, comp) + struct hash_table *table; + struct hash_entry *(*newfunc) PARAMS ((struct hash_entry *, + 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, hash, comp, DEFAULT_SIZE); +} + +/* Free a hash table. */ + +void +hash_table_free (table) + struct hash_table *table; +{ + obstack_free (&table->memory, (PTR) NULL); +} + +/* 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, key, create, copy) + struct hash_table *table; + hash_table_key key; + boolean create; + hash_table_key (*copy) PARAMS ((struct obstack* memory, + hash_table_key key)); +{ + register unsigned long hash; + struct hash_entry *hashp; + unsigned int index; + + hash = (*table->hash)(key); + + index = hash % table->size; + for (hashp = table->table[index]; + hashp != (struct hash_entry *) NULL; + hashp = hashp->next) + { + if (hashp->hash == hash + && (*table->comp)(hashp->key, key)) + return hashp; + } + + if (! create) + return (struct hash_entry *) NULL; + + hashp = (*table->newfunc) ((struct hash_entry *) NULL, table, key); + if (hashp == (struct hash_entry *) NULL) + return (struct hash_entry *) NULL; + if (copy) + key = (*copy) (&table->memory, key); + hashp->key = key; + hashp->hash = hash; + hashp->next = table->table[index]; + table->table[index] = hashp; + + return hashp; +} + +/* Base method for creating a new hash table entry. */ + +/*ARGSUSED*/ +struct hash_entry * +hash_newfunc (entry, table, p) + struct hash_entry *entry; + struct hash_table *table; + hash_table_key p; +{ + if (entry == (struct hash_entry *) NULL) + entry = ((struct hash_entry *) + hash_allocate (table, sizeof (struct hash_entry))); + return entry; +} + +/* Allocate space in a hash table. */ + +PTR +hash_allocate (table, size) + struct hash_table *table; + unsigned int size; +{ + PTR ret; + + ret = obstack_alloc (&table->memory, size); + if (ret == NULL && size != 0) + error ("no memory"); + return ret; +} + +/* Traverse a hash table. */ + +void +hash_traverse (table, func, info) + struct hash_table *table; + boolean (*func) PARAMS ((struct hash_entry *, hash_table_key)); + PTR info; +{ + unsigned int i; + + for (i = 0; i < table->size; i++) + { + struct hash_entry *p; + + for (p = table->table[i]; p != NULL; p = p->next) + { + if (! (*func) (p, info)) + return; + } + } +} + +/* 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; +} |