Cleanup the rest of pkg_parse.c. Give some functions more appropriate names too.
[oweals/opkg-lede.git] / libopkg / hash_table.c
index c0c0530372d2e22317426a77ccc7d97d2e8a4da8..9e42da07a936220dcae41ad1593a32af78a6a9d3 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 #include "hash_table.h"
 #include "opkg_message.h"
+#include "libbb/libbb.h"
 
 
 static int hash_index(hash_table_t *hash, const char *pkg_name);
@@ -68,11 +69,8 @@ int hash_table_init(const char *name, hash_table_t *hash, int len)
     --picker;
 
     hash->n_entries = *picker;
-    hash->entries = (hash_entry_t *)calloc(hash->n_entries, sizeof(hash_entry_t));
-    if (hash->entries == NULL) {
-       fprintf(stderr, "%s: Out of memory.\n", __FUNCTION__);
-       return ENOMEM;
-    }
+    hash->entries = xcalloc(hash->n_entries, sizeof(hash_entry_t));
+
     return 0;
 }
 
@@ -85,6 +83,7 @@ void hash_table_deinit(hash_table_t *hash)
     /* free the reminaing entries */
     for (i = 0; i < hash->n_entries; i++) {
        hash_entry_t *hash_entry = (hash->entries + i);
+       free (hash_entry->key);
        /* skip the first entry as this is part of the array */
        hash_entry = hash_entry->next;
         while (hash_entry)
@@ -124,11 +123,9 @@ int hash_table_insert(hash_table_t *hash, const char *key, void *value)
 {
      int ndx= hash_index(hash, key);
      hash_entry_t *hash_entry = hash->entries + ndx;
-     if (0) opkg_message(NULL, OPKG_DEBUG2, "Function: %s. Inserting in hash for '%s' \n", __FUNCTION__, key);
      if (hash_entry->key) {
          if (strcmp(hash_entry->key, key) == 0) {
               /* alread in table, update the value */
-               if (0) opkg_message(NULL, OPKG_DEBUG2, "Function: %s. Value already in hash for '%s' \n", __FUNCTION__, key);
               hash_entry->data = value;
               return 0;
          } else {
@@ -137,24 +134,56 @@ int hash_table_insert(hash_table_t *hash, const char *key, void *value)
                * then add a new entry
                * before we can hook up the value
                */
-               if (0) opkg_message(NULL, OPKG_DEBUG2, "Function: %s. Value already in hash by collision for '%s' \n", __FUNCTION__, key);
-              while (hash_entry->next)
+              while (hash_entry->next) {
                    hash_entry = hash_entry->next;
-              hash_entry->next = (hash_entry_t *)malloc(sizeof(hash_entry_t));
-              if (!hash_entry->next) {
-                   return -ENOMEM;
-              }
+                    if (strcmp(hash_entry->key, key) == 0) {
+                        hash_entry->data = value;
+                        return 0;
+                    }
+               }
+              hash_entry->next = xcalloc(1, sizeof(hash_entry_t));
               hash_entry = hash_entry->next;
               hash_entry->next = NULL;
          }
      }
      hash->n_elements++;
-     hash_entry->key = strdup(key);
+     hash_entry->key = xstrdup(key);
      hash_entry->data = value;
 
      return 0;
 }
 
+int hash_table_remove(hash_table_t *hash, const char *key)
+{
+    int ndx= hash_index(hash, key);
+    hash_entry_t *hash_entry = hash->entries + ndx;
+    hash_entry_t *next_entry=NULL, *last_entry=NULL;
+    while (hash_entry) 
+    {
+        if (hash_entry->key) 
+        {
+            if (strcmp(key, hash_entry->key) == 0) {
+                free(hash_entry->key);
+                if (last_entry) {
+                    last_entry->next = hash_entry->next;
+                    free(hash_entry);
+                } else {
+                    next_entry = hash_entry->next;
+                    if (next_entry) {
+                        memmove(hash_entry, next_entry, sizeof(hash_entry_t));
+                        free(next_entry);
+                    } else {
+                        memset(hash_entry, 0 , sizeof(hash_entry_t));
+                    }
+                }
+                return 1;
+            }
+        }
+        last_entry = hash_entry;
+        hash_entry = hash_entry->next;
+    }
+    return 0;
+}
 
 void hash_table_foreach(hash_table_t *hash, void (*f)(const char *key, void *entry, void *data), void *data)
 {