|
|
@@ -1,16 +1,33 @@
|
|
|
#include "toolbox/hashtable.h"
|
|
|
+
|
|
|
+#include <stddef.h>
|
|
|
+#include <stdint.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <string.h>
|
|
|
+
|
|
|
#include "toolbox/hash.h"
|
|
|
#include "toolbox/cstring.h"
|
|
|
#include "toolbox/log.h"
|
|
|
-#include "toolbox/return_codes.h"
|
|
|
+#include "toolbox/errno.h"
|
|
|
#include "toolbox/void_pointer.h"
|
|
|
#include "toolbox/vptr.h"
|
|
|
|
|
|
-#include <stdbool.h>
|
|
|
-#include <stddef.h>
|
|
|
-#include <stdint.h>
|
|
|
-#include <stdlib.h>
|
|
|
-#include <string.h>
|
|
|
+#define true ((unsigned char) 1L)
|
|
|
+#define false ((unsigned char) 0L)
|
|
|
+
|
|
|
+#define TEST_FOR_NULL(POINTER) \
|
|
|
+ if ( POINTER == NULL ) { \
|
|
|
+ LOG_ERROR("Null Pointer Not Expected"); \
|
|
|
+ toolbox_errno = RET_EVN; \
|
|
|
+ return toolbox_errno; \
|
|
|
+ }
|
|
|
+
|
|
|
+#define TEST_FOR_NULL_SR(POINTER, RET) \
|
|
|
+ if ( POINTER == NULL ) { \
|
|
|
+ LOG_ERROR("Null Pointer Not Expected"); \
|
|
|
+ toolbox_errno = RET_EVN; \
|
|
|
+ return RET; \
|
|
|
+ }
|
|
|
|
|
|
struct hashtable_item {
|
|
|
struct {
|
|
|
@@ -35,29 +52,12 @@ struct hashtable {
|
|
|
struct hashtable_item data[HASHTABLE_SIZE];
|
|
|
};
|
|
|
|
|
|
-#define TEST_FOR_NULL(POINTER) \
|
|
|
- if ( POINTER == NULL ) \
|
|
|
- { \
|
|
|
- LOG_ERROR("Null Pointer Not Expected"); \
|
|
|
- toolbox_errno = RET_ERR_VALUE_NULL; \
|
|
|
- return RET_ERR_VALUE_NULL; \
|
|
|
- }
|
|
|
-
|
|
|
-#define TEST_FOR_NULL_SR(POINTER, RETURN) \
|
|
|
- if ( POINTER == NULL ) \
|
|
|
- { \
|
|
|
- LOG_ERROR("Null Pointer Not Expected"); \
|
|
|
- toolbox_errno = RET_ERR_VALUE_NULL; \
|
|
|
- return RETURN; \
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
struct hashtable *
|
|
|
hashtable_create(void) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
struct hashtable *self = calloc(1, sizeof(struct hashtable));
|
|
|
if ( self == NULL ) {
|
|
|
- toolbox_errno = RET_ERR_FAILED_MALLOC;
|
|
|
+ toolbox_errno = RET_EFM;
|
|
|
}
|
|
|
return self;
|
|
|
}
|
|
|
@@ -67,19 +67,23 @@ hashtable_destroy(struct hashtable **self) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL(self);
|
|
|
TEST_FOR_NULL(*self);
|
|
|
- for ( size_t i = 0; i < (*self)->used_keys.size; ++i ) {
|
|
|
- if ( (*self)->data[(*self)->used_keys.data[i]].item.data != NULL ) {
|
|
|
- free((*self)->data[(*self)->used_keys.data[i]].item.data);
|
|
|
- }
|
|
|
+
|
|
|
+ struct hashtable *ht = (*self);
|
|
|
+
|
|
|
+ for ( size_t i = 0; i < ht->used_keys.size; ++i ) {
|
|
|
+ if ( ht->data[ht->used_keys.data[i]].item.data == NULL )
|
|
|
+ continue;
|
|
|
+
|
|
|
+ free(ht->data[ht->used_keys.data[i]].item.data);
|
|
|
}
|
|
|
free(*self);
|
|
|
*self = NULL;
|
|
|
return RET_OK;
|
|
|
}
|
|
|
|
|
|
-bool
|
|
|
+_Bool
|
|
|
hashtable_contain_item(const struct hashtable *self
|
|
|
- , const void* p_item, const size_t p_item_size) {
|
|
|
+ , const void* p_item, const size_t p_item_size) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL(self);
|
|
|
TEST_FOR_NULL(p_item);
|
|
|
@@ -87,13 +91,13 @@ hashtable_contain_item(const struct hashtable *self
|
|
|
for ( size_t i = 0; i < self->used_keys.size; ++i ) {
|
|
|
p_tmp = &self->data[self->used_keys.data[i]];
|
|
|
if ( void_pointer_equal(p_tmp->item.data, p_tmp->item.size
|
|
|
- , p_item, p_item_size) ) {
|
|
|
+ , p_item, p_item_size) ) {
|
|
|
return true;
|
|
|
}
|
|
|
while ( p_tmp->p_next != NULL ) {
|
|
|
p_tmp = p_tmp->p_next;
|
|
|
if ( void_pointer_equal(p_tmp->item.data, p_tmp->item.size
|
|
|
- , p_item, p_item_size) ) {
|
|
|
+ , p_item, p_item_size) ) {
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
@@ -101,9 +105,9 @@ hashtable_contain_item(const struct hashtable *self
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-bool
|
|
|
+_Bool
|
|
|
hashtable_contain_key(const struct hashtable *self
|
|
|
- , const char *r_p_key) {
|
|
|
+ , const char *r_p_key) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL(self);
|
|
|
TEST_FOR_NULL(r_p_key);
|
|
|
@@ -116,9 +120,9 @@ hashtable_contain_key(const struct hashtable *self
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-bool
|
|
|
+_Bool
|
|
|
hashtable_contain_key_hash(const struct hashtable *self
|
|
|
- , const size_t p_key_hash) {
|
|
|
+ , const size_t p_key_hash) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL(self);
|
|
|
if ( self->data[p_key_hash].key.hash == p_key_hash ) {
|
|
|
@@ -129,7 +133,7 @@ hashtable_contain_key_hash(const struct hashtable *self
|
|
|
|
|
|
const void *
|
|
|
hashtable_get(const struct hashtable *self
|
|
|
- , const char *r_p_key) {
|
|
|
+ , const char *r_p_key) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL_SR(self, NULL);
|
|
|
TEST_FOR_NULL_SR(r_p_key, NULL);
|
|
|
@@ -145,34 +149,37 @@ hashtable_get(const struct hashtable *self
|
|
|
return p_tmp->item.data;
|
|
|
}
|
|
|
}
|
|
|
- toolbox_errno = RET_ERR_ITEM_DOES_NOT_EXIST;
|
|
|
+ toolbox_errno = RET_EIDNE;
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
const void *
|
|
|
hashtable_get_or_default(const struct hashtable *self
|
|
|
- , const char *r_p_key
|
|
|
- , const void *p_default_item) {
|
|
|
+ , const char *r_p_key
|
|
|
+ , const void *p_default_item) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL_SR(self, NULL);
|
|
|
TEST_FOR_NULL_SR(r_p_key, NULL);
|
|
|
TEST_FOR_NULL_SR(p_default_item, NULL);
|
|
|
+
|
|
|
const uint64_t true_key_hash = hash_cstr(r_p_key);
|
|
|
const struct hashtable_item *p_tmp
|
|
|
= &self->data[true_key_hash % HASHTABLE_SIZE];
|
|
|
- if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
+
|
|
|
+ if ( p_tmp->key.true_hash == true_key_hash )
|
|
|
return p_tmp->item.data;
|
|
|
- }
|
|
|
+
|
|
|
while ( p_tmp->p_next != NULL ) {
|
|
|
p_tmp = p_tmp->p_next;
|
|
|
- if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
+
|
|
|
+ if ( p_tmp->key.true_hash == true_key_hash )
|
|
|
return p_tmp->item.data;
|
|
|
- }
|
|
|
}
|
|
|
+
|
|
|
return p_default_item;
|
|
|
}
|
|
|
|
|
|
-bool
|
|
|
+_Bool
|
|
|
hashtable_is_empty(const struct hashtable *self) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL(self);
|
|
|
@@ -181,21 +188,23 @@ hashtable_is_empty(const struct hashtable *self) {
|
|
|
|
|
|
static RET_TYPE
|
|
|
m_hashtable_put_helper(struct hashtable *self, struct hashtable_item *p_tmp
|
|
|
- , uint64_t true_key_hash, size_t key_hash
|
|
|
- , const void *r_p_item, size_t p_item_size) {
|
|
|
+ , uint64_t true_key_hash, size_t key_hash
|
|
|
+ , const void *r_p_item, size_t p_item_size) {
|
|
|
p_tmp->key.true_hash = true_key_hash;
|
|
|
p_tmp->key.hash = key_hash;
|
|
|
p_tmp->p_next = NULL;
|
|
|
p_tmp->item.size = p_item_size;
|
|
|
p_tmp->item.data = malloc(p_tmp->item.size);
|
|
|
+
|
|
|
if ( p_tmp->item.data == NULL ) {
|
|
|
self->used_keys.data[--self->used_keys.size] = 0;
|
|
|
p_tmp->key.true_hash = 0;
|
|
|
p_tmp->key.hash = 0;
|
|
|
p_tmp->item.size = 0;
|
|
|
- toolbox_errno = RET_ERR_FAILED_MALLOC;
|
|
|
- return RET_ERR_FAILED_MALLOC;
|
|
|
+ toolbox_errno = RET_EFM;
|
|
|
+ return RET_EFM;
|
|
|
}
|
|
|
+
|
|
|
memcpy(p_tmp->item.data, r_p_item, p_tmp->item.size);
|
|
|
return RET_OK;
|
|
|
}
|
|
|
@@ -211,24 +220,29 @@ hashtable_put(struct hashtable *self
|
|
|
const uint64_t true_key_hash = hash_cstr(r_p_key);
|
|
|
const size_t key_hash = true_key_hash % HASHTABLE_SIZE;
|
|
|
struct hashtable_item *p_tmp = &self->data[key_hash];
|
|
|
+
|
|
|
if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
- toolbox_errno = RET_ERR_ITEM_ALREADY_EXIST;
|
|
|
- return RET_ERR_ITEM_ALREADY_EXIST;
|
|
|
+ toolbox_errno = RET_EIAE;
|
|
|
+ return RET_EIAE;
|
|
|
}
|
|
|
+
|
|
|
if ( p_tmp->key.true_hash == 0 ) {
|
|
|
self->used_keys.data[self->used_keys.size++] = key_hash;
|
|
|
return m_hashtable_put_helper(self, p_tmp
|
|
|
- , true_key_hash, key_hash
|
|
|
- , r_p_item, p_item_size);
|
|
|
- } else {
|
|
|
- do {
|
|
|
- p_tmp = p_tmp->p_next;
|
|
|
- } while ( p_tmp != NULL );
|
|
|
- p_tmp = malloc(sizeof(struct hashtable_item));
|
|
|
- return m_hashtable_put_helper(self, p_tmp
|
|
|
- , true_key_hash, key_hash
|
|
|
- , r_p_item, p_item_size);
|
|
|
+ , true_key_hash, key_hash
|
|
|
+ , r_p_item, p_item_size);
|
|
|
}
|
|
|
+
|
|
|
+ do {
|
|
|
+ p_tmp = p_tmp->p_next;
|
|
|
+ } while ( p_tmp != NULL );
|
|
|
+
|
|
|
+ p_tmp = malloc(sizeof(struct hashtable_item));
|
|
|
+
|
|
|
+ return m_hashtable_put_helper(self, p_tmp
|
|
|
+ , true_key_hash, key_hash
|
|
|
+ , r_p_item, p_item_size);
|
|
|
+
|
|
|
return RET_OK;
|
|
|
}
|
|
|
|
|
|
@@ -245,14 +259,14 @@ m_remove_index_carray(size_t *restrict r_p_carray, size_t *restrict r_p_size
|
|
|
__attribute__((__nonnull__))
|
|
|
inline static void
|
|
|
m_remove_item(struct hashtable *self
|
|
|
- , const size_t p_key_hash, const uint64_t p_true_key_hash) {
|
|
|
+ , const size_t p_key_hash, const uint64_t p_true_key_hash) {
|
|
|
struct hashtable_item *p_tmp = &self->data[p_key_hash];
|
|
|
if ( p_tmp->key.true_hash == p_true_key_hash ) {
|
|
|
if ( p_tmp->p_next == NULL ) {
|
|
|
for ( size_t i = 0; i < self->used_keys.size; ++i ) {
|
|
|
if ( self->used_keys.data[i] == p_key_hash ) {
|
|
|
m_remove_index_carray(self->used_keys.data
|
|
|
- , &self->used_keys.size, i);
|
|
|
+ , &self->used_keys.size, i);
|
|
|
}
|
|
|
}
|
|
|
p_tmp->key.hash = 0;
|
|
|
@@ -280,123 +294,147 @@ hashtable_remove(struct hashtable *self, const char *r_p_key) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL_SR(self, NULL);
|
|
|
TEST_FOR_NULL_SR(r_p_key, NULL);
|
|
|
+
|
|
|
const uint64_t true_key_hash = hash_cstr(r_p_key);
|
|
|
const size_t key_hash = true_key_hash % HASHTABLE_SIZE;
|
|
|
const struct hashtable_item *p_tmp = &self->data[key_hash];
|
|
|
+
|
|
|
void *ret = NULL;
|
|
|
if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
ret = malloc(p_tmp->item.size);
|
|
|
memcpy(ret, p_tmp->item.data, p_tmp->item.size);
|
|
|
m_remove_item(self, key_hash, true_key_hash);
|
|
|
- } else {
|
|
|
- while ( p_tmp->p_next != NULL ) {
|
|
|
- if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
- ret = malloc(p_tmp->item.size);
|
|
|
- memcpy(ret, p_tmp->item.data, p_tmp->item.size);
|
|
|
- m_remove_item(self, key_hash, true_key_hash);
|
|
|
- }
|
|
|
+ goto exit;
|
|
|
+ }
|
|
|
+
|
|
|
+ while ( p_tmp->p_next != NULL ) {
|
|
|
+ if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
+ ret = malloc(p_tmp->item.size);
|
|
|
+ memcpy(ret, p_tmp->item.data, p_tmp->item.size);
|
|
|
+ m_remove_item(self, key_hash, true_key_hash);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+exit:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-bool
|
|
|
+_Bool
|
|
|
hashtable_remove_if_equal(struct hashtable *self
|
|
|
- , const char *r_p_key
|
|
|
- , const void *r_p_item, const size_t p_item_size) {
|
|
|
+ , const char *r_p_key
|
|
|
+ , const void *r_p_item, const size_t p_item_size) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL(self);
|
|
|
TEST_FOR_NULL(r_p_key);
|
|
|
TEST_FOR_NULL(r_p_item);
|
|
|
+
|
|
|
const uint64_t true_key_hash = hash_cstr(r_p_key);
|
|
|
const size_t key_hash = true_key_hash % HASHTABLE_SIZE;
|
|
|
const struct hashtable_item *p_tmp = &self->data[key_hash];
|
|
|
+
|
|
|
if ( p_tmp->key.true_hash == true_key_hash
|
|
|
&& void_pointer_equal(p_tmp->item.data, p_tmp->item.size
|
|
|
- , r_p_item, p_item_size) ) {
|
|
|
+ , r_p_item, p_item_size) ) {
|
|
|
m_remove_item(self, key_hash, true_key_hash);
|
|
|
return true;
|
|
|
- } else {
|
|
|
- while ( p_tmp->p_next != NULL ) {
|
|
|
- if ( p_tmp->key.true_hash == true_key_hash
|
|
|
- && void_pointer_equal(p_tmp->item.data, p_tmp->item.size
|
|
|
- , r_p_item, p_item_size) ) {
|
|
|
- m_remove_item(self, key_hash, true_key_hash);
|
|
|
- return true;
|
|
|
- }
|
|
|
+ }
|
|
|
+
|
|
|
+ while ( p_tmp->p_next != NULL ) {
|
|
|
+ if ( p_tmp->key.true_hash == true_key_hash
|
|
|
+ && void_pointer_equal(p_tmp->item.data, p_tmp->item.size
|
|
|
+ , r_p_item, p_item_size) ) {
|
|
|
+ m_remove_item(self, key_hash, true_key_hash);
|
|
|
+ return true;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
const void *
|
|
|
hashtable_replace(struct hashtable *self
|
|
|
- , const char *r_p_key
|
|
|
- , const void *r_p_item, const size_t p_item_size) {
|
|
|
+ , const char *r_p_key
|
|
|
+ , const void *r_p_item, const size_t p_item_size) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
+
|
|
|
TEST_FOR_NULL_SR(self, NULL);
|
|
|
TEST_FOR_NULL_SR(r_p_key, NULL);
|
|
|
TEST_FOR_NULL_SR(r_p_item, NULL);
|
|
|
+
|
|
|
const uint64_t true_key_hash = hash_cstr(r_p_key);
|
|
|
struct hashtable_item *p_tmp
|
|
|
= &self->data[true_key_hash % HASHTABLE_SIZE];
|
|
|
void *ret = NULL;
|
|
|
+
|
|
|
if ( p_tmp->key.true_hash != true_key_hash ) {
|
|
|
while ( p_tmp->p_next != NULL ) {
|
|
|
p_tmp = p_tmp->p_next;
|
|
|
- if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
+
|
|
|
+ if ( p_tmp->key.true_hash == true_key_hash )
|
|
|
break;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
ret = malloc(p_tmp->item.size);
|
|
|
memcpy(ret, p_tmp->item.data, p_tmp->item.size);
|
|
|
+
|
|
|
if ( p_tmp->item.size == p_item_size ) {
|
|
|
memcpy(p_tmp->item.data, r_p_item, p_tmp->item.size);
|
|
|
- } else {
|
|
|
- free(p_tmp->item.data);
|
|
|
- p_tmp->item.size = p_item_size;
|
|
|
- p_tmp->item.data = malloc(p_tmp->item.size);
|
|
|
- memcpy(p_tmp->item.data, r_p_item, p_tmp->item.size);
|
|
|
+ goto exit;
|
|
|
}
|
|
|
+
|
|
|
+ free(p_tmp->item.data);
|
|
|
+ p_tmp->item.size = p_item_size;
|
|
|
+ p_tmp->item.data = malloc(p_tmp->item.size);
|
|
|
+ memcpy(p_tmp->item.data, r_p_item, p_tmp->item.size);
|
|
|
+
|
|
|
+exit:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-bool
|
|
|
+_Bool
|
|
|
hashtable_replace_if_equal(struct hashtable *self
|
|
|
- , const char *r_p_key
|
|
|
- , const void *restrict r_p_old_item
|
|
|
- , const size_t p_old_item_size
|
|
|
- , const void *restrict r_p_new_item
|
|
|
- , const size_t p_new_item_size) {
|
|
|
+ , const char *r_p_key
|
|
|
+ , const void *restrict r_p_old_item
|
|
|
+ , const size_t p_old_item_size
|
|
|
+ , const void *restrict r_p_new_item
|
|
|
+ , const size_t p_new_item_size) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
TEST_FOR_NULL(self);
|
|
|
TEST_FOR_NULL(r_p_key);
|
|
|
TEST_FOR_NULL(r_p_old_item);
|
|
|
TEST_FOR_NULL(r_p_new_item);
|
|
|
+
|
|
|
const uint64_t true_key_hash = hash_cstr(r_p_key);
|
|
|
- struct hashtable_item *p_tmp = &self->data[true_key_hash % HASHTABLE_SIZE];
|
|
|
+ struct hashtable_item *p_tmp
|
|
|
+ = &self->data[true_key_hash % HASHTABLE_SIZE];
|
|
|
+
|
|
|
if ( p_tmp->key.true_hash != true_key_hash ) {
|
|
|
while ( p_tmp->p_next != NULL ) {
|
|
|
p_tmp = p_tmp->p_next;
|
|
|
- if ( p_tmp->key.true_hash == true_key_hash ) {
|
|
|
+
|
|
|
+ if ( p_tmp->key.true_hash == true_key_hash )
|
|
|
break;
|
|
|
- }
|
|
|
}
|
|
|
}
|
|
|
- if ( void_pointer_equal(p_tmp->item.data, p_tmp->item.size
|
|
|
- , r_p_old_item, p_old_item_size) ) {
|
|
|
- if ( p_tmp->item.size == p_new_item_size ) {
|
|
|
- memcpy(p_tmp->item.data, r_p_new_item, p_tmp->item.size);
|
|
|
- } else {
|
|
|
- free(p_tmp->item.data);
|
|
|
- p_tmp->item.size = p_new_item_size;
|
|
|
- p_tmp->item.data = malloc(p_tmp->item.size);
|
|
|
- memcpy(p_tmp->item.data, r_p_new_item, p_tmp->item.size);
|
|
|
- }
|
|
|
- return true;
|
|
|
+
|
|
|
+ if ( ! void_pointer_equal(p_tmp->item.data, p_tmp->item.size
|
|
|
+ , r_p_old_item, p_old_item_size) ) {
|
|
|
+ return false;
|
|
|
}
|
|
|
- return false;
|
|
|
+
|
|
|
+ if ( p_tmp->item.size == p_new_item_size ) {
|
|
|
+ memcpy(p_tmp->item.data, r_p_new_item, p_tmp->item.size);
|
|
|
+ goto exit_true;
|
|
|
+ }
|
|
|
+
|
|
|
+ free(p_tmp->item.data);
|
|
|
+ p_tmp->item.size = p_new_item_size;
|
|
|
+ p_tmp->item.data = malloc(p_tmp->item.size);
|
|
|
+ memcpy(p_tmp->item.data, r_p_new_item, p_tmp->item.size);
|
|
|
+
|
|
|
+exit_true:
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
size_t
|
|
|
@@ -408,7 +446,7 @@ hashtable_used_size(const struct hashtable *self) {
|
|
|
|
|
|
RET_TYPE
|
|
|
hashtable_for_each(struct hashtable *self
|
|
|
- , void (*for_each)(void *item, size_t *item_size)) {
|
|
|
+ , void (*for_each)(void *item, size_t *item_size)) {
|
|
|
toolbox_errno = RET_OK;
|
|
|
for ( size_t i = 0; i < self->used_keys.size; ++i ) {
|
|
|
struct hashtable_item *tmp_it
|
|
|
@@ -424,4 +462,8 @@ hashtable_for_each(struct hashtable *self
|
|
|
return RET_OK;
|
|
|
}
|
|
|
|
|
|
+#undef TEST_FOR_NULL_SR
|
|
|
#undef TEST_FOR_NULL
|
|
|
+
|
|
|
+#undef false
|
|
|
+#undef true
|