Feature #756 ยป 0024-genhash.c-Replace-NULLs-with-nullptrs.patch
| utility/genhash.c | ||
|---|---|---|
|
****************************************************************************/
|
||
|
char *genhash_str_copy_func(const char *vkey)
|
||
|
{
|
||
|
return fc_strdup(NULL != vkey ? vkey : "");
|
||
|
return fc_strdup(vkey != nullptr ? vkey : "");
|
||
|
}
|
||
|
/************************************************************************//**
|
||
| ... | ... | |
|
void genhash_str_free_func(char *vkey)
|
||
|
{
|
||
|
#ifdef FREECIV_DEBUG
|
||
|
fc_assert_ret(NULL != vkey);
|
||
|
fc_assert_ret(vkey != nullptr);
|
||
|
#endif
|
||
|
free(vkey);
|
||
|
}
|
||
| ... | ... | |
|
size_t nentries)
|
||
|
{
|
||
|
return genhash_new_nbuckets(key_val_func, key_comp_func,
|
||
|
NULL, NULL, NULL, NULL,
|
||
|
nullptr, nullptr, nullptr, nullptr,
|
||
|
genhash_calc_num_buckets(nentries));
|
||
|
}
|
||
| ... | ... | |
|
genhash_comp_fn_t key_comp_func)
|
||
|
{
|
||
|
return genhash_new_nbuckets(key_val_func, key_comp_func,
|
||
|
NULL, NULL, NULL, NULL, MIN_BUCKETS);
|
||
|
nullptr, nullptr, nullptr, nullptr, MIN_BUCKETS);
|
||
|
}
|
||
|
/************************************************************************//**
|
||
| ... | ... | |
|
****************************************************************************/
|
||
|
void genhash_destroy(struct genhash *pgenhash)
|
||
|
{
|
||
|
fc_assert_ret(NULL != pgenhash);
|
||
|
fc_assert_ret(pgenhash != nullptr);
|
||
|
pgenhash->no_shrink = TRUE;
|
||
|
genhash_clear(pgenhash);
|
||
|
free(pgenhash->buckets);
|
||
| ... | ... | |
|
bucket = pgenhash->buckets;
|
||
|
end = bucket + pgenhash->num_buckets;
|
||
|
for (; bucket < end; bucket++) {
|
||
|
for (iter = *bucket; NULL != iter; iter = next) {
|
||
|
for (iter = *bucket; iter != nullptr; iter = next) {
|
||
|
slot = new_buckets + (iter->hash_val % new_nbuckets);
|
||
|
next = iter->next;
|
||
|
iter->next = *slot;
|
||
| ... | ... | |
|
static inline genhash_val_t genhash_val_calc(const struct genhash *pgenhash,
|
||
|
const void *key)
|
||
|
{
|
||
|
if (NULL != pgenhash->key_val_func) {
|
||
|
if (pgenhash->key_val_func != nullptr) {
|
||
|
return pgenhash->key_val_func(key);
|
||
|
} else {
|
||
|
return ((intptr_t) key);
|
||
| ... | ... | |
|
genhash_comp_fn_t key_comp_func = pgenhash->key_comp_func;
|
||
|
slot = pgenhash->buckets + (hash_val % pgenhash->num_buckets);
|
||
|
if (NULL != key_comp_func) {
|
||
|
for (; NULL != *slot; slot = &(*slot)->next) {
|
||
|
if (key_comp_func != nullptr) {
|
||
|
for (; *slot != nullptr; slot = &(*slot)->next) {
|
||
|
if (hash_val == (*slot)->hash_val
|
||
|
&& key_comp_func((*slot)->key, key)) {
|
||
|
return slot;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
for (; NULL != *slot; slot = &(*slot)->next) {
|
||
|
for (; *slot != nullptr; slot = &(*slot)->next) {
|
||
|
if (key == (*slot)->key) {
|
||
|
return slot;
|
||
|
}
|
||
| ... | ... | |
|
****************************************************************************/
|
||
|
static inline void genhash_default_get(void **pkey, void **data)
|
||
|
{
|
||
|
if (NULL != pkey) {
|
||
|
*pkey = NULL;
|
||
|
if (pkey != nullptr) {
|
||
|
*pkey = nullptr;
|
||
|
}
|
||
|
if (NULL != data) {
|
||
|
*data = NULL;
|
||
|
if (data != nullptr) {
|
||
|
*data = nullptr;
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
const struct genhash_entry *entry = *slot;
|
||
|
if (NULL != pkey) {
|
||
|
if (pkey != nullptr) {
|
||
|
*pkey = entry->key;
|
||
|
}
|
||
|
if (NULL != data) {
|
||
|
if (data != nullptr) {
|
||
|
*data = entry->data;
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
struct genhash_entry *entry = fc_malloc(sizeof(*entry));
|
||
|
entry->key = (NULL != pgenhash->key_copy_func
|
||
|
entry->key = (pgenhash->key_copy_func != nullptr
|
||
|
? pgenhash->key_copy_func(key) : (void *) key);
|
||
|
entry->data = (NULL != pgenhash->data_copy_func
|
||
|
entry->data = (pgenhash->data_copy_func != nullptr
|
||
|
? pgenhash->data_copy_func(data) : (void *) data);
|
||
|
entry->hash_val = hash_val;
|
||
|
entry->next = *slot;
|
||
| ... | ... | |
|
{
|
||
|
struct genhash_entry *entry = *slot;
|
||
|
if (NULL != pgenhash->key_free_func) {
|
||
|
if (pgenhash->key_free_func != nullptr) {
|
||
|
pgenhash->key_free_func(entry->key);
|
||
|
}
|
||
|
if (NULL != pgenhash->data_free_func) {
|
||
|
if (pgenhash->data_free_func != nullptr) {
|
||
|
pgenhash->data_free_func(entry->data);
|
||
|
}
|
||
|
*slot = entry->next;
|
||
|
free(entry);
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
struct genhash_entry *entry = *slot;
|
||
|
if (NULL != pgenhash->key_free_func) {
|
||
|
if (pgenhash->key_free_func != nullptr) {
|
||
|
pgenhash->key_free_func(entry->key);
|
||
|
}
|
||
|
if (NULL != pgenhash->data_free_func) {
|
||
|
if (pgenhash->data_free_func != nullptr) {
|
||
|
pgenhash->data_free_func(entry->data);
|
||
|
}
|
||
|
entry->key = (NULL != pgenhash->key_copy_func
|
||
|
entry->key = (pgenhash->key_copy_func != nullptr
|
||
|
? pgenhash->key_copy_func(key) : (void *) key);
|
||
|
entry->data = (NULL != pgenhash->data_copy_func
|
||
|
entry->data = (pgenhash->data_copy_func != nullptr
|
||
|
? pgenhash->data_copy_func(data) : (void *) data);
|
||
|
}
|
||
| ... | ... | |
|
{
|
||
|
bool old;
|
||
|
fc_assert_ret_val(NULL != pgenhash, FALSE);
|
||
|
fc_assert_ret_val(pgenhash != nullptr, FALSE);
|
||
|
old = pgenhash->no_shrink;
|
||
|
pgenhash->no_shrink = no_shrink;
|
||
|
return old;
|
||
|
}
|
||
| ... | ... | |
|
****************************************************************************/
|
||
|
size_t genhash_size(const struct genhash *pgenhash)
|
||
|
{
|
||
|
fc_assert_ret_val(NULL != pgenhash, 0);
|
||
|
fc_assert_ret_val(pgenhash != nullptr, 0);
|
||
|
return pgenhash->num_entries;
|
||
|
}
|
||
| ... | ... | |
|
****************************************************************************/
|
||
|
size_t genhash_capacity(const struct genhash *pgenhash)
|
||
|
{
|
||
|
fc_assert_ret_val(NULL != pgenhash, 0);
|
||
|
fc_assert_ret_val(pgenhash != nullptr, 0);
|
||
|
return pgenhash->num_buckets;
|
||
|
}
|
||
| ... | ... | |
|
const struct genhash_entry *src_iter;
|
||
|
struct genhash_entry **dest_slot, **dest_bucket;
|
||
|
fc_assert_ret_val(NULL != pgenhash, NULL);
|
||
|
fc_assert_ret_val(pgenhash != nullptr, nullptr);
|
||
|
new_genhash = fc_malloc(sizeof(*new_genhash));
|
||
| ... | ... | |
|
for (; src_bucket < end; src_bucket++, dest_bucket++) {
|
||
|
dest_slot = dest_bucket;
|
||
|
for (src_iter = *src_bucket; NULL != src_iter;
|
||
|
for (src_iter = *src_bucket; src_iter != nullptr;
|
||
|
src_iter = src_iter->next) {
|
||
|
genhash_slot_create(new_genhash, dest_slot, src_iter->key,
|
||
|
src_iter->data, src_iter->hash_val);
|
||
| ... | ... | |
|
{
|
||
|
struct genhash_entry **bucket, **end;
|
||
|
fc_assert_ret(NULL != pgenhash);
|
||
|
fc_assert_ret(pgenhash != nullptr);
|
||
|
bucket = pgenhash->buckets;
|
||
|
end = bucket + pgenhash->num_buckets;
|
||
|
for (; bucket < end; bucket++) {
|
||
|
while (NULL != *bucket) {
|
||
|
while (*bucket != nullptr) {
|
||
|
genhash_slot_free(pgenhash, bucket);
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
struct genhash_entry **slot;
|
||
|
genhash_val_t hash_val;
|
||
|
fc_assert_ret_val(NULL != pgenhash, FALSE);
|
||
|
fc_assert_ret_val(pgenhash != nullptr, FALSE);
|
||
|
hash_val = genhash_val_calc(pgenhash, key);
|
||
|
slot = genhash_slot_lookup(pgenhash, key, hash_val);
|
||
|
if (NULL != *slot) {
|
||
|
if (*slot != nullptr) {
|
||
|
return FALSE;
|
||
|
} else {
|
||
|
if (genhash_maybe_expand(pgenhash)) {
|
||
| ... | ... | |
|
bool genhash_replace(struct genhash *pgenhash, const void *key,
|
||
|
const void *data)
|
||
|
{
|
||
|
return genhash_replace_full(pgenhash, key, data, NULL, NULL);
|
||
|
return genhash_replace_full(pgenhash, key, data, nullptr, nullptr);
|
||
|
}
|
||
|
/************************************************************************//**
|
||
| ... | ... | |
|
insertion.
|
||
|
Returns in 'old_pkey' and 'old_pdata' the old content of the bucket if
|
||
|
they are not NULL. NB: It can returns freed pointers if free functions
|
||
|
they are not nullptr. NB: It can returns freed pointers if free functions
|
||
|
were supplied to the genhash table.
|
||
|
****************************************************************************/
|
||
|
bool genhash_replace_full(struct genhash *pgenhash, const void *key,
|
||
| ... | ... | |
|
struct genhash_entry **slot;
|
||
|
genhash_val_t hash_val;
|
||
|
fc_assert_action(NULL != pgenhash,
|
||
|
fc_assert_action(pgenhash != nullptr,
|
||
|
genhash_default_get(old_pkey, old_pdata); return FALSE);
|
||
|
hash_val = genhash_val_calc(pgenhash, key);
|
||
|
slot = genhash_slot_lookup(pgenhash, key, hash_val);
|
||
|
if (NULL != *slot) {
|
||
|
if (*slot != nullptr) {
|
||
|
/* Replace. */
|
||
|
genhash_slot_get(slot, old_pkey, old_pdata);
|
||
|
genhash_slot_set(pgenhash, slot, key, data);
|
||
| ... | ... | |
|
}
|
||
|
/************************************************************************//**
|
||
|
Lookup data. Return TRUE on success, then pdata - if not NULL will be set
|
||
|
Lookup data. Return TRUE on success, then pdata - if not nullptr will be set
|
||
|
to the data value.
|
||
|
****************************************************************************/
|
||
|
bool genhash_lookup(const struct genhash *pgenhash, const void *key,
|
||
| ... | ... | |
|
{
|
||
|
struct genhash_entry **slot;
|
||
|
fc_assert_action(NULL != pgenhash,
|
||
|
genhash_default_get(NULL, pdata); return FALSE);
|
||
|
fc_assert_action(pgenhash != nullptr,
|
||
|
genhash_default_get(nullptr, pdata); return FALSE);
|
||
|
slot = genhash_slot_lookup(pgenhash, key, genhash_val_calc(pgenhash, key));
|
||
|
if (NULL != *slot) {
|
||
|
genhash_slot_get(slot, NULL, pdata);
|
||
|
if (*slot != nullptr) {
|
||
|
genhash_slot_get(slot, nullptr, pdata);
|
||
|
return TRUE;
|
||
|
} else {
|
||
|
genhash_default_get(NULL, pdata);
|
||
|
genhash_default_get(nullptr, pdata);
|
||
|
return FALSE;
|
||
|
}
|
||
|
}
|
||
| ... | ... | |
|
****************************************************************************/
|
||
|
bool genhash_remove(struct genhash *pgenhash, const void *key)
|
||
|
{
|
||
|
return genhash_remove_full(pgenhash, key, NULL, NULL);
|
||
|
return genhash_remove_full(pgenhash, key, nullptr, nullptr);
|
||
|
}
|
||
|
/************************************************************************//**
|
||
|
Delete an entry from the genhash table. Returns TRUE on success.
|
||
|
Returns in 'deleted_pkey' and 'deleted_pdata' the old contents of the
|
||
|
deleted entry if not NULL. NB: It can returns freed pointers if free
|
||
|
deleted entry if not nullptr. NB: It can returns freed pointers if free
|
||
|
functions were supplied to the genhash table.
|
||
|
****************************************************************************/
|
||
|
bool genhash_remove_full(struct genhash *pgenhash, const void *key,
|
||
| ... | ... | |
|
{
|
||
|
struct genhash_entry **slot;
|
||
|
fc_assert_action(NULL != pgenhash,
|
||
|
fc_assert_action(pgenhash != nullptr,
|
||
|
genhash_default_get(deleted_pkey, deleted_pdata);
|
||
|
return FALSE);
|
||
|
slot = genhash_slot_lookup(pgenhash, key, genhash_val_calc(pgenhash, key));
|
||
|
if (NULL != *slot) {
|
||
|
if (*slot != nullptr) {
|
||
|
genhash_slot_get(slot, deleted_pkey, deleted_pdata);
|
||
|
genhash_slot_free(pgenhash, slot);
|
||
|
genhash_maybe_shrink(pgenhash);
|
||
| ... | ... | |
|
bool genhashes_are_equal(const struct genhash *pgenhash1,
|
||
|
const struct genhash *pgenhash2)
|
||
|
{
|
||
|
return genhashes_are_equal_full(pgenhash1, pgenhash2, NULL);
|
||
|
return genhashes_are_equal_full(pgenhash1, pgenhash2, nullptr);
|
||
|
}
|
||
|
/************************************************************************//**
|
||
| ... | ... | |
|
/* Check pointers. */
|
||
|
if (pgenhash1 == pgenhash2) {
|
||
|
return TRUE;
|
||
|
} else if (NULL == pgenhash1 || NULL == pgenhash2) {
|
||
|
} else if (pgenhash1 == nullptr || pgenhash2 == nullptr) {
|
||
|
return FALSE;
|
||
|
}
|
||
| ... | ... | |
|
bucket1 = pgenhash1->buckets;
|
||
|
max1 = bucket1 + pgenhash1->num_buckets;
|
||
|
for (; bucket1 < max1; bucket1++) {
|
||
|
for (iter1 = *bucket1; NULL != iter1; iter1 = iter1->next) {
|
||
|
for (iter1 = *bucket1; iter1 != nullptr; iter1 = iter1->next) {
|
||
|
slot2 = genhash_slot_lookup(pgenhash2, iter1->key, iter1->hash_val);
|
||
|
if (NULL == *slot2
|
||
|
if (*slot2 == nullptr
|
||
|
|| (iter1->data != (*slot2)->data
|
||
|
&& (NULL == data_comp_func
|
||
|
&& (data_comp_func == nullptr
|
||
|
|| !data_comp_func(iter1->data, (*slot2)->data)))) {
|
||
|
return FALSE;
|
||
|
}
|
||
| ... | ... | |
|
struct genhash_iter *iter = GENHASH_ITER(genhash_iter);
|
||
|
iter->iterator = iter->iterator->next;
|
||
|
if (NULL != iter->iterator) {
|
||
|
if (iter->iterator != nullptr) {
|
||
|
return;
|
||
|
}
|
||
|
for (iter->bucket++; iter->bucket < iter->end; iter->bucket++) {
|
||
|
if (NULL != *iter->bucket) {
|
||
|
if (*iter->bucket != nullptr) {
|
||
|
iter->iterator = *iter->bucket;
|
||
|
return;
|
||
|
}
|
||
| ... | ... | |
|
const struct genhash *pgenhash,
|
||
|
void * (*get) (const struct iterator *))
|
||
|
{
|
||
|
if (NULL == pgenhash) {
|
||
|
if (pgenhash == nullptr) {
|
||
|
return invalid_iter_init(ITERATOR(iter));
|
||
|
}
|
||
| ... | ... | |
|
/* Seek to the first used bucket. */
|
||
|
for (; iter->bucket < iter->end; iter->bucket++) {
|
||
|
if (NULL != *iter->bucket) {
|
||
|
if (*iter->bucket != nullptr) {
|
||
|
iter->iterator = *iter->bucket;
|
||
|
break;
|
||
|
}
|
||