Imported from ../bash-2.0.tar.gz.
[platform/upstream/bash.git] / hashlib.c
similarity index 82%
rename from hash.c
rename to hashlib.c
index b955b3f..37e4dc9 100644 (file)
--- a/hash.c
+++ b/hashlib.c
@@ -1,4 +1,4 @@
-/* Hash.c -- Where hashing for bash is done. */
+/* hashlib.c -- functions to manage and access hash tables for bash. */
 
 /* Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
 
@@ -18,8 +18,7 @@ You should have received a copy of the GNU General Public License along
 with Bash; see the file COPYING.  If not, write to the Free Software
 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
 
-/* There appears to be library functions for this stuff, but it seems like
-   a lot of overhead, so I just implemented this hashing stuff on my own. */
+#include "config.h"
 
 #if defined (HAVE_STRING_H)
 #  include <string.h>
@@ -33,12 +32,12 @@ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
 #  include "ansi_stdlib.h"
 #endif /* HAVE_STDLIB_H */
 
-#include "shell.h"
-#include "hash.h"
-
-HASH_TABLE *hashed_filenames;
+#if defined (HAVE_UNISTD_H)
+#  include <unistd.h>
+#endif
 
-#define FILENAME_HASH_BUCKETS 107
+#include "shell.h"
+#include "hashlib.h"
 
 /* Zero the buckets in TABLE. */
 static void
@@ -56,8 +55,9 @@ HASH_TABLE *
 make_hash_table (buckets)
      int buckets;
 {
-  HASH_TABLE *new_table = (HASH_TABLE *)xmalloc (sizeof (HASH_TABLE));
+  HASH_TABLE *new_table;
 
+  new_table = (HASH_TABLE *)xmalloc (sizeof (HASH_TABLE));
   if (buckets == 0)
     buckets = DEFAULT_HASH_BUCKETS;
 
@@ -69,15 +69,6 @@ make_hash_table (buckets)
   return (new_table);
 }
 
-#if 0
-/* UNUSED */
-/* Create the hash table for filenames that we use in the shell. */
-initialize_hashed_filenames ()
-{
-  hashed_filenames = make_hash_table (FILENAME_HASH_BUCKETS);
-}
-#endif
-
 /* Return the location of the bucket which should contain the data
    for STRING.  TABLE is a pointer to a HASH_TABLE. */
 
@@ -107,21 +98,18 @@ find_hash_item (string, table)
   BUCKET_CONTENTS *list;
   int which_bucket;
 
-  if (!table)
+  if (table == 0)
     return (BUCKET_CONTENTS *)NULL;
 
   which_bucket = hash_string (string, table);
 
-  list = table->bucket_array[which_bucket];
-
-  while (list)
+  for (list = table->bucket_array[which_bucket]; list; list = list->next)
     {
       if (STREQ (list->key, string))
        {
          list->times_found++;
          return (list);
        }
-      else list = list->next;
     }
   return (BUCKET_CONTENTS *)NULL;
 }
@@ -137,14 +125,12 @@ remove_hash_item (string, table)
   int the_bucket;
   BUCKET_CONTENTS *prev, *temp;
 
-  if (!table)
+  if (table == 0)
     return (BUCKET_CONTENTS *)NULL;
 
   the_bucket = hash_string (string, table);
   prev = (BUCKET_CONTENTS *)NULL;
-  temp = table->bucket_array[the_bucket];
-
-  while (temp)
+  for (temp = table->bucket_array[the_bucket]; temp; temp = temp->next)
     {
       if (STREQ (temp->key, string))
        {
@@ -157,7 +143,6 @@ remove_hash_item (string, table)
          return (temp);
        }
       prev = temp;
-      temp = temp->next;
     }
   return ((BUCKET_CONTENTS *) NULL);
 }
@@ -170,13 +155,14 @@ add_hash_item (string, table)
      HASH_TABLE *table;
 {
   BUCKET_CONTENTS *item;
+  int bucket;
 
-  if (!table)
+  if (table == 0)
     table = make_hash_table (0);
 
   if ((item = find_hash_item (string, table)) == 0)
     {
-      int bucket = hash_string (string, table);
+      bucket = hash_string (string, table);
       item = table->bucket_array[bucket];
 
       while (item && item->next)
@@ -204,6 +190,37 @@ add_hash_item (string, table)
   return (item);
 }
 
+/* Remove and discard all entries in TABLE.  If FREE_DATA is non-null, it
+   is a function to call to dispose of a hash item's data.  Otherwise,
+   free() is called. */
+void
+flush_hash_table (table, free_data)
+     HASH_TABLE *table;
+     VFunction *free_data;
+{
+  int i;
+  register BUCKET_CONTENTS *bucket, *item;
+
+  for (i = 0; i < table->nbuckets; i++)
+    {
+      bucket = table->bucket_array[i];
+
+      while (bucket)
+       {
+         item = bucket;
+         bucket = bucket->next;
+
+         if (free_data)
+           (*free_data) (item->data);
+         else
+           free (item->data);
+         free (item->key);
+         free (item);
+       }
+      table->bucket_array[i] = (BUCKET_CONTENTS *)NULL;
+    }
+}
+
 /* Return the bucket_contents list of bucket BUCKET in TABLE.  If
    TABLE doesn't have BUCKET buckets, return NULL. */
 #undef get_hash_bucket
@@ -233,7 +250,7 @@ xmalloc (bytes)
   char *result = (char *)malloc (bytes);
   if (!result)
     {
-      fprintf (stderr, "Out of memory!");
+      fprintf (stderr, "hash: out of virtual memory\n");
       abort ();
     }
   return (result);
@@ -246,7 +263,7 @@ main ()
   BUCKET_CONTENTS *tt;
 
   table = make_hash_table (NBUCKETS);
-  
+
   for (;;)
     {
       char *temp_string;
@@ -266,7 +283,7 @@ main ()
          count++;
        }
     }
-  
+
   printf ("You have entered %d (%d) items.  The distribution is:\n",
          table->nentries, count);
 
@@ -276,7 +293,7 @@ main ()
     {
       int bcount;
       register BUCKET_CONTENTS *list = get_hash_bucket (count, table);
-    
+
       printf ("slot %3d: ", count);
       bcount = 0;
 
@@ -289,9 +306,3 @@ main ()
 }
 
 #endif /* TEST_HASHING */
-\f
-/*
- * Local variables:
- * compile-command: "gcc -g -DTEST_HASHING -o hash hash.c"
- * end:
- */