daily update
[deliverable/binutils-gdb.git] / gas / hash.c
index 29c97b94b35b909ee0d0e86ea7612e18232ec196..6977ceeb53284c98e986d653f5152be82577547f 100644 (file)
@@ -17,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with GAS; see the file COPYING.  If not, write to the Free
-   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+   Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
+   02110-1301, USA.  */
 
 /* This version of the hash table code is a wholescale replacement of
    the old hash table code, which was fairly bad.  This is based on
@@ -150,19 +150,13 @@ hash_die (struct hash_control *table)
    Each time we look up a string, we move it to the start of the list
    for its hash code, to take advantage of referential locality.  */
 
-static struct hash_entry *hash_lookup (struct hash_control *,
-                                      const char *,
-                                      struct hash_entry ***,
-                                      unsigned long *);
-
 static struct hash_entry *
-hash_lookup (struct hash_control *table, const char *key,
+hash_lookup (struct hash_control *table, const char *key, size_t len,
             struct hash_entry ***plist, unsigned long *phash)
 {
-  register unsigned long hash;
-  unsigned int len;
-  register const unsigned char *s;
-  register unsigned int c;
+  unsigned long hash;
+  size_t n;
+  unsigned int c;
   unsigned int index;
   struct hash_entry **list;
   struct hash_entry *p;
@@ -173,13 +167,11 @@ hash_lookup (struct hash_control *table, const char *key,
 #endif
 
   hash = 0;
-  len = 0;
-  s = (const unsigned char *) key;
-  while ((c = *s++) != '\0')
+  for (n = 0; n < len; n++)
     {
+      c = key[n];
       hash += c + (c << 17);
       hash ^= hash >> 2;
-      ++len;
     }
   hash += len + (len << 17);
   hash ^= hash >> 2;
@@ -206,7 +198,7 @@ hash_lookup (struct hash_control *table, const char *key,
          ++table->string_compares;
 #endif
 
-         if (strcmp (p->string, key) == 0)
+         if (strncmp (p->string, key, len) == 0 && p->string[len] == '\0')
            {
              if (prev != NULL)
                {
@@ -237,7 +229,7 @@ hash_insert (struct hash_control *table, const char *key, PTR value)
   struct hash_entry **list;
   unsigned long hash;
 
-  p = hash_lookup (table, key, &list, &hash);
+  p = hash_lookup (table, key, strlen (key), &list, &hash);
   if (p != NULL)
     return "exists";
 
@@ -267,7 +259,7 @@ hash_jam (struct hash_control *table, const char *key, PTR value)
   struct hash_entry **list;
   unsigned long hash;
 
-  p = hash_lookup (table, key, &list, &hash);
+  p = hash_lookup (table, key, strlen (key), &list, &hash);
   if (p != NULL)
     {
 #ifdef HASH_STATISTICS
@@ -294,6 +286,31 @@ hash_jam (struct hash_control *table, const char *key, PTR value)
   return NULL;
 }
 
+/* Replace an existing entry in a hash table.  This returns the old
+   value stored for the entry.  If the entry is not found in the hash
+   table, this does nothing and returns NULL.  */
+
+PTR
+hash_replace (struct hash_control *table, const char *key, PTR value)
+{
+  struct hash_entry *p;
+  PTR ret;
+
+  p = hash_lookup (table, key, strlen (key), NULL, NULL);
+  if (p == NULL)
+    return NULL;
+
+#ifdef HASH_STATISTICS
+  ++table->replacements;
+#endif
+
+  ret = p->data;
+
+  p->data = value;
+
+  return ret;
+}
+
 /* Find an entry in a hash table, returning its value.  Returns NULL
    if the entry is not found.  */
 
@@ -302,10 +319,54 @@ hash_find (struct hash_control *table, const char *key)
 {
   struct hash_entry *p;
 
-  p = hash_lookup (table, key, NULL, NULL);
+  p = hash_lookup (table, key, strlen (key), NULL, NULL);
+  if (p == NULL)
+    return NULL;
+
+  return p->data;
+}
+
+/* As hash_find, but KEY is of length LEN and is not guaranteed to be
+   NUL-terminated.  */
+
+PTR
+hash_find_n (struct hash_control *table, const char *key, size_t len)
+{
+  struct hash_entry *p;
+
+  p = hash_lookup (table, key, len, NULL, NULL);
+  if (p == NULL)
+    return NULL;
+
+  return p->data;
+}
+
+/* Delete an entry from a hash table.  This returns the value stored
+   for that entry, or NULL if there is no such entry.  */
+
+PTR
+hash_delete (struct hash_control *table, const char *key)
+{
+  struct hash_entry *p;
+  struct hash_entry **list;
+
+  p = hash_lookup (table, key, strlen (key), &list, NULL);
   if (p == NULL)
     return NULL;
 
+  if (p != *list)
+    abort ();
+
+#ifdef HASH_STATISTICS
+  ++table->deletions;
+#endif
+
+  *list = p->next;
+
+  /* Note that we never reclaim the memory for this entry.  If gas
+     ever starts deleting hash table entries in a big way, this will
+     have to change.  */
+
   return p->data;
 }
 
This page took 0.024893 seconds and 4 git commands to generate.