]> jfr.im git - irc/evilnet/x3.git/blobdiff - src/dict-splay.c
Minor typo in previous commit where returning 0 when it should have been 1 from opser...
[irc/evilnet/x3.git] / src / dict-splay.c
index 38117cdb7eac59500baf748ccf2b98ff071f26c9..2e6f3a1dc3c2e4a95aad3252bb6f571917b5a9a1 100644 (file)
@@ -1,11 +1,11 @@
 /* dict-splay.c - Abstract dictionary type
  * Copyright 2000-2004 srvx Development Team
  *
- * This file is part of srvx.
+ * This file is part of x3.
  *
- * srvx is free software; you can redistribute it and/or modify
+ * x3 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
+ * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
@@ -75,12 +75,15 @@ static struct dict_node*
 dict_splay(struct dict_node *node, const char *key)
 {
     struct dict_node N, *l, *r, *y;
+    int res;
+
     if (!node) return NULL;
     N.l = N.r = NULL;
     l = r = &N;
 
     while (1) {
-       int res = irccasecmp(key, node->key);
+        verify(node);
+        res = irccasecmp(key, node->key);
        if (!res) break;
        if (res < 0) {
            if (!node->l) break;
@@ -123,10 +126,18 @@ dict_splay(struct dict_node *node, const char *key)
 static void
 dict_dispose_node(struct dict_node *node, free_f free_keys, free_f free_data)
 {
-    if (free_keys && node->key)
-        free_keys((void*)node->key);
-    if (free_data && node->data)
-        free_data(node->data);
+    if (free_keys && node->key) {
+        if (free_keys == free)
+            free((void*)node->key);
+        else
+            free_keys((void*)node->key);
+    }
+    if (free_data && node->data) {
+        if (free_data == free)
+            free(node->data);
+        else
+            free_data(node->data);
+    }
     free(node);
 }
 
@@ -141,6 +152,7 @@ dict_insert(dict_t dict, const char *key, void *data)
     struct dict_node *new_node;
     if (!key)
         return;
+    verify(dict);
     new_node = malloc(sizeof(struct dict_node));
     new_node->key = key;
     new_node->data = data;
@@ -178,8 +190,18 @@ dict_insert(dict_t dict, const char *key, void *data)
            dict->root = new_node;
        } else {
            /* maybe we don't want to overwrite it .. oh well */
-           if (dict->free_data) dict->free_data(dict->root->data);
-            if (dict->free_keys) dict->free_keys((void*)dict->root->key);
+           if (dict->free_data) {
+                if (dict->free_data == free)
+                    free(dict->root->data);
+                else
+                    dict->free_data(dict->root->data);
+            }
+            if (dict->free_keys) {
+                if (dict->free_keys == free)
+                    free((void*)dict->root->key);
+                else
+                    dict->free_keys((void*)dict->root->key);
+            }
             free(new_node);
             dict->root->key = key;
            dict->root->data = data;
@@ -202,10 +224,11 @@ dict_insert(dict_t dict, const char *key, void *data)
 int
 dict_remove2(dict_t dict, const char *key, int no_dispose)
 {
-    struct dict_node *new_root;
+    struct dict_node *new_root, *old_root;
 
     if (!dict->root)
         return 0;
+    verify(dict);
     dict->root = dict_splay(dict->root, key);
     if (irccasecmp(key, dict->root->key))
         return 0;
@@ -220,13 +243,14 @@ dict_remove2(dict_t dict, const char *key, int no_dispose)
     if (dict->first == dict->root) dict->first = dict->first->next;
     if (dict->root->next) dict->root->next->prev = dict->root->prev;
     if (dict->last == dict->root) dict->last = dict->last->prev;
+    old_root = dict->root;
+    dict->root = new_root;
+    dict->count--;
     if (no_dispose) {
-        free(dict->root);
+        free(old_root);
     } else {
-        dict_dispose_node(dict->root, dict->free_keys, dict->free_data);
+        dict_dispose_node(old_root, dict->free_keys, dict->free_data);
     }
-    dict->root = new_root;
-    dict->count--;
     return 1;
 }
 
@@ -245,6 +269,7 @@ dict_find(dict_t dict, const char *key, int *found)
             *found = 0;
        return NULL;
     }
+    verify(dict);
     dict->root = dict_splay(dict->root, key);
     was_found = !irccasecmp(key, dict->root->key);
     if (found)
@@ -277,21 +302,22 @@ struct dict_sanity_struct {
 static int
 dict_sanity_check_node(struct dict_node *node, struct dict_sanity_struct *dss)
 {
+    verify(node);
     if (!node->key) {
-        snprintf(dss->error, sizeof(dss->error), "Node %p had null key", node);
+        snprintf(dss->error, sizeof(dss->error), "Node %p had null key", (void*)node);
         return 1;
     }
     if (node->l) {
         if (dict_sanity_check_node(node->l, dss)) return 1;
         if (irccasecmp(node->l->key, node->key) >= 0) {
-            snprintf(dss->error, sizeof(dss->error), "Node %p's left child's key '%s' >= its key '%s'", node, node->l->key, node->key);
+            snprintf(dss->error, sizeof(dss->error), "Node %p's left child's key '%s' >= its key '%s'", (void*)node, node->l->key, node->key);
             return 1;
         }
     }
     if (node->r) {
         if (dict_sanity_check_node(node->r, dss)) return 1;
         if (irccasecmp(node->key, node->r->key) >= 0) {
-            snprintf(dss->error, sizeof(dss->error), "Node %p's right child's key '%s' <= its key '%s'", node, node->r->key, node->key);
+            snprintf(dss->error, sizeof(dss->error), "Node %p's right child's key '%s' <= its key '%s'", (void*)node, node->r->key, node->key);
             return 1;
         }
     }
@@ -309,6 +335,7 @@ dict_sanity_check(dict_t dict)
     dss.node_count = 0;
     dss.bad_node = 0;
     dss.error[0] = 0;
+    verify(dict);
     if (dict->root && dict_sanity_check_node(dict->root, &dss)) {
         return strdup(dss.error);
     } else if (dss.node_count != dict->count) {