Fix undefined function pointer casts in LHASH.
Bug: chromium:785442 Change-Id: I516e42684b913dc0de778dd9134f1ca108c04dfc Reviewed-on: https://boringssl-review.googlesource.com/c/32120 Commit-Queue: David Benjamin <davidben@google.com> CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org> Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
parent
1eff9482ca
commit
b68b832238
@ -139,15 +139,17 @@ size_t lh_num_items(const _LHASH *lh) { return lh->num_items; }
|
|||||||
// not found, it returns a pointer that points to a NULL pointer. If |out_hash|
|
// not found, it returns a pointer that points to a NULL pointer. If |out_hash|
|
||||||
// is not NULL, then it also puts the hash value of |data| in |*out_hash|.
|
// is not NULL, then it also puts the hash value of |data| in |*out_hash|.
|
||||||
static LHASH_ITEM **get_next_ptr_and_hash(const _LHASH *lh, uint32_t *out_hash,
|
static LHASH_ITEM **get_next_ptr_and_hash(const _LHASH *lh, uint32_t *out_hash,
|
||||||
const void *data) {
|
const void *data,
|
||||||
const uint32_t hash = lh->hash(data);
|
lhash_hash_func_helper call_hash_func,
|
||||||
|
lhash_cmp_func_helper call_cmp_func) {
|
||||||
|
const uint32_t hash = call_hash_func(lh->hash, data);
|
||||||
if (out_hash != NULL) {
|
if (out_hash != NULL) {
|
||||||
*out_hash = hash;
|
*out_hash = hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
LHASH_ITEM **ret = &lh->buckets[hash % lh->num_buckets];
|
LHASH_ITEM **ret = &lh->buckets[hash % lh->num_buckets];
|
||||||
for (LHASH_ITEM *cur = *ret; cur != NULL; cur = *ret) {
|
for (LHASH_ITEM *cur = *ret; cur != NULL; cur = *ret) {
|
||||||
if (lh->comp(cur->data, data) == 0) {
|
if (call_cmp_func(lh->comp, cur->data, data) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ret = &cur->next;
|
ret = &cur->next;
|
||||||
@ -173,8 +175,11 @@ static LHASH_ITEM **get_next_ptr_by_key(const _LHASH *lh, const void *key,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *lh_retrieve(const _LHASH *lh, const void *data) {
|
void *lh_retrieve(const _LHASH *lh, const void *data,
|
||||||
LHASH_ITEM **next_ptr = get_next_ptr_and_hash(lh, NULL, data);
|
lhash_hash_func_helper call_hash_func,
|
||||||
|
lhash_cmp_func_helper call_cmp_func) {
|
||||||
|
LHASH_ITEM **next_ptr =
|
||||||
|
get_next_ptr_and_hash(lh, NULL, data, call_hash_func, call_cmp_func);
|
||||||
return *next_ptr == NULL ? NULL : (*next_ptr)->data;
|
return *next_ptr == NULL ? NULL : (*next_ptr)->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,12 +252,15 @@ static void lh_maybe_resize(_LHASH *lh) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lh_insert(_LHASH *lh, void **old_data, void *data) {
|
int lh_insert(_LHASH *lh, void **old_data, void *data,
|
||||||
|
lhash_hash_func_helper call_hash_func,
|
||||||
|
lhash_cmp_func_helper call_cmp_func) {
|
||||||
uint32_t hash;
|
uint32_t hash;
|
||||||
LHASH_ITEM **next_ptr, *item;
|
LHASH_ITEM **next_ptr, *item;
|
||||||
|
|
||||||
*old_data = NULL;
|
*old_data = NULL;
|
||||||
next_ptr = get_next_ptr_and_hash(lh, &hash, data);
|
next_ptr =
|
||||||
|
get_next_ptr_and_hash(lh, &hash, data, call_hash_func, call_cmp_func);
|
||||||
|
|
||||||
|
|
||||||
if (*next_ptr != NULL) {
|
if (*next_ptr != NULL) {
|
||||||
@ -279,10 +287,13 @@ int lh_insert(_LHASH *lh, void **old_data, void *data) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *lh_delete(_LHASH *lh, const void *data) {
|
void *lh_delete(_LHASH *lh, const void *data,
|
||||||
|
lhash_hash_func_helper call_hash_func,
|
||||||
|
lhash_cmp_func_helper call_cmp_func) {
|
||||||
LHASH_ITEM **next_ptr, *item, *ret;
|
LHASH_ITEM **next_ptr, *item, *ret;
|
||||||
|
|
||||||
next_ptr = get_next_ptr_and_hash(lh, NULL, data);
|
next_ptr =
|
||||||
|
get_next_ptr_and_hash(lh, NULL, data, call_hash_func, call_cmp_func);
|
||||||
|
|
||||||
if (*next_ptr == NULL) {
|
if (*next_ptr == NULL) {
|
||||||
// No such element.
|
// No such element.
|
||||||
@ -300,8 +311,7 @@ void *lh_delete(_LHASH *lh, const void *data) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lh_doall_internal(_LHASH *lh, void (*no_arg_func)(void *),
|
void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), void *arg) {
|
||||||
void (*arg_func)(void *, void *), void *arg) {
|
|
||||||
if (lh == NULL) {
|
if (lh == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -315,11 +325,7 @@ static void lh_doall_internal(_LHASH *lh, void (*no_arg_func)(void *),
|
|||||||
LHASH_ITEM *next;
|
LHASH_ITEM *next;
|
||||||
for (LHASH_ITEM *cur = lh->buckets[i]; cur != NULL; cur = next) {
|
for (LHASH_ITEM *cur = lh->buckets[i]; cur != NULL; cur = next) {
|
||||||
next = cur->next;
|
next = cur->next;
|
||||||
if (arg_func) {
|
func(cur->data, arg);
|
||||||
arg_func(cur->data, arg);
|
|
||||||
} else {
|
|
||||||
no_arg_func(cur->data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,14 +339,6 @@ static void lh_doall_internal(_LHASH *lh, void (*no_arg_func)(void *),
|
|||||||
lh_maybe_resize(lh);
|
lh_maybe_resize(lh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lh_doall(_LHASH *lh, void (*func)(void *)) {
|
|
||||||
lh_doall_internal(lh, func, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), void *arg) {
|
|
||||||
lh_doall_internal(lh, NULL, func, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t lh_strhash(const char *c) {
|
uint32_t lh_strhash(const char *c) {
|
||||||
if (c == NULL) {
|
if (c == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -104,11 +104,22 @@ typedef struct lhash_item_st {
|
|||||||
// equal, to zero depending on whether |*a| is equal, or not equal to |*b|,
|
// equal, to zero depending on whether |*a| is equal, or not equal to |*b|,
|
||||||
// respectively. Note the difference between this and |stack_cmp_func| in that
|
// respectively. Note the difference between this and |stack_cmp_func| in that
|
||||||
// this takes pointers to the objects directly.
|
// this takes pointers to the objects directly.
|
||||||
|
//
|
||||||
|
// This function's actual type signature is int (*)(const T*, const T*). The
|
||||||
|
// low-level |lh_*| functions will be passed a type-specific wrapper to call it
|
||||||
|
// correctly.
|
||||||
typedef int (*lhash_cmp_func)(const void *a, const void *b);
|
typedef int (*lhash_cmp_func)(const void *a, const void *b);
|
||||||
|
typedef int (*lhash_cmp_func_helper)(lhash_cmp_func func, const void *a,
|
||||||
|
const void *b);
|
||||||
|
|
||||||
// lhash_hash_func is a function that maps an object to a uniformly distributed
|
// lhash_hash_func is a function that maps an object to a uniformly distributed
|
||||||
// uint32_t.
|
// uint32_t.
|
||||||
|
//
|
||||||
|
// This function's actual type signature is uint32_t (*)(const T*). The
|
||||||
|
// low-level |lh_*| functions will be passed a type-specific wrapper to call it
|
||||||
|
// correctly.
|
||||||
typedef uint32_t (*lhash_hash_func)(const void *a);
|
typedef uint32_t (*lhash_hash_func)(const void *a);
|
||||||
|
typedef uint32_t (*lhash_hash_func_helper)(lhash_hash_func func, const void *a);
|
||||||
|
|
||||||
typedef struct lhash_st _LHASH;
|
typedef struct lhash_st _LHASH;
|
||||||
|
|
||||||
@ -124,7 +135,9 @@ OPENSSL_EXPORT size_t lh_num_items(const _LHASH *lh);
|
|||||||
|
|
||||||
// lh_retrieve finds an element equal to |data| in the hash table and returns
|
// lh_retrieve finds an element equal to |data| in the hash table and returns
|
||||||
// it. If no such element exists, it returns NULL.
|
// it. If no such element exists, it returns NULL.
|
||||||
OPENSSL_EXPORT void *lh_retrieve(const _LHASH *lh, const void *data);
|
OPENSSL_EXPORT void *lh_retrieve(const _LHASH *lh, const void *data,
|
||||||
|
lhash_hash_func_helper call_hash_func,
|
||||||
|
lhash_cmp_func_helper call_cmp_func);
|
||||||
|
|
||||||
// lh_retrieve_key finds an element matching |key|, given the specified hash and
|
// lh_retrieve_key finds an element matching |key|, given the specified hash and
|
||||||
// comparison function. This differs from |lh_retrieve| in that the key may be a
|
// comparison function. This differs from |lh_retrieve| in that the key may be a
|
||||||
@ -140,15 +153,15 @@ OPENSSL_EXPORT void *lh_retrieve_key(const _LHASH *lh, const void *key,
|
|||||||
// will be set to that value and it will be replaced. Otherwise, or in the
|
// will be set to that value and it will be replaced. Otherwise, or in the
|
||||||
// event of an error, |*old_data| will be set to NULL. It returns one on
|
// event of an error, |*old_data| will be set to NULL. It returns one on
|
||||||
// success or zero in the case of an allocation error.
|
// success or zero in the case of an allocation error.
|
||||||
OPENSSL_EXPORT int lh_insert(_LHASH *lh, void **old_data, void *data);
|
OPENSSL_EXPORT int lh_insert(_LHASH *lh, void **old_data, void *data,
|
||||||
|
lhash_hash_func_helper call_hash_func,
|
||||||
|
lhash_cmp_func_helper call_cmp_func);
|
||||||
|
|
||||||
// lh_delete removes an element equal to |data| from the hash table and returns
|
// lh_delete removes an element equal to |data| from the hash table and returns
|
||||||
// it. If no such element is found, it returns NULL.
|
// it. If no such element is found, it returns NULL.
|
||||||
OPENSSL_EXPORT void *lh_delete(_LHASH *lh, const void *data);
|
OPENSSL_EXPORT void *lh_delete(_LHASH *lh, const void *data,
|
||||||
|
lhash_hash_func_helper call_hash_func,
|
||||||
// lh_doall calls |func| on each element of the hash table.
|
lhash_cmp_func_helper call_cmp_func);
|
||||||
// TODO(fork): rename this
|
|
||||||
OPENSSL_EXPORT void lh_doall(_LHASH *lh, void (*func)(void *));
|
|
||||||
|
|
||||||
// lh_doall_arg calls |func| on each element of the hash table and also passes
|
// lh_doall_arg calls |func| on each element of the hash table and also passes
|
||||||
// |arg| as the second argument.
|
// |arg| as the second argument.
|
||||||
@ -166,6 +179,16 @@ OPENSSL_EXPORT uint32_t lh_strhash(const char *c);
|
|||||||
typedef int (*lhash_##type##_cmp_func)(const type *, const type *); \
|
typedef int (*lhash_##type##_cmp_func)(const type *, const type *); \
|
||||||
typedef uint32_t (*lhash_##type##_hash_func)(const type *); \
|
typedef uint32_t (*lhash_##type##_hash_func)(const type *); \
|
||||||
\
|
\
|
||||||
|
OPENSSL_INLINE int lh_##type##_call_cmp_func(lhash_cmp_func func, \
|
||||||
|
const void *a, const void *b) { \
|
||||||
|
return ((lhash_##type##_cmp_func)func)((const type *)a, (const type *)b); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
OPENSSL_INLINE uint32_t lh_##type##_call_hash_func(lhash_hash_func func, \
|
||||||
|
const void *a) { \
|
||||||
|
return ((lhash_##type##_hash_func)func)((const type *)a); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
OPENSSL_INLINE LHASH_OF(type) * \
|
OPENSSL_INLINE LHASH_OF(type) * \
|
||||||
lh_##type##_new(lhash_##type##_hash_func hash, \
|
lh_##type##_new(lhash_##type##_hash_func hash, \
|
||||||
lhash_##type##_cmp_func comp) { \
|
lhash_##type##_cmp_func comp) { \
|
||||||
@ -183,38 +206,72 @@ OPENSSL_EXPORT uint32_t lh_strhash(const char *c);
|
|||||||
\
|
\
|
||||||
OPENSSL_INLINE type *lh_##type##_retrieve(const LHASH_OF(type) *lh, \
|
OPENSSL_INLINE type *lh_##type##_retrieve(const LHASH_OF(type) *lh, \
|
||||||
const type *data) { \
|
const type *data) { \
|
||||||
return (type *)lh_retrieve((const _LHASH *)lh, data); \
|
return (type *)lh_retrieve((const _LHASH *)lh, data, \
|
||||||
|
lh_##type##_call_hash_func, \
|
||||||
|
lh_##type##_call_cmp_func); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
typedef struct { \
|
||||||
|
int (*cmp_key)(const void *key, const type *value); \
|
||||||
|
const void *key; \
|
||||||
|
} LHASH_CMP_KEY_##type; \
|
||||||
|
\
|
||||||
|
OPENSSL_INLINE int lh_##type##_call_cmp_key(const void *key, \
|
||||||
|
const void *value) { \
|
||||||
|
const LHASH_CMP_KEY_##type *cb = (const LHASH_CMP_KEY_##type *)key; \
|
||||||
|
return cb->cmp_key(cb->key, (const type *)value); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
OPENSSL_INLINE type *lh_##type##_retrieve_key( \
|
OPENSSL_INLINE type *lh_##type##_retrieve_key( \
|
||||||
const LHASH_OF(type) *lh, const void *key, uint32_t key_hash, \
|
const LHASH_OF(type) *lh, const void *key, uint32_t key_hash, \
|
||||||
int (*cmp_key)(const void *key, const type *value)) { \
|
int (*cmp_key)(const void *key, const type *value)) { \
|
||||||
return (type *)lh_retrieve_key( \
|
LHASH_CMP_KEY_##type cb = {cmp_key, key}; \
|
||||||
(const _LHASH *)lh, key, key_hash, \
|
return (type *)lh_retrieve_key((const _LHASH *)lh, &cb, key_hash, \
|
||||||
(int (*)(const void *, const void *))cmp_key); \
|
lh_##type##_call_cmp_key); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
OPENSSL_INLINE int lh_##type##_insert(LHASH_OF(type) *lh, type **old_data, \
|
OPENSSL_INLINE int lh_##type##_insert(LHASH_OF(type) *lh, type **old_data, \
|
||||||
type *data) { \
|
type *data) { \
|
||||||
void *old_data_void = NULL; \
|
void *old_data_void = NULL; \
|
||||||
int ret = lh_insert((_LHASH *)lh, &old_data_void, data); \
|
int ret = \
|
||||||
|
lh_insert((_LHASH *)lh, &old_data_void, data, \
|
||||||
|
lh_##type##_call_hash_func, lh_##type##_call_cmp_func); \
|
||||||
*old_data = (type *)old_data_void; \
|
*old_data = (type *)old_data_void; \
|
||||||
return ret; \
|
return ret; \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
OPENSSL_INLINE type *lh_##type##_delete(LHASH_OF(type) *lh, \
|
OPENSSL_INLINE type *lh_##type##_delete(LHASH_OF(type) *lh, \
|
||||||
const type *data) { \
|
const type *data) { \
|
||||||
return (type *)lh_delete((_LHASH *)lh, data); \
|
return (type *)lh_delete((_LHASH *)lh, data, lh_##type##_call_hash_func, \
|
||||||
|
lh_##type##_call_cmp_func); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
typedef struct { \
|
||||||
|
void (*doall)(type *); \
|
||||||
|
void (*doall_arg)(type *, void *); \
|
||||||
|
void *arg; \
|
||||||
|
} LHASH_DOALL_##type; \
|
||||||
|
\
|
||||||
|
OPENSSL_INLINE void lh_##type##_call_doall(void *value, void *arg) { \
|
||||||
|
const LHASH_DOALL_##type *cb = (const LHASH_DOALL_##type *)arg; \
|
||||||
|
cb->doall((type *)value); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
OPENSSL_INLINE void lh_##type##_call_doall_arg(void *value, void *arg) { \
|
||||||
|
const LHASH_DOALL_##type *cb = (const LHASH_DOALL_##type *)arg; \
|
||||||
|
cb->doall_arg((type *)value, cb->arg); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
OPENSSL_INLINE void lh_##type##_doall(LHASH_OF(type) *lh, \
|
OPENSSL_INLINE void lh_##type##_doall(LHASH_OF(type) *lh, \
|
||||||
void (*func)(type *)) { \
|
void (*func)(type *)) { \
|
||||||
lh_doall((_LHASH *)lh, (void (*)(void *))func); \
|
LHASH_DOALL_##type cb = {func, NULL, NULL}; \
|
||||||
|
lh_doall_arg((_LHASH *)lh, lh_##type##_call_doall, &cb); \
|
||||||
} \
|
} \
|
||||||
\
|
\
|
||||||
OPENSSL_INLINE void lh_##type##_doall_arg( \
|
OPENSSL_INLINE void lh_##type##_doall_arg( \
|
||||||
LHASH_OF(type) *lh, void (*func)(type *, void *), void *arg) { \
|
LHASH_OF(type) *lh, void (*func)(type *, void *), void *arg) { \
|
||||||
lh_doall_arg((_LHASH *)lh, (void (*)(void *, void *))func, arg); \
|
LHASH_DOALL_##type cb = {NULL, func, arg}; \
|
||||||
|
lh_doall_arg((_LHASH *)lh, lh_##type##_call_doall_arg, &cb); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user