From: Nick Alcock Date: Tue, 2 Jun 2020 20:31:45 +0000 (+0100) Subject: libctf: add new dynhash functions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=809f6eb3321edb91fcc96b1f8353dbfe2f762fa7;p=binutils-gdb.git libctf: add new dynhash functions Future commits will use these. ctf_dynhash_elements: count elements in a dynhash ctf_dynhash_lookup_kv: look up and return pointers to the original key and value in a dynhash (the only way of getting a reference to the original key) ctf_dynhash_iter_find: iterate until an item is found, then return its key ctf_dynhash_cinsert: insert a const key / value into a dynhash (a thim wrapper in a new header dedicated to inline functions). As with the rest of ctf_dynhash, this is not public API. No impact on existing callers is expected. libctf/ * ctf-inlines.h: New file. * ctf-impl.h: Include it. (ctf_hash_iter_find_f): New typedef. (ctf_dynhash_elements): New. (ctf_dynhash_lookup_kv): New. (ctf_dynhash_iter_find): New. * ctf-hash.c (ctf_dynhash_lookup_kv): New. (ctf_traverse_find_cb_arg_t): New. (ctf_hashtab_traverse_find): New. (ctf_dynhash_iter_find): New. (ctf_dynhash_elements): New. --- diff --git a/libctf/ChangeLog b/libctf/ChangeLog index 642ed3f83c1..a7a31e70fc1 100644 --- a/libctf/ChangeLog +++ b/libctf/ChangeLog @@ -1,3 +1,17 @@ +2020-07-22 Nick Alcock + + * ctf-inlines.h: New file. + * ctf-impl.h: Include it. + (ctf_hash_iter_find_f): New typedef. + (ctf_dynhash_elements): New. + (ctf_dynhash_lookup_kv): New. + (ctf_dynhash_iter_find): New. + * ctf-hash.c (ctf_dynhash_lookup_kv): New. + (ctf_traverse_find_cb_arg_t): New. + (ctf_hashtab_traverse_find): New. + (ctf_dynhash_iter_find): New. + (ctf_dynhash_elements): New. + 2020-07-22 Nick Alcock * ctf-impl.h [!__GNUC__] (__extension__): Define to nothing. diff --git a/libctf/ctf-hash.c b/libctf/ctf-hash.c index 71c1f8e4e21..4696fcb2d43 100644 --- a/libctf/ctf-hash.c +++ b/libctf/ctf-hash.c @@ -218,6 +218,12 @@ ctf_dynhash_empty (ctf_dynhash_t *hp) htab_empty (hp->htab); } +size_t +ctf_dynhash_elements (ctf_dynhash_t *hp) +{ + return htab_elements (hp->htab); +} + void * ctf_dynhash_lookup (ctf_dynhash_t *hp, const void *key) { @@ -231,6 +237,26 @@ ctf_dynhash_lookup (ctf_dynhash_t *hp, const void *key) return NULL; } +/* TRUE/FALSE return. */ +int +ctf_dynhash_lookup_kv (ctf_dynhash_t *hp, const void *key, + const void **orig_key, void **value) +{ + ctf_helem_t **slot; + + slot = ctf_hashtab_lookup (hp->htab, key, NO_INSERT); + + if (slot) + { + if (orig_key) + *orig_key = (*slot)->key; + if (value) + *value = (*slot)->value; + return 1; + } + return 0; +} + typedef struct ctf_traverse_cb_arg { ctf_hash_iter_f fun; @@ -254,6 +280,35 @@ ctf_dynhash_iter (ctf_dynhash_t *hp, ctf_hash_iter_f fun, void *arg_) htab_traverse (hp->htab, ctf_hashtab_traverse, &arg); } +typedef struct ctf_traverse_find_cb_arg +{ + ctf_hash_iter_find_f fun; + void *arg; + void *found_key; +} ctf_traverse_find_cb_arg_t; + +static int +ctf_hashtab_traverse_find (void **slot, void *arg_) +{ + ctf_helem_t *helem = *((ctf_helem_t **) slot); + ctf_traverse_find_cb_arg_t *arg = (ctf_traverse_find_cb_arg_t *) arg_; + + if (arg->fun (helem->key, helem->value, arg->arg)) + { + arg->found_key = helem->key; + return 0; + } + return 1; +} + +void * +ctf_dynhash_iter_find (ctf_dynhash_t *hp, ctf_hash_iter_find_f fun, void *arg_) +{ + ctf_traverse_find_cb_arg_t arg = { fun, arg_, NULL }; + htab_traverse (hp->htab, ctf_hashtab_traverse_find, &arg); + return arg.found_key; +} + typedef struct ctf_traverse_remove_cb_arg { struct htab *htab; diff --git a/libctf/ctf-impl.h b/libctf/ctf-impl.h index f832c71b97c..3e097795bc6 100644 --- a/libctf/ctf-impl.h +++ b/libctf/ctf-impl.h @@ -382,6 +382,7 @@ typedef void (*ctf_hash_free_fun) (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); +typedef int (*ctf_hash_iter_find_f) (void *key, void *value, void *arg); extern ctf_hash_t *ctf_hash_create (unsigned long, ctf_hash_fun, ctf_hash_eq_fun); extern int ctf_hash_insert_type (ctf_hash_t *, ctf_file_t *, uint32_t, uint32_t); @@ -394,12 +395,17 @@ extern ctf_dynhash_t *ctf_dynhash_create (ctf_hash_fun, ctf_hash_eq_fun, ctf_hash_free_fun, ctf_hash_free_fun); extern int ctf_dynhash_insert (ctf_dynhash_t *, void *, void *); extern void ctf_dynhash_remove (ctf_dynhash_t *, const void *); +extern size_t ctf_dynhash_elements (ctf_dynhash_t *); extern void ctf_dynhash_empty (ctf_dynhash_t *); extern void *ctf_dynhash_lookup (ctf_dynhash_t *, const void *); +extern int ctf_dynhash_lookup_kv (ctf_dynhash_t *, const void *key, + const void **orig_key, void **value); extern void ctf_dynhash_destroy (ctf_dynhash_t *); extern void ctf_dynhash_iter (ctf_dynhash_t *, ctf_hash_iter_f, void *); extern void ctf_dynhash_iter_remove (ctf_dynhash_t *, ctf_hash_iter_remove_f, void *); +extern void *ctf_dynhash_iter_find (ctf_dynhash_t *, ctf_hash_iter_find_f, + void *); #define ctf_list_prev(elem) ((void *)(((ctf_list_t *)(elem))->l_prev)) #define ctf_list_next(elem) ((void *)(((ctf_list_t *)(elem))->l_next)) @@ -492,6 +498,8 @@ extern const char _CTF_NULLSTR[]; /* empty string */ extern int _libctf_version; /* library client version */ extern int _libctf_debug; /* debugging messages enabled */ +#include "ctf-inlines.h" + #ifdef __cplusplus } #endif diff --git a/libctf/ctf-inlines.h b/libctf/ctf-inlines.h new file mode 100644 index 00000000000..ad74b39f539 --- /dev/null +++ b/libctf/ctf-inlines.h @@ -0,0 +1,45 @@ +/* Inline functions. + Copyright (C) 2020 Free Software Foundation, Inc. + + This file is part of libctf. + + libctf 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 3, or (at your option) any later + version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; see the file COPYING. If not see + . */ + +#ifndef _CTF_INLINES_H +#define _CTF_INLINES_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "config.h" + +#ifndef _libctf_malloc_ +#error "ctf-inlines.h" should not be included directly: include "ctf-impl.h". +#endif + + +static inline int +ctf_dynhash_cinsert (ctf_dynhash_t *h, const void *k, const void *v) +{ + return ctf_dynhash_insert (h, (void *) k, (void *) v); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _CTF_INLINES_H */