forked from Imagelibrary/binutils-gdb
libctf, hash: add support for freeing functions taking an arg
There are a bunch of places in libctf where the code is complicated by the fact that freeing a hash key or value requires access to the dict: more generally, they want an arg pointer to *something*. But for the sake of being able to use free() as a freeing function, we can't do this at all times. We also don't want to bloat up the hash itself with an arg value unless necessary (in the same way we already avoid storing the key or value freeing functions unless at least one of them is specified). So from the outside this change is simple: add a new ctf_dynhash_create_arg which takes a new sort of freeing function which takes an argument. Internally, we store the arg only when the key or owner is set, and cast from the one freeing function to the other iff the arg is non-NULL. This means it's impossible to pass a value that may or may not be NULL to the freeing function, but that's harmless for all current uses, and allows significant simplifications elsewhere.
This commit is contained in:
@@ -651,7 +651,12 @@ extern int ctf_hash_eq_string (const void *, const void *);
|
||||
extern int ctf_hash_eq_type_key (const void *, const void *);
|
||||
extern int ctf_hash_eq_type_id_key (const void *, const void *);
|
||||
|
||||
/* Freeing functions. ctf_hash_free_fun is used unless the arg
|
||||
parameter to ctf_dynhash_create_{arg,sized} is non-NULL.
|
||||
There is no way to pass a NULL arg to ctf_hash_free_arg_fun. */
|
||||
|
||||
typedef void (*ctf_hash_free_fun) (void *);
|
||||
typedef void (*ctf_hash_free_arg_fun) (void *, void *);
|
||||
|
||||
typedef void (*ctf_hash_iter_f) (void *key, void *value, void *arg);
|
||||
typedef int (*ctf_hash_iter_remove_f) (void *key, void *value, void *arg);
|
||||
@@ -661,10 +666,14 @@ typedef int (*ctf_hash_sort_f) (const ctf_next_hkv_t *, const ctf_next_hkv_t *,
|
||||
|
||||
extern ctf_dynhash_t *ctf_dynhash_create (ctf_hash_fun, ctf_hash_eq_fun,
|
||||
ctf_hash_free_fun, ctf_hash_free_fun);
|
||||
extern ctf_dynhash_t *ctf_dynhash_create_arg (ctf_hash_fun, ctf_hash_eq_fun,
|
||||
ctf_hash_free_arg_fun,
|
||||
ctf_hash_free_arg_fun, void *);
|
||||
extern ctf_dynhash_t *ctf_dynhash_create_sized (unsigned long, ctf_hash_fun,
|
||||
ctf_hash_eq_fun,
|
||||
ctf_hash_free_fun,
|
||||
ctf_hash_free_fun);
|
||||
ctf_hash_free_arg_fun,
|
||||
ctf_hash_free_arg_fun,
|
||||
void *);
|
||||
|
||||
extern int ctf_dynhash_insert (ctf_dynhash_t *, void *, void *);
|
||||
extern void ctf_dynhash_remove (ctf_dynhash_t *, const void *);
|
||||
|
||||
Reference in New Issue
Block a user