powerpc/85xx: Refactor some defines out of corenet_ds.h
[platform/kernel/u-boot.git] / lib / hashtable.c
index b47f3b6..026dbca 100644 (file)
@@ -65,7 +65,7 @@
  * which describes the current status.
  */
 typedef struct _ENTRY {
-       unsigned int used;
+       int used;
        ENTRY entry;
 } _ENTRY;
 
@@ -152,10 +152,10 @@ void hdestroy_r(struct hsearch_data *htab)
 
        /* free used memory */
        for (i = 1; i <= htab->size; ++i) {
-               if (htab->table[i].used) {
+               if (htab->table[i].used > 0) {
                        ENTRY *ep = &htab->table[i].entry;
 
-                       free(ep->key);
+                       free((void *)ep->key);
                        free(ep->data);
                }
        }
@@ -202,6 +202,49 @@ void hdestroy_r(struct hsearch_data *htab)
  *   example for functions like hdelete().
  */
 
+/*
+ * hstrstr_r - return index to entry whose key and/or data contains match
+ */
+int hstrstr_r(const char *match, int last_idx, ENTRY ** retval,
+             struct hsearch_data *htab)
+{
+       unsigned int idx;
+
+       for (idx = last_idx + 1; idx < htab->size; ++idx) {
+               if (htab->table[idx].used <= 0)
+                       continue;
+               if (strstr(htab->table[idx].entry.key, match) ||
+                   strstr(htab->table[idx].entry.data, match)) {
+                       *retval = &htab->table[idx].entry;
+                       return idx;
+               }
+       }
+
+       __set_errno(ESRCH);
+       *retval = NULL;
+       return 0;
+}
+
+int hmatch_r(const char *match, int last_idx, ENTRY ** retval,
+            struct hsearch_data *htab)
+{
+       unsigned int idx;
+       size_t key_len = strlen(match);
+
+       for (idx = last_idx + 1; idx < htab->size; ++idx) {
+               if (htab->table[idx].used <= 0)
+                       continue;
+               if (!strncmp(match, htab->table[idx].entry.key, key_len)) {
+                       *retval = &htab->table[idx].entry;
+                       return idx;
+               }
+       }
+
+       __set_errno(ESRCH);
+       *retval = NULL;
+       return 0;
+}
+
 int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
              struct hsearch_data *htab)
 {
@@ -209,6 +252,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
        unsigned int count;
        unsigned int len = strlen(item.key);
        unsigned int idx;
+       unsigned int first_deleted = 0;
 
        /* Compute an value for the given string. Perhaps use a better method. */
        hval = len;
@@ -236,6 +280,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
                 */
                unsigned hval2;
 
+               if (htab->table[idx].used == -1
+                   && !first_deleted)
+                       first_deleted = idx;
+
                if (htab->table[idx].used == hval
                    && strcmp(item.key, htab->table[idx].entry.key) == 0) {
                        /* Overwrite existing value? */
@@ -315,6 +363,9 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
                 * Create new entry;
                 * create copies of item.key and item.data
                 */
+               if (first_deleted)
+                       idx = first_deleted;
+
                htab->table[idx].used = hval;
                htab->table[idx].entry.key = strdup(item.key);
                htab->table[idx].entry.data = strdup(item.data);
@@ -365,9 +416,9 @@ int hdelete_r(const char *key, struct hsearch_data *htab)
        /* free used ENTRY */
        debug("hdelete: DELETING key \"%s\"\n", key);
 
-       free(ep->key);
+       free((void *)ep->key);
        free(ep->data);
-       htab->table[idx].used = 0;
+       htab->table[idx].used = -1;
 
        --htab->filled;
 
@@ -447,7 +498,7 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep,
         */
        for (i = 1, n = 0, totlen = 0; i <= htab->size; ++i) {
 
-               if (htab->table[i].used) {
+               if (htab->table[i].used > 0) {
                        ENTRY *ep = &htab->table[i].entry;
 
                        list[n++] = ep;
@@ -513,7 +564,7 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep,
         * export sorted list of result data
         */
        for (i = 0, p = res; i < n; ++i) {
-               char *s;
+               const char *s;
 
                s = list[i]->key;
                while (*s)