From f2d8e0db3d128ed4fc5d6cbec3479ac1893c625d Mon Sep 17 00:00:00 2001 From: pelijah Date: Tue, 16 Apr 2024 15:27:48 +0300 Subject: [PATCH] Add HtSP, HtSS, HtSU, SetS (#4415) - All `ht_*_new0()` are removed - `freefn` field of HT options was renamed to `finiKV` - `finiKV_user` fields was added to HT options - Added `ht_*_new_opt_size` API - `HtSP` and `HtUP` are created with `ValueFree` callback that allows to reduce extra LOC and prevent bugs - `SetP` replaced with `SetS` (based on `HtSP`) - `rz_th_ht_*_new0()` and `rz_th_ht_*_new_opt()` are replaced with `rz_th_ht_*_new(HtXX *)` --- .clang-format | 3 +- binrz/rz-test/rz-test.c | 19 +- librz/arch/analysis.c | 15 +- librz/arch/asm.c | 19 +- librz/arch/block.c | 21 +-- librz/arch/class.c | 14 +- librz/arch/dwarf_process.c | 51 ++--- librz/arch/esil/esil.c | 15 +- librz/arch/esil/esil_interrupt.c | 5 +- librz/arch/esil/esil_trace.c | 8 +- librz/arch/fcn.c | 16 +- librz/arch/function.c | 39 ++-- librz/arch/hint.c | 6 +- librz/arch/il/analysis_il_trace.c | 8 +- librz/arch/isa/arm/arm_it.c | 4 +- librz/arch/isa/tms320/tms320_dasm.c | 2 +- librz/arch/labels.c | 12 +- librz/arch/platform_profile.c | 8 +- librz/arch/platform_target_index.c | 2 +- librz/arch/rtti_msvc.c | 10 +- librz/arch/serialize_analysis.c | 6 +- librz/arch/var_global.c | 12 +- librz/arch/xrefs.c | 16 +- librz/bin/bfile_string.c | 2 +- librz/bin/bobj.c | 28 +-- librz/bin/bobj_process_class.c | 22 +-- librz/bin/bobj_process_section.c | 10 +- librz/bin/bobj_process_symbol.c | 8 +- librz/bin/dbginfo.c | 6 +- librz/bin/dwarf/abbrev.c | 9 +- librz/bin/dwarf/endian_reader.c | 6 +- librz/bin/dwarf/loclists.c | 4 +- librz/bin/dwarf/macro.h | 2 +- librz/bin/dwarf/rnglists.c | 4 +- librz/bin/dwarf/unit.c | 8 +- librz/bin/format/coff/coff.c | 6 +- librz/bin/format/elf/elf_dynamic.c | 2 +- librz/bin/format/elf/elf_relocs.c | 2 +- librz/bin/format/elf/elf_symbols.c | 10 +- librz/bin/format/le/le.c | 6 +- librz/bin/format/mach0/dyldcache.c | 14 +- librz/bin/format/mach0/mach0.c | 22 +-- librz/bin/format/pe/pe_info.c | 2 +- librz/bin/p/bin_symbols.c | 2 +- librz/bin/p/bin_xnu_kernelcache.c | 12 +- librz/config/config.c | 18 +- librz/config/serialize_config.c | 10 +- librz/cons/canvas.c | 6 +- librz/cons/hud.c | 13 +- librz/cons/line.c | 2 +- librz/core/agraph.c | 57 +++--- librz/core/analysis_objc.c | 6 +- librz/core/analysis_tp.c | 16 +- librz/core/basefind.c | 2 +- librz/core/canalysis.c | 12 +- librz/core/cannotated_code.c | 2 +- librz/core/cbin.c | 45 ++--- librz/core/cgraph.c | 6 +- librz/core/cmd/cmd.c | 2 +- librz/core/cmd/cmd_analysis.c | 46 ++--- librz/core/cmd/cmd_api.c | 35 ++-- librz/core/cmd/cmd_eval.c | 12 +- librz/core/cmd/cmd_info.c | 10 +- librz/core/cmd/cmd_regs.c | 2 +- librz/core/core_private.h | 2 +- librz/core/disasm.c | 12 +- librz/core/tui/panels.c | 17 +- librz/debug/debug.c | 8 +- librz/debug/dsession.c | 8 +- librz/debug/trace.c | 12 +- librz/diff/diff.c | 23 ++- librz/flag/flag.c | 29 ++- librz/il/definitions/variable.c | 42 ++--- librz/il/il_validate.c | 77 ++++---- librz/il/il_vm.c | 28 +-- librz/include/meson.build | 3 + librz/include/rz_agraph.h | 2 +- librz/include/rz_analysis.h | 10 +- librz/include/rz_asm.h | 3 +- librz/include/rz_bin.h | 8 +- librz/include/rz_bin_source_line.h | 2 +- librz/include/rz_cmd.h | 4 +- librz/include/rz_config.h | 2 +- librz/include/rz_core.h | 2 +- librz/include/rz_debug.h | 2 +- librz/include/rz_flag.h | 3 +- librz/include/rz_il/definitions/variable.h | 5 +- librz/include/rz_il/rz_il_validate.h | 2 +- librz/include/rz_il/rz_il_vm.h | 5 +- librz/include/rz_lib.h | 4 +- librz/include/rz_list.h | 1 + librz/include/rz_reg.h | 3 +- librz/include/rz_type.h | 8 +- librz/include/rz_util/ht_inc.h | 120 ++++++++---- librz/include/rz_util/ht_pp.h | 14 +- librz/include/rz_util/ht_pu.h | 12 +- librz/include/rz_util/ht_sp.h | 25 +++ librz/include/rz_util/ht_ss.h | 25 +++ librz/include/rz_util/ht_su.h | 25 +++ librz/include/rz_util/ht_up.h | 16 +- librz/include/rz_util/ht_uu.h | 12 +- librz/include/rz_util/rz_serialize.h | 11 +- librz/include/rz_util/rz_str_constpool.h | 4 +- librz/include/rz_util/rz_th_ht.h | 9 +- librz/include/rz_util/set.h | 25 +-- librz/io/p_cache.c | 6 +- librz/main/rz-asm.c | 6 +- librz/reg/profile.c | 4 +- librz/reg/reg.c | 8 +- librz/sign/flirt.c | 2 +- librz/sign/sigdb.c | 6 +- librz/syscall/syscall.c | 6 +- librz/type/base.c | 16 +- librz/type/format.c | 14 +- librz/type/function.c | 26 ++- librz/type/parser/c_cpp_parser.c | 18 +- librz/type/parser/types_parser.h | 8 +- librz/type/parser/types_storage.c | 16 +- librz/type/serialize_functions.c | 22 +-- librz/type/serialize_types.c | 10 +- librz/type/type.c | 75 +++----- librz/type/typeclass.c | 8 +- librz/util/event.c | 6 +- librz/util/ht/ht_inc.c | 170 ++++++++++------- librz/util/ht/ht_pp.c | 44 ----- librz/util/ht/ht_pu.c | 20 -- librz/util/ht/ht_sp.c | 46 +++++ librz/util/ht/ht_ss.c | 45 +++++ librz/util/ht/ht_su.c | 33 ++++ librz/util/ht/ht_up.c | 67 ++++--- librz/util/ht/ht_uu.c | 16 +- librz/util/lib.c | 8 +- librz/util/meson.build | 3 + librz/util/sdb/src/sdb.c | 6 +- librz/util/sdb/src/sdb.h | 2 +- librz/util/sdb/src/sdbht.c | 37 ++-- librz/util/sdb/src/sdbht.h | 22 +-- librz/util/set.c | 77 +++++--- librz/util/str_constpool.c | 14 +- librz/util/sys.c | 2 +- librz/util/thread_hash_table.c | 32 +--- test/unit/test_analysis_function.c | 6 +- test/unit/test_il_validate.c | 48 ++--- test/unit/test_sdb_hash.c | 207 ++++++++++----------- test/unit/test_threads.c | 21 ++- 145 files changed, 1308 insertions(+), 1300 deletions(-) create mode 100644 librz/include/rz_util/ht_sp.h create mode 100644 librz/include/rz_util/ht_ss.h create mode 100644 librz/include/rz_util/ht_su.h create mode 100644 librz/util/ht/ht_sp.c create mode 100644 librz/util/ht/ht_ss.c create mode 100644 librz/util/ht/ht_su.c diff --git a/.clang-format b/.clang-format index 12abbc64b5f..0f55ff7bb65 100644 --- a/.clang-format +++ b/.clang-format @@ -24,4 +24,5 @@ AlignOperands: false Cpp11BracedListStyle: false ForEachMacros: ['rz_list_foreach', 'rz_list_foreach_safe', 'rz_pvector_foreach', 'rz_rbtree_foreach', 'rz_interval_tree_foreach', 'ls_foreach', 'rz_skiplist_foreach', 'graph_foreach_anode'] SortIncludes: false -RequiresClausePosition: SingleLine \ No newline at end of file +RequiresClausePosition: SingleLine +TypenameMacros: ['HT_', 'Ht_', 'HtName_'] \ No newline at end of file diff --git a/binrz/rz-test/rz-test.c b/binrz/rz-test/rz-test.c index ca3ba88c38e..25a9ae19388 100644 --- a/binrz/rz-test/rz-test.c +++ b/binrz/rz-test/rz-test.c @@ -42,7 +42,7 @@ typedef struct rz_test_state_t { RzThreadCond *cond; // signaled from workers to main thread to update status RzThreadLock *lock; // protects everything below - HtPP *path_left; // char * (path to test file) => RzTestFileCounts * + HtSP *path_left; // char * (path to test file) => RzTestFileCounts * RzPVector /**/ completed_paths; ut64 ok_count; ut64 xx_count; @@ -106,11 +106,6 @@ static int help(bool verbose) { return 1; } -static void path_left_free_kv(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - static bool rz_test_chdir(const char *argv0) { #if __UNIX__ if (rz_file_is_directory("db")) { @@ -517,15 +512,15 @@ int rz_test_main(int argc, const char **argv) { if (log_mode) { // Log mode prints the state after every completed file. // The count of tests left per file is stored in a ht. - state.path_left = ht_pp_new(NULL, path_left_free_kv, NULL); + state.path_left = ht_sp_new(HT_STR_DUP, NULL, free); if (state.path_left) { void **it; rz_pvector_foreach (&state.queue, it) { RzTest *test = *it; - RzTestFileCounts *counts = ht_pp_find(state.path_left, test->path, NULL); + RzTestFileCounts *counts = ht_sp_find(state.path_left, test->path, NULL); if (!counts) { counts = calloc(1, sizeof(RzTestFileCounts)); - ht_pp_insert(state.path_left, test->path, counts); + ht_sp_insert(state.path_left, test->path, counts); } counts->tests_left++; } @@ -615,7 +610,7 @@ int rz_test_main(int argc, const char **argv) { rz_test_test_database_free(state.db); rz_th_lock_free(state.lock); rz_th_cond_free(state.cond); - ht_pp_free(state.path_left); + ht_sp_free(state.path_left); beach: free(output_file); free(rizin_cmd); @@ -709,7 +704,7 @@ static void *worker_th(RzTestState *state) { } } if (state->path_left) { - RzTestFileCounts *counts = ht_pp_find(state->path_left, test->path, NULL); + RzTestFileCounts *counts = ht_sp_find(state->path_left, test->path, NULL); if (counts) { switch (result->result) { case RZ_TEST_RESULT_OK: @@ -953,7 +948,7 @@ static void print_log(RzTestState *state, ut64 prev_completed, ut64 prev_paths_c } printf("[**] %50s ", name); if (state->path_left) { - RzTestFileCounts *counts = ht_pp_find(state->path_left, name, NULL); + RzTestFileCounts *counts = ht_sp_find(state->path_left, name, NULL); if (counts) { state->ok_count += counts->ok; state->xx_count += counts->xx; diff --git a/librz/arch/analysis.c b/librz/arch/analysis.c index 68e9e9ce083..664c03f44db 100644 --- a/librz/arch/analysis.c +++ b/librz/arch/analysis.c @@ -66,11 +66,6 @@ static void meta_item_free(void *item) { free(it); } -static void global_kv_free(HtPPKv *kv) { - free(kv->key); - rz_analysis_var_global_free(kv->value); -} - RZ_API RzAnalysis *rz_analysis_new(void) { RzAnalysis *analysis = RZ_NEW0(RzAnalysis); if (!analysis) { @@ -86,8 +81,8 @@ RZ_API RzAnalysis *rz_analysis_new(void) { return NULL; } analysis->bb_tree = NULL; - analysis->ht_addr_fun = ht_up_new0(); - analysis->ht_name_fun = ht_pp_new0(); + analysis->ht_addr_fun = ht_up_new(NULL, NULL); + analysis->ht_name_fun = ht_sp_new(HT_STR_DUP, NULL, NULL); analysis->os = strdup(RZ_SYS_OS); analysis->esil_goto_limit = RZ_ANALYSIS_ESIL_GOTO_LIMIT; analysis->opt.nopskip = true; // skip nops in code analysis @@ -133,7 +128,7 @@ RZ_API RzAnalysis *rz_analysis_new(void) { rz_analysis_plugin_add(analysis, plugin); } } - analysis->ht_global_var = ht_pp_new(NULL, global_kv_free, NULL); + analysis->ht_global_var = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_analysis_var_global_free); analysis->global_var_tree = NULL; analysis->il_vm = NULL; analysis->hash = rz_hash_new(); @@ -164,7 +159,7 @@ RZ_API RzAnalysis *rz_analysis_free(RzAnalysis *a) { rz_analysis_il_vm_cleanup(a); rz_list_free(a->fcns); ht_up_free(a->ht_addr_fun); - ht_pp_free(a->ht_name_fun); + ht_sp_free(a->ht_name_fun); set_u_free(a->visited); rz_analysis_hint_storage_fini(a); rz_interval_tree_fini(&a->meta); @@ -189,7 +184,7 @@ RZ_API RzAnalysis *rz_analysis_free(RzAnalysis *a) { free(a->last_disasm_reg); rz_list_free(a->imports); rz_str_constpool_fini(&a->constpool); - ht_pp_free(a->ht_global_var); + ht_sp_free(a->ht_global_var); rz_list_free(a->plugins); rz_analysis_debug_info_free(a->debug_info); free(a); diff --git a/librz/arch/asm.c b/librz/arch/asm.c index 3774e67030b..530ac183c1f 100644 --- a/librz/arch/asm.c +++ b/librz/arch/asm.c @@ -75,7 +75,7 @@ static bool is_register(const char *name, RZ_BORROW const RzRegSet *regset) { bool found = false; for (ut32 i = 0; i < RZ_REG_TYPE_LAST; ++i) { if (regset[i].ht_regs) { - ht_pp_find(regset[i].ht_regs, name, &found); + ht_sp_find(regset[i].ht_regs, name, &found); if (found) { return true; } @@ -345,7 +345,7 @@ RZ_API void rz_asm_free(RzAsm *a) { free(a->cpu); free(a->features); sdb_free(a->pair); - ht_pp_free(a->flags); + ht_ss_free(a->flags); a->pair = NULL; free(a); } @@ -835,15 +835,6 @@ RZ_API RzAsmCode *rz_asm_mdisassemble_hexstr(RzAsm *a, RzParse *p, const char *h return ret; } -static void __flag_free_kv(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - -static void *__dup_val(const void *v) { - return (void *)strdup((char *)v); -} - RZ_API RzAsmCode *rz_asm_massemble(RzAsm *a, const char *assembly) { int num, stage, ret, idx, ctr, i, linenum = 0; char *lbuf = NULL, *ptr2, *ptr = NULL, *ptr_start = NULL; @@ -862,8 +853,8 @@ RZ_API RzAsmCode *rz_asm_massemble(RzAsm *a, const char *assembly) { free(tokens); return NULL; } - ht_pp_free(a->flags); - if (!(a->flags = ht_pp_new(__dup_val, __flag_free_kv, NULL))) { + ht_ss_free(a->flags); + if (!(a->flags = ht_ss_new(HT_STR_DUP, HT_STR_DUP))) { free(tokens); return NULL; } @@ -1037,7 +1028,7 @@ RZ_API RzAsmCode *rz_asm_massemble(RzAsm *a, const char *assembly) { off += (acode->code_align - (off % acode->code_align)); } char *food = rz_str_newf("0x%" PFMT64x, off); - ht_pp_insert(a->flags, ptr_start, food); + ht_ss_insert(a->flags, ptr_start, food); rz_asm_code_set_equ(acode, p, food); free(p); free(food); diff --git a/librz/arch/block.c b/librz/arch/block.c index 200d5ed55b1..cd63777b409 100644 --- a/librz/arch/block.c +++ b/librz/arch/block.c @@ -436,7 +436,7 @@ RZ_API bool rz_analysis_block_recurse(RzAnalysisBlock *block, RzAnalysisBlockCb RzAnalysisBlockRecurseContext ctx; ctx.analysis = block->analysis; rz_pvector_init(&ctx.to_visit, NULL); - ctx.visited = ht_up_new0(); + ctx.visited = ht_up_new(NULL, NULL); if (!ctx.visited) { goto beach; } @@ -464,7 +464,7 @@ RZ_API bool rz_analysis_block_recurse_followthrough(RzAnalysisBlock *block, RzAn RzAnalysisBlockRecurseContext ctx; ctx.analysis = block->analysis; rz_pvector_init(&ctx.to_visit, NULL); - ctx.visited = ht_up_new0(); + ctx.visited = ht_up_new(NULL, NULL); if (!ctx.visited) { goto beach; } @@ -497,7 +497,7 @@ RZ_API bool rz_analysis_block_recurse_depth_first(RzAnalysisBlock *block, RzAnal rz_return_val_if_fail(block && cb, true); RzVector path; bool breaked = false; - HtUP *visited = ht_up_new0(); + HtUP *visited = ht_up_new(NULL, NULL); rz_vector_init(&path, sizeof(RecurseDepthFirstCtx), NULL, NULL); if (!visited) { goto beach; @@ -637,7 +637,7 @@ RZ_API RZ_NULLABLE RzList /**/ *rz_analysis_block_shortest_pa ctx.next_visit = &visit_a; RzPVector *cur_visit = &visit_b; // cur visit is the current level in the tree - ctx.visited = ht_up_new0(); + ctx.visited = ht_up_new(NULL, NULL); if (!ctx.visited) { goto beach; } @@ -721,8 +721,7 @@ typedef struct { bool reachable; } NoreturnSuccessor; -static void noreturn_successor_free(HtUPKv *kv) { - NoreturnSuccessor *succ = kv->value; +static void noreturn_successor_free(NoreturnSuccessor *succ) { rz_analysis_block_unref(succ->block); free(succ); } @@ -776,7 +775,7 @@ RZ_API RzAnalysisBlock *rz_analysis_block_chop_noreturn(RzAnalysisBlock *block, // Cache all recursive successors of block here. // These are the candidates that we might have to remove from functions later. - HtUP *succs = ht_up_new(NULL, noreturn_successor_free, NULL); // maps block addr (ut64) => NoreturnSuccessor * + HtUP *succs = ht_up_new(NULL, (HtUPFreeValue)noreturn_successor_free); // maps block addr (ut64) => NoreturnSuccessor * if (!succs) { return block; } @@ -897,12 +896,12 @@ static bool automerge_get_predecessors_cb(void *user, const ut64 k, const void * RZ_API void rz_analysis_block_automerge(RzPVector /**/ *blocks) { rz_return_if_fail(blocks); AutomergeCtx ctx = { - .predecessors = ht_up_new0(), - .visited_blocks = ht_up_new0(), - .blocks = ht_up_new0() + .predecessors = ht_up_new(NULL, NULL), + .visited_blocks = ht_up_new(NULL, NULL), + .blocks = ht_up_new(NULL, NULL) }; - HtUP *relevant_fcns = ht_up_new0(); // all the functions that contain some of our blocks (ht abused as a set) + HtUP *relevant_fcns = ht_up_new(NULL, NULL); // all the functions that contain some of our blocks (ht abused as a set) RzList *fixup_candidates = rz_list_new(); // used further down if (!ctx.predecessors || !ctx.visited_blocks || !ctx.blocks || !relevant_fcns || !fixup_candidates) { goto beach; diff --git a/librz/arch/class.c b/librz/arch/class.c index 82e7d9ea836..b74980713f4 100644 --- a/librz/arch/class.c +++ b/librz/arch/class.c @@ -1284,7 +1284,7 @@ RZ_API RzGraph /**/ *rz_analysis_class_get_inheritance_graph( rz_graph_free(class_graph); return NULL; } - HtPP /**/ *hashmap = ht_pp_new0(); + HtSP /**/ *hashmap = ht_sp_new(HT_STR_DUP, NULL, NULL); if (!hashmap) { rz_graph_free(class_graph); ls_free(classes); @@ -1296,39 +1296,39 @@ RZ_API RzGraph /**/ *rz_analysis_class_get_inheritance_graph( ls_foreach (classes, iter, kv) { const char *name = sdbkv_key(kv); // create nodes - RzGraphNode *curr_node = ht_pp_find(hashmap, name, NULL); + RzGraphNode *curr_node = ht_sp_find(hashmap, name, NULL); if (!curr_node) { curr_node = rz_graph_add_node_info(class_graph, name, NULL, 0); if (!curr_node) { goto failure; } - ht_pp_insert(hashmap, name, curr_node); + ht_sp_insert(hashmap, name, curr_node); } // create edges between node and it's parents RzVector *bases = rz_analysis_class_base_get_all(analysis, name); RzAnalysisBaseClass *base; rz_vector_foreach(bases, base) { bool base_found = false; - RzGraphNode *base_node = ht_pp_find(hashmap, base->class_name, &base_found); + RzGraphNode *base_node = ht_sp_find(hashmap, base->class_name, &base_found); // If base isn't processed, do it now if (!base_found) { base_node = rz_graph_add_node_info(class_graph, base->class_name, NULL, 0); if (!base_node) { goto failure; } - ht_pp_insert(hashmap, base->class_name, base_node); + ht_sp_insert(hashmap, base->class_name, base_node); } rz_graph_add_edge(class_graph, base_node, curr_node); } rz_vector_free(bases); } ls_free(classes); - ht_pp_free(hashmap); + ht_sp_free(hashmap); return class_graph; failure: ls_free(classes); - ht_pp_free(hashmap); + ht_sp_free(hashmap); rz_graph_free(class_graph); return NULL; } diff --git a/librz/arch/dwarf_process.c b/librz/arch/dwarf_process.c index fbe9e5c91f0..c8cd0f793c7 100644 --- a/librz/arch/dwarf_process.c +++ b/librz/arch/dwarf_process.c @@ -8,13 +8,6 @@ #include #include -#define Ht_FREE_IMPL(V, T, f) \ - static void Ht##V##_##T##_free(Ht##V##Kv *kv) { \ - if (!kv) \ - return; \ - f(kv->value); \ - } - typedef struct { char *c_str; ut64 length; @@ -28,8 +21,6 @@ static void String_free(String *str) { free(str); } -Ht_FREE_IMPL(UP, String, String_free); - typedef struct dwarf_context_t { RzAnalysis *analysis; RzBinDwarfCompUnit *unit; @@ -477,7 +468,8 @@ static const char *map_dwarf_reg_to_riscv_reg(ut32 reg_num) { } #define KASE(_num, _reg) \ - case _num: return #_reg; + case _num: \ + return #_reg; #include #include @@ -762,10 +754,10 @@ static RzBaseType *RzBaseType_from_die(DwContext *ctx, const RzBinDwarfDie *die) btype->name, die->offset); } - RzPVector *btypes = ht_pp_find(ctx->analysis->debug_info->base_types_by_name, btype->name, NULL); + RzPVector *btypes = ht_sp_find(ctx->analysis->debug_info->base_types_by_name, btype->name, NULL); if (!btypes) { btypes = rz_pvector_new(NULL); - ht_pp_insert(ctx->analysis->debug_info->base_types_by_name, btype->name, btypes); + ht_sp_insert(ctx->analysis->debug_info->base_types_by_name, btype->name, btypes); rz_pvector_push(btypes, btype); } else { void **it; @@ -1749,7 +1741,7 @@ RZ_API void rz_analysis_dwarf_preprocess_info( DwContext ctx = { .analysis = analysis, .dw = dw, - .str_escaped = ht_up_new(NULL, HtUP_String_free, NULL), + .str_escaped = ht_up_new(NULL, (HtUPFreeValue)String_free), .unit = NULL, }; RzBinDwarfCompUnit *unit; @@ -1797,7 +1789,7 @@ static void db_save_renamed(RzTypeDB *db, RzBaseType *b, char *name) { rz_type_db_update_base_type(db, b); } -static bool store_base_type(void *u, const void *k, const void *v) { +static bool store_base_type(void *u, const char *k, const void *v) { RzAnalysis *analysis = u; const char *name = k; RzPVector *types = (RzPVector *)v; @@ -1859,7 +1851,7 @@ static bool store_callable(void *u, ut64 k, const void *v) { RZ_API void rz_analysis_dwarf_process_info(RzAnalysis *analysis, RzBinDWARF *dw) { rz_return_if_fail(analysis && dw); rz_analysis_dwarf_preprocess_info(analysis, dw); - ht_pp_foreach(analysis->debug_info->base_types_by_name, store_base_type, (void *)analysis); + ht_sp_foreach(analysis->debug_info->base_types_by_name, store_base_type, (void *)analysis); ht_up_foreach(analysis->debug_info->callable_by_offset, store_callable, (void *)analysis); } @@ -2072,19 +2064,6 @@ RZ_API void rz_analysis_dwarf_integrate_functions(RzAnalysis *analysis, RzFlag * ht_up_foreach(analysis->debug_info->function_by_addr, dwarf_integrate_function, analysis); } -Ht_FREE_IMPL(UP, RzType, rz_type_free); -Ht_FREE_IMPL(UP, RzBaseType, rz_type_base_type_free); -Ht_FREE_IMPL(UP, RzAnalysisDwarfFunction, function_free); -Ht_FREE_IMPL(UP, RzCallable, rz_type_callable_free); - -static void HtPP_RzPVector_free(HtPPKv *kv) { - if (!kv) { - return; - } - free(kv->key); - rz_pvector_free(kv->value); -} - /** * \brief Create a new debug info * \return RzAnalysisDebugInfo pointer @@ -2094,13 +2073,13 @@ RZ_API RzAnalysisDebugInfo *rz_analysis_debug_info_new() { if (!debug_info) { return NULL; } - debug_info->function_by_offset = ht_up_new(NULL, HtUP_RzAnalysisDwarfFunction_free, NULL); - debug_info->function_by_addr = ht_up_new0(); - debug_info->variable_by_offset = ht_up_new0(); - debug_info->type_by_offset = ht_up_new(NULL, HtUP_RzType_free, NULL); - debug_info->callable_by_offset = ht_up_new(NULL, HtUP_RzCallable_free, NULL); - debug_info->base_type_by_offset = ht_up_new(NULL, HtUP_RzBaseType_free, NULL); - debug_info->base_types_by_name = ht_pp_new(NULL, HtPP_RzPVector_free, NULL); + debug_info->function_by_offset = ht_up_new(NULL, (HtUPFreeValue)function_free); + debug_info->function_by_addr = ht_up_new(NULL, NULL); + debug_info->variable_by_offset = ht_up_new(NULL, NULL); + debug_info->type_by_offset = ht_up_new(NULL, (HtUPFreeValue)rz_type_free); + debug_info->callable_by_offset = ht_up_new(NULL, (HtUPFreeValue)rz_type_callable_free); + debug_info->base_type_by_offset = ht_up_new(NULL, (HtUPFreeValue)rz_type_base_type_free); + debug_info->base_types_by_name = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_pvector_free); debug_info->visited = set_u_new(); return debug_info; } @@ -2119,7 +2098,7 @@ RZ_API void rz_analysis_debug_info_free(RzAnalysisDebugInfo *debuginfo) { ht_up_free(debuginfo->type_by_offset); ht_up_free(debuginfo->callable_by_offset); ht_up_free(debuginfo->base_type_by_offset); - ht_pp_free(debuginfo->base_types_by_name); + ht_sp_free(debuginfo->base_types_by_name); rz_bin_dwarf_free(debuginfo->dw); set_u_free(debuginfo->visited); free(debuginfo); diff --git a/librz/arch/esil/esil.c b/librz/arch/esil/esil.c index beaefd6519b..a03bbeeb51e 100644 --- a/librz/arch/esil/esil.c +++ b/librz/arch/esil/esil.c @@ -77,11 +77,6 @@ static bool popRN(RzAnalysisEsil *esil, ut64 *n) { /* RZ_ANALYSIS_ESIL API */ -static void esil_ops_free(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize) { RzAnalysisEsil *esil = RZ_NEW0(RzAnalysisEsil); if (!esil) { @@ -98,7 +93,7 @@ RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned esil->verbose = false; esil->stacksize = stacksize; esil->parse_goto_count = RZ_ANALYSIS_ESIL_GOTO_LIMIT; - esil->ops = ht_pp_new(NULL, esil_ops_free, NULL); + esil->ops = ht_sp_new(HT_STR_DUP, NULL, free); esil->iotrap = iotrap; esil->in_cmd_step = false; rz_analysis_esil_sources_init(esil); @@ -110,14 +105,14 @@ RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned RZ_API bool rz_analysis_esil_set_op(RzAnalysisEsil *esil, const char *op, RzAnalysisEsilOpCb code, ut32 push, ut32 pop, ut32 type) { rz_return_val_if_fail(code && RZ_STR_ISNOTEMPTY(op) && esil && esil->ops, false); - RzAnalysisEsilOp *eop = ht_pp_find(esil->ops, op, NULL); + RzAnalysisEsilOp *eop = ht_sp_find(esil->ops, op, NULL); if (!eop) { eop = RZ_NEW(RzAnalysisEsilOp); if (!eop) { RZ_LOG_ERROR("Cannot allocate esil-operation %s\n", op); return false; } - if (!ht_pp_insert(esil->ops, op, eop)) { + if (!ht_sp_insert(esil->ops, op, eop)) { RZ_LOG_ERROR("Cannot set esil-operation %s\n", op); free(eop); return false; @@ -168,7 +163,7 @@ RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil) { if (esil->analysis && esil == esil->analysis->esil) { esil->analysis->esil = NULL; } - ht_pp_free(esil->ops); + ht_sp_free(esil->ops); esil->ops = NULL; rz_analysis_esil_interrupts_fini(esil); rz_analysis_esil_sources_fini(esil); @@ -2828,7 +2823,7 @@ static bool esil_set_delay_slot(RzAnalysisEsil *esil) { } static bool iscommand(RzAnalysisEsil *esil, const char *word, RzAnalysisEsilOp **op) { - RzAnalysisEsilOp *eop = ht_pp_find(esil->ops, word, NULL); + RzAnalysisEsilOp *eop = ht_sp_find(esil->ops, word, NULL); if (eop) { *op = eop; return true; diff --git a/librz/arch/esil/esil_interrupt.c b/librz/arch/esil/esil_interrupt.c index c30235135f9..b36750c2fcf 100644 --- a/librz/arch/esil/esil_interrupt.c +++ b/librz/arch/esil/esil_interrupt.c @@ -5,14 +5,13 @@ #include #include -static void interrupt_free(HtUPKv *kv) { - RzAnalysisEsilInterrupt *i = (RzAnalysisEsilInterrupt *)kv->value; +static void interrupt_free(RzAnalysisEsilInterrupt *i) { rz_analysis_esil_interrupt_free(i->esil, i); } RZ_API void rz_analysis_esil_interrupts_init(RzAnalysisEsil *esil) { rz_return_if_fail(esil); - esil->interrupts = ht_up_new(NULL, interrupt_free, NULL); + esil->interrupts = ht_up_new(NULL, (HtUPFreeValue)interrupt_free); } RZ_API RzAnalysisEsilInterrupt *rz_analysis_esil_interrupt_new(RzAnalysisEsil *esil, ut32 src_id, RzAnalysisEsilInterruptHandler *ih) { diff --git a/librz/arch/esil/esil_trace.c b/librz/arch/esil/esil_trace.c index 76e353222c2..747d2bee3f3 100644 --- a/librz/arch/esil/esil_trace.c +++ b/librz/arch/esil/esil_trace.c @@ -20,10 +20,6 @@ static inline bool esil_add_reg_trace(RzAnalysisEsilTrace *etrace, RzILTraceRegO return rz_analysis_il_trace_add_reg(instr_trace, reg); } -static void htup_vector_free(HtUPKv *kv) { - rz_vector_free(kv->value); -} - RZ_API RzAnalysisEsilTrace *rz_analysis_esil_trace_new(RzAnalysisEsil *esil) { rz_return_val_if_fail(esil && esil->stack_addr && esil->stack_size, NULL); size_t i; @@ -31,12 +27,12 @@ RZ_API RzAnalysisEsilTrace *rz_analysis_esil_trace_new(RzAnalysisEsil *esil) { if (!trace) { return NULL; } - trace->registers = ht_up_new(NULL, htup_vector_free, NULL); + trace->registers = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); if (!trace->registers) { RZ_LOG_ERROR("esil: Cannot allocate hashmap for trace registers\n"); goto error; } - trace->memory = ht_up_new(NULL, htup_vector_free, NULL); + trace->memory = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); if (!trace->memory) { RZ_LOG_ERROR("esil: Cannot allocate hashmap for trace memory\n"); goto error; diff --git a/librz/arch/fcn.c b/librz/arch/fcn.c index d7a9444f9a8..7a0a21ace04 100644 --- a/librz/arch/fcn.c +++ b/librz/arch/fcn.c @@ -1732,7 +1732,7 @@ RZ_DEPRECATE RZ_API RzAnalysisFunction *rz_analysis_get_fcn_in_bounds(RzAnalysis */ RZ_API RzAnalysisFunction *rz_analysis_get_function_byname(RzAnalysis *a, const char *name) { bool found = false; - RzAnalysisFunction *f = ht_pp_find(a->ht_name_fun, name, &found); + RzAnalysisFunction *f = ht_sp_find(a->ht_name_fun, name, &found); if (f && found) { return f; } @@ -2134,7 +2134,7 @@ RZ_API int rz_analysis_function_count_edges(const RzAnalysisFunction *fcn, RZ_NU */ RZ_API bool rz_analysis_function_purity(RzAnalysisFunction *fcn) { if (fcn->has_changed) { - HtUP *ht = ht_up_new(NULL, NULL, NULL); + HtUP *ht = ht_up_new(NULL, NULL); if (ht) { check_purity(ht, fcn); ht_up_free(ht); @@ -2265,10 +2265,6 @@ static bool analize_descendents(RzAnalysisBlock *bb, void *user) { return rz_analysis_block_successor_addrs_foreach(bb, analize_addr_cb, user); } -static void free_ht_up(HtUPKv *kv) { - ht_up_free((HtUP *)kv->value); -} - static void update_vars_analysis(RzAnalysisFunction *fcn, RzAnalysisBlock *block, int align, ut64 from, ut64 to) { RzAnalysis *analysis = fcn->analysis; ut64 cur_addr; @@ -2343,7 +2339,7 @@ static void update_analysis(RzAnalysis *analysis, RzList /*addr, NULL); BlockRecurseCtx ctx = { fcn, ht }; rz_analysis_block_recurse(bb, analize_descendents, &ctx); @@ -2382,7 +2378,7 @@ static void calc_reachable_and_remove_block(RzList /**/ *f rz_list_append(fcns, fcn); // Calculate reachable blocks from the start of function - HtUP *ht = ht_up_new0(); + HtUP *ht = ht_up_new(NULL, NULL); BlockRecurseCtx ctx = { fcn, ht }; rz_analysis_block_recurse(rz_analysis_get_block_at(fcn->analysis, fcn->addr), mark_as_visited, &ctx); ht_up_insert(reachable, fcn->addr, ht); @@ -2402,7 +2398,7 @@ RZ_API void rz_analysis_update_analysis_range(RzAnalysis *analysis, ut64 addr, i return; } RzList *fcns = rz_list_new(); - HtUP *reachable = ht_up_new(NULL, free_ht_up, NULL); + HtUP *reachable = ht_up_new(NULL, (HtUPFreeValue)ht_up_free); const int align = rz_analysis_archinfo(analysis, RZ_ANALYSIS_ARCHINFO_TEXT_ALIGN); const ut64 end_write = addr + size; @@ -2436,7 +2432,7 @@ RZ_API void rz_analysis_function_update_analysis(RzAnalysisFunction *fcn) { RzAnalysisBlock *bb; RzAnalysisFunction *f; RzList *fcns = rz_list_new(); - HtUP *reachable = ht_up_new(NULL, free_ht_up, NULL); + HtUP *reachable = ht_up_new(NULL, (HtUPFreeValue)ht_up_free); // in this loop we modify the pvector size we cannot loop normally. size_t count = rz_pvector_len(fcn->bbs); diff --git a/librz/arch/function.c b/librz/arch/function.c index 3ce5b63098b..006ee5774ec 100644 --- a/librz/arch/function.c +++ b/librz/arch/function.c @@ -63,7 +63,7 @@ static bool function_name_exists(RzAnalysis *analysis, const char *name, ut64 ad RZ_LOG_INFO("Empty function name, we must auto generate one\n"); return true; } - RzAnalysisFunction *f = ht_pp_find(analysis->ht_name_fun, name, &found); + RzAnalysisFunction *f = ht_sp_find(analysis->ht_name_fun, name, &found); if (f && found) { return true; } @@ -80,19 +80,6 @@ static bool function_already_defined_at(RzAnalysis *analysis, const char *name, return false; } -static void inst_vars_kv_free(HtUPKv *kv) { - rz_pvector_free(kv->value); -} - -static void labels_kv_free(HtUPKv *kv) { - free(kv->value); -} - -static void label_addrs_kv_free(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - RZ_API RzAnalysisFunction *rz_analysis_function_new(RzAnalysis *analysis) { RzAnalysisFunction *fcn = RZ_NEW0(RzAnalysisFunction); if (!fcn) { @@ -108,9 +95,9 @@ RZ_API RzAnalysisFunction *rz_analysis_function_new(RzAnalysis *analysis) { fcn->is_noreturn = false; fcn->meta._min = UT64_MAX; rz_pvector_init(&fcn->vars, (RzPVectorFree)rz_analysis_var_free); - fcn->inst_vars = ht_up_new(NULL, inst_vars_kv_free, NULL); - fcn->labels = ht_up_new(NULL, labels_kv_free, NULL); - fcn->label_addrs = ht_pp_new(NULL, label_addrs_kv_free, NULL); + fcn->inst_vars = ht_up_new(NULL, (HtUPFreeValue)rz_pvector_free); + fcn->labels = ht_up_new(NULL, free); + fcn->label_addrs = ht_sp_new(HT_STR_DUP, NULL, free); return fcn; } @@ -133,14 +120,14 @@ RZ_API void rz_analysis_function_free(void *_fcn) { if (ht_up_find(analysis->ht_addr_fun, fcn->addr, NULL) == _fcn) { ht_up_delete(analysis->ht_addr_fun, fcn->addr); } - if (ht_pp_find(analysis->ht_name_fun, fcn->name, NULL) == _fcn) { - ht_pp_delete(analysis->ht_name_fun, fcn->name); + if (ht_sp_find(analysis->ht_name_fun, fcn->name, NULL) == _fcn) { + ht_sp_delete(analysis->ht_name_fun, fcn->name); } rz_pvector_fini(&fcn->vars); ht_up_free(fcn->inst_vars); ht_up_free(fcn->labels); - ht_pp_free(fcn->label_addrs); + ht_sp_free(fcn->label_addrs); rz_type_free(fcn->ret_type); free(fcn->name); rz_list_free(fcn->imports); @@ -174,7 +161,7 @@ RZ_API bool rz_analysis_add_function(RzAnalysis *analysis, RzAnalysisFunction *f } fcn->is_noreturn = rz_analysis_noreturn_at_addr(analysis, fcn->addr); rz_list_append(analysis->fcns, fcn); - return ht_pp_insert(analysis->ht_name_fun, fcn->name, fcn) && ht_up_insert(analysis->ht_addr_fun, fcn->addr, fcn); + return ht_sp_insert(analysis->ht_name_fun, fcn->name, fcn) && ht_up_insert(analysis->ht_addr_fun, fcn->addr, fcn); } RZ_API RzAnalysisFunction *rz_analysis_create_function(RzAnalysis *analysis, const char *name, ut64 addr, RzAnalysisFcnType type) { @@ -255,13 +242,13 @@ RZ_API bool rz_analysis_function_relocate(RzAnalysisFunction *fcn, ut64 addr) { } } InstVarsRelocateCtx ctx = { - .inst_vars_new = ht_up_new(NULL, inst_vars_kv_free, NULL), + .inst_vars_new = ht_up_new(NULL, (HtUPFreeValue)rz_pvector_free), .delta = delta }; if (ctx.inst_vars_new) { ht_up_foreach(fcn->inst_vars, inst_vars_relocate_cb, &ctx); // Do not free the elements of the Ht, because they were moved to ctx.inst_vars_new - fcn->inst_vars->opt.freefn = NULL; + fcn->inst_vars->opt.finiKV = NULL; ht_up_free(fcn->inst_vars); fcn->inst_vars = ctx.inst_vars_new; } @@ -273,7 +260,7 @@ RZ_API bool rz_analysis_function_relocate(RzAnalysisFunction *fcn, ut64 addr) { RZ_API bool rz_analysis_function_rename(RzAnalysisFunction *fcn, const char *name) { RzAnalysis *analysis = fcn->analysis; - RzAnalysisFunction *existing = ht_pp_find(analysis->ht_name_fun, name, NULL); + RzAnalysisFunction *existing = ht_sp_find(analysis->ht_name_fun, name, NULL); if (existing) { if (existing == fcn) { // fcn->name == name, nothing to do @@ -285,12 +272,12 @@ RZ_API bool rz_analysis_function_rename(RzAnalysisFunction *fcn, const char *nam if (!newname) { return false; } - bool in_tree = ht_pp_delete(analysis->ht_name_fun, fcn->name); + bool in_tree = ht_sp_delete(analysis->ht_name_fun, fcn->name); free(fcn->name); fcn->name = newname; if (in_tree) { // only re-insert if it really was in the tree before - ht_pp_insert(analysis->ht_name_fun, fcn->name, fcn); + ht_sp_insert(analysis->ht_name_fun, fcn->name, fcn); } return true; } diff --git a/librz/arch/hint.c b/librz/arch/hint.c index 100489793ff..06f7b31cdaa 100644 --- a/librz/arch/hint.c +++ b/librz/arch/hint.c @@ -54,10 +54,6 @@ static void addr_hint_record_fini(void *element, void *user) { } } -static void addr_hint_record_ht_free(HtUPKv *kv) { - rz_vector_free(kv->value); -} - static void bits_hint_record_free_rb(RBNode *node, void *user) { free(container_of(node, RzAnalysisRangedHintRecordBase, rb)); } @@ -70,7 +66,7 @@ static void arch_hint_record_free_rb(RBNode *node, void *user) { // used in analysis.c, but no API needed void rz_analysis_hint_storage_init(RzAnalysis *a) { - a->addr_hints = ht_up_new(NULL, addr_hint_record_ht_free, NULL); + a->addr_hints = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); a->arch_hints = NULL; a->bits_hints = NULL; } diff --git a/librz/arch/il/analysis_il_trace.c b/librz/arch/il/analysis_il_trace.c index 3e8993eca5e..ba5e2031d2c 100644 --- a/librz/arch/il/analysis_il_trace.c +++ b/librz/arch/il/analysis_il_trace.c @@ -11,10 +11,6 @@ * 4. reg.write name & data **/ -static void htup_vector_free(HtUPKv *kv) { - rz_vector_free(kv->value); -} - /** * Create a new trace to collect infos * \param analysis pointer to RzAnalysis @@ -30,12 +26,12 @@ RZ_API RzAnalysisRzilTrace *rz_analysis_rzil_trace_new(RzAnalysis *analysis, RZ_ } // TODO : maybe we could remove memory && register in rzil trace ? - trace->registers = ht_up_new(NULL, htup_vector_free, NULL); + trace->registers = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); if (!trace->registers) { RZ_LOG_ERROR("rzil: Cannot allocate hasmap for trace registers\n"); goto error; } - trace->memory = ht_up_new(NULL, htup_vector_free, NULL); + trace->memory = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); if (!trace->memory) { RZ_LOG_ERROR("rzil: Cannot allocate hasmap for trace memory\n"); goto error; diff --git a/librz/arch/isa/arm/arm_it.c b/librz/arch/isa/arm/arm_it.c index b708a7685f3..36169d30a3c 100644 --- a/librz/arch/isa/arm/arm_it.c +++ b/librz/arch/isa/arm/arm_it.c @@ -19,8 +19,8 @@ typedef union arm_cs_itcond_t { } ArmCSITCond; RZ_API void rz_arm_it_context_init(RzArmITContext *ctx) { - ctx->ht_itcond = ht_uu_new0(); - ctx->ht_itblock = ht_uu_new0(); + ctx->ht_itcond = ht_uu_new(); + ctx->ht_itblock = ht_uu_new(); } RZ_API void rz_arm_it_context_fini(RzArmITContext *ctx) { diff --git a/librz/arch/isa/tms320/tms320_dasm.c b/librz/arch/isa/tms320/tms320_dasm.c index 481d30188cf..ffb31dd7e10 100644 --- a/librz/arch/isa/tms320/tms320_dasm.c +++ b/librz/arch/isa/tms320/tms320_dasm.c @@ -1184,7 +1184,7 @@ int tms320_dasm_init(tms320_dasm_t *dasm) { return 0; } - dasm->map = ht_up_new0(); + dasm->map = ht_up_new(NULL, NULL); if (!dasm->map) { return 0; } diff --git a/librz/arch/labels.c b/librz/arch/labels.c index 5a322eb311d..7a72081169d 100644 --- a/librz/arch/labels.c +++ b/librz/arch/labels.c @@ -8,7 +8,7 @@ HEAPTYPE(ut64); RZ_API ut64 rz_analysis_function_get_label(RzAnalysisFunction *fcn, const char *name) { rz_return_val_if_fail(fcn, UT64_MAX); - ut64 *addr = ht_pp_find(fcn->label_addrs, name, NULL); + ut64 *addr = ht_sp_find(fcn->label_addrs, name, NULL); return addr ? *addr : UT64_MAX; } @@ -19,7 +19,7 @@ RZ_API const char *rz_analysis_function_get_label_at(RzAnalysisFunction *fcn, ut RZ_API bool rz_analysis_function_set_label(RzAnalysisFunction *fcn, const char *name, ut64 addr) { rz_return_val_if_fail(fcn && name, false); - if (ht_pp_find(fcn->label_addrs, name, NULL)) { + if (ht_sp_find(fcn->label_addrs, name, NULL)) { return false; } char *n = strdup(name); @@ -27,18 +27,18 @@ RZ_API bool rz_analysis_function_set_label(RzAnalysisFunction *fcn, const char * free(n); return false; } - ht_pp_insert(fcn->label_addrs, name, ut64_new(addr)); + ht_sp_insert(fcn->label_addrs, name, ut64_new(addr)); return true; } RZ_API bool rz_analysis_function_delete_label(RzAnalysisFunction *fcn, const char *name) { rz_return_val_if_fail(fcn && name, false); - ut64 *addr = ht_pp_find(fcn->label_addrs, name, NULL); + ut64 *addr = ht_sp_find(fcn->label_addrs, name, NULL); if (!addr) { return false; } ht_up_delete(fcn->labels, *addr); - ht_pp_delete(fcn->label_addrs, name); + ht_sp_delete(fcn->label_addrs, name); return true; } @@ -48,7 +48,7 @@ RZ_API bool rz_analysis_function_delete_label_at(RzAnalysisFunction *fcn, ut64 a if (!name) { return false; } - ht_pp_delete(fcn->label_addrs, name); + ht_sp_delete(fcn->label_addrs, name); ht_up_delete(fcn->labels, addr); return true; } diff --git a/librz/arch/platform_profile.c b/librz/arch/platform_profile.c index a6f7315524f..94f718d1221 100644 --- a/librz/arch/platform_profile.c +++ b/librz/arch/platform_profile.c @@ -19,10 +19,6 @@ RZ_API void rz_platform_profile_free(RzPlatformProfile *p) { free(p); } -static void free_mmio_kv(HtUPKv *kv) { - free(kv->value); -} - /** * \brief Creates a new RzPlatformProfile type */ @@ -31,12 +27,12 @@ RZ_API RZ_OWN RzPlatformProfile *rz_platform_profile_new() { if (!profile) { return NULL; } - profile->registers_mmio = ht_up_new((HtUPDupValue)strdup, free_mmio_kv, (HtUPCalcSizeV)strlen); + profile->registers_mmio = ht_up_new((HtUPDupValue)strdup, free); if (!profile->registers_mmio) { free(profile); return NULL; } - profile->registers_extended = ht_up_new((HtUPDupValue)strdup, free_mmio_kv, (HtUPCalcSizeV)strlen); + profile->registers_extended = ht_up_new((HtUPDupValue)strdup, free); if (!profile->registers_extended) { ht_up_free(profile->registers_mmio); free(profile); diff --git a/librz/arch/platform_target_index.c b/librz/arch/platform_target_index.c index 6714c230672..d6de9f07db9 100644 --- a/librz/arch/platform_target_index.c +++ b/librz/arch/platform_target_index.c @@ -25,7 +25,7 @@ RZ_API RZ_OWN RzPlatformTargetIndex *rz_platform_target_index_new() { if (!target) { return NULL; } - target->platforms = ht_up_new0(); + target->platforms = ht_up_new(NULL, NULL); if (!target->platforms) { free(target); return NULL; diff --git a/librz/arch/rtti_msvc.c b/librz/arch/rtti_msvc.c index cbd2367ffb4..35ccb7079f2 100644 --- a/librz/arch/rtti_msvc.c +++ b/librz/arch/rtti_msvc.c @@ -961,21 +961,17 @@ static const char *recovery_apply_type_descriptor(RRTTIMSVCAnalContext *context, return name; } -void str_value_free(HtUPKv *kv) { - free(kv->value); -} - RZ_API void rz_analysis_rtti_msvc_recover_all(RVTableContext *vt_context, RzList /**/ *vtables) { RRTTIMSVCAnalContext context; context.vt_context = vt_context; rz_pvector_init(&context.vtables, (RzPVectorFree)rz_analysis_vtable_info_free); rz_pvector_init(&context.complete_object_locators, (RzPVectorFree)recovery_complete_object_locator_free); - context.addr_col = ht_up_new0(); + context.addr_col = ht_up_new(NULL, NULL); rz_pvector_init(&context.type_descriptors, (RzPVectorFree)recovery_type_descriptor_free); - context.addr_td = ht_up_new0(); + context.addr_td = ht_up_new(NULL, NULL); - context.col_td_classes = ht_up_new(NULL, (HtUPKvFreeFunc)str_value_free, (HtUPCalcSizeV)strlen); + context.col_td_classes = ht_up_new(NULL, free); RzListIter *vtableIter; RVTableInfo *table; diff --git a/librz/arch/serialize_analysis.c b/librz/arch/serialize_analysis.c index 921aa44d403..fccae0721f4 100644 --- a/librz/arch/serialize_analysis.c +++ b/librz/arch/serialize_analysis.c @@ -1759,10 +1759,6 @@ typedef struct { bool bits_set; } HintsAtAddr; -static void hints_at_addr_kv_free(HtUPKv *kv) { - free(kv->value); -} - static HintsAtAddr *hints_at_addr(HtUP *acc, ut64 addr) { HintsAtAddr *h = ht_up_find(acc, addr, NULL); if (h) { @@ -1890,7 +1886,7 @@ static bool hints_acc_store_cb(void *user, const ut64 addr, const void *v) { } RZ_API void rz_serialize_analysis_hints_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis) { - HtUP /**/ *acc = ht_up_new(NULL, hints_at_addr_kv_free, NULL); + HtUP /**/ *acc = ht_up_new(NULL, free); rz_analysis_addr_hints_foreach(analysis, addr_hint_acc_cb, acc); rz_analysis_arch_hints_foreach(analysis, arch_hint_acc_cb, acc); rz_analysis_bits_hints_foreach(analysis, bits_hint_acc_cb, acc); diff --git a/librz/arch/var_global.c b/librz/arch/var_global.c index d9f813ab901..eaaf7527e96 100644 --- a/librz/arch/var_global.c +++ b/librz/arch/var_global.c @@ -63,7 +63,7 @@ RZ_API bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalys RZ_LOG_ERROR("Global variable %s at 0x%" PFMT64x " already exists!\n", existing_glob->name, existing_glob->addr); return false; } - if (!ht_pp_insert(analysis->ht_global_var, global_var->name, global_var)) { + if (!ht_sp_insert(analysis->ht_global_var, global_var->name, global_var)) { return false; } if (!rz_rbtree_aug_insert(&analysis->global_var_tree, &global_var->addr, &global_var->rb, global_var_node_cmp, NULL, NULL)) { @@ -158,7 +158,7 @@ RZ_API bool rz_analysis_var_global_delete(RZ_NONNULL RzAnalysis *analysis, RZ_NO // We need to delete RBTree first because ht_pp_delete will free its member bool deleted = rz_rbtree_delete(&analysis->global_var_tree, &glob->addr, global_var_node_cmp, NULL, NULL, NULL); - return deleted ? ht_pp_delete(analysis->ht_global_var, glob->name) : deleted; + return deleted ? ht_sp_delete(analysis->ht_global_var, glob->name) : deleted; } /** @@ -224,7 +224,7 @@ RZ_API bool rz_analysis_var_global_delete_byaddr_in(RzAnalysis *analysis, ut64 a */ RZ_API RZ_BORROW RzAnalysisVarGlobal *rz_analysis_var_global_get_byname(RzAnalysis *analysis, RZ_NONNULL const char *name) { rz_return_val_if_fail(analysis && name, NULL); - return (RzAnalysisVarGlobal *)ht_pp_find(analysis->ht_global_var, name, NULL); + return (RzAnalysisVarGlobal *)ht_sp_find(analysis->ht_global_var, name, NULL); } struct list_addr { @@ -278,7 +278,7 @@ RZ_API RZ_BORROW RzAnalysisVarGlobal *rz_analysis_var_global_get_byaddr_in(RzAna return var; } -static bool global_var_collect_cb(void *user, const void *k, const void *v) { +static bool global_var_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { RzList *l = user; RzAnalysisVarGlobal *glob = (RzAnalysisVarGlobal *)v; rz_list_append(l, glob); @@ -297,7 +297,7 @@ RZ_API RZ_OWN RzList /**/ *rz_analysis_var_global_get_all if (!globals) { return NULL; } - ht_pp_foreach(analysis->ht_global_var, global_var_collect_cb, globals); + ht_sp_foreach(analysis->ht_global_var, global_var_collect_cb, globals); return globals; } @@ -324,7 +324,7 @@ RZ_API bool rz_analysis_var_global_rename(RzAnalysis *analysis, RZ_NONNULL const RZ_FREE(glob->name); glob->name = strdup(newname); - return ht_pp_update_key(analysis->ht_global_var, old_name, newname); + return ht_sp_update_key(analysis->ht_global_var, old_name, newname); } /** diff --git a/librz/arch/xrefs.c b/librz/arch/xrefs.c index 4f38bd2ac20..c6a008a7004 100644 --- a/librz/arch/xrefs.c +++ b/librz/arch/xrefs.c @@ -38,14 +38,6 @@ RZ_API RZ_OWN RzList /**/ *rz_analysis_xref_list_new() { return rz_list_newf((RzListFree)free); } -static void xrefs_ht_free(HtUPKv *kv) { - ht_up_free(kv->value); -} - -static void xrefs_ref_free(HtUPKv *kv) { - rz_analysis_xref_free(kv->value); -} - static bool appendRef(void *u, const ut64 k, const void *v) { RzList *list = (RzList *)u; RzAnalysisXRef *xref = (RzAnalysisXRef *)v; @@ -99,8 +91,8 @@ static bool set_xref(HtUP *m, RzAnalysisXRef *xref, bool from2to) { HtUP *ht = ht_up_find(m, key1, NULL); if (!ht) { // RzAnalysis::ht_xrefs_to is responsible for releasing of pointers. - HtUPKvFreeFunc cb = from2to ? NULL : xrefs_ref_free; - ht = ht_up_new(NULL, cb, NULL); + HtUPFreeValue cb = from2to ? NULL : (HtUPFreeValue)rz_analysis_xref_free; + ht = ht_up_new(NULL, cb); if (!ht) { return false; } @@ -247,13 +239,13 @@ RZ_API bool rz_analysis_xrefs_init(RzAnalysis *analysis) { ht_up_free(analysis->ht_xrefs_to); analysis->ht_xrefs_to = NULL; - HtUP *tmp = ht_up_new(NULL, xrefs_ht_free, NULL); + HtUP *tmp = ht_up_new(NULL, (HtUPFreeValue)ht_up_free); if (!tmp) { return false; } analysis->ht_xrefs_from = tmp; - tmp = ht_up_new(NULL, xrefs_ht_free, NULL); + tmp = ht_up_new(NULL, (HtUPFreeValue)ht_up_free); if (!tmp) { ht_up_free(analysis->ht_xrefs_from); analysis->ht_xrefs_from = NULL; diff --git a/librz/bin/bfile_string.c b/librz/bin/bfile_string.c index 198c0a27275..8b16de205db 100644 --- a/librz/bin/bfile_string.c +++ b/librz/bin/bfile_string.c @@ -361,7 +361,7 @@ RZ_API RZ_OWN RzPVector /**/ *rz_bin_file_strings(RZ_NONNULL RzBi goto fail; } - strings_db = ht_up_new0(); + strings_db = ht_up_new(NULL, NULL); if (!strings_db) { RZ_LOG_ERROR("bin_file_strings: cannot allocate string map.\n"); goto fail; diff --git a/librz/bin/bobj.c b/librz/bin/bobj.c index 4a22da80917..e4b7b339501 100644 --- a/librz/bin/bobj.c +++ b/librz/bin/bobj.c @@ -184,10 +184,10 @@ RZ_IPI void rz_bin_object_free(RzBinObject *o) { return; } free(o->regstate); - ht_pp_free(o->glue_to_class_field); - ht_pp_free(o->glue_to_class_method); - ht_pp_free(o->name_to_class_object); - ht_pp_free(o->import_name_symbols); + ht_sp_free(o->glue_to_class_field); + ht_sp_free(o->glue_to_class_method); + ht_sp_free(o->name_to_class_object); + ht_sp_free(o->import_name_symbols); ht_up_free(o->vaddr_to_class_method); rz_bin_info_free(o->info); rz_bin_reloc_storage_free(o->relocs); @@ -220,7 +220,7 @@ RZ_IPI void rz_bin_object_free(RzBinObject *o) { */ RZ_API RZ_BORROW RzBinClass *rz_bin_object_find_class(RZ_NONNULL RzBinObject *o, RZ_NONNULL const char *name) { rz_return_val_if_fail(o && name, NULL); - return ht_pp_find(o->name_to_class_object, name, NULL); + return ht_sp_find(o->name_to_class_object, name, NULL); } static RzBinClass *bin_class_new(RzBinObject *o, const char *name, const char *super, ut64 address) { @@ -298,7 +298,7 @@ static int bin_compare_class_field(RzBinClassField *a, RzBinClassField *b, void RZ_API RZ_BORROW RzBinClass *rz_bin_object_add_class(RZ_NONNULL RzBinObject *o, RZ_NONNULL const char *name, RZ_NULLABLE const char *super, ut64 vaddr) { rz_return_val_if_fail(o && RZ_STR_ISNOTEMPTY(name), NULL); - RzBinClass *oclass = ht_pp_find(o->name_to_class_object, name, NULL); + RzBinClass *oclass = ht_sp_find(o->name_to_class_object, name, NULL); if (oclass) { if (super && !oclass->super) { oclass->super = strdup(super); @@ -316,7 +316,7 @@ RZ_API RZ_BORROW RzBinClass *rz_bin_object_add_class(RZ_NONNULL RzBinObject *o, rz_pvector_push(o->classes, oclass); rz_pvector_sort(o->classes, (RzPVectorComparator)bin_compare_class, NULL); - ht_pp_insert(o->name_to_class_object, name, oclass); + ht_sp_insert(o->name_to_class_object, name, oclass); return oclass; } @@ -336,7 +336,7 @@ RZ_API RzBinSymbol *rz_bin_object_find_method(RZ_NONNULL RzBinObject *o, RZ_NONN if (!key) { return NULL; } - RzBinSymbol *sym = (RzBinSymbol *)ht_pp_find(o->glue_to_class_method, key, NULL); + RzBinSymbol *sym = (RzBinSymbol *)ht_sp_find(o->glue_to_class_method, key, NULL); free(key); return sym; } @@ -401,7 +401,7 @@ RZ_API RZ_BORROW RzBinSymbol *rz_bin_object_add_method(RZ_NONNULL RzBinObject *o char *key = rz_str_newf(RZ_BIN_FMT_CLASS_HT_GLUE, klass, method); if (key) { - ht_pp_insert(o->glue_to_class_method, key, symbol); + ht_sp_insert(o->glue_to_class_method, key, symbol); free(key); } @@ -428,7 +428,7 @@ RZ_API RzBinClassField *rz_bin_object_find_field(RZ_NONNULL RzBinObject *o, RZ_N if (!key) { return NULL; } - RzBinClassField *sym = (RzBinClassField *)ht_pp_find(o->glue_to_class_field, key, NULL); + RzBinClassField *sym = (RzBinClassField *)ht_sp_find(o->glue_to_class_field, key, NULL); free(key); return sym; } @@ -478,7 +478,7 @@ RZ_API RZ_BORROW RzBinClassField *rz_bin_object_add_field(RZ_NONNULL RzBinObject rz_list_add_sorted(c->fields, field, (RzListComparator)bin_compare_class_field, NULL); char *key = rz_str_newf(RZ_BIN_FMT_CLASS_HT_GLUE, klass, name); if (key) { - ht_pp_insert(o->glue_to_class_field, key, field); + ht_sp_insert(o->glue_to_class_field, key, field); free(key); } return field; @@ -569,7 +569,7 @@ RZ_API RzBinSymbol *rz_bin_object_get_symbol_of_import(RzBinObject *o, RzBinImpo if (!o->import_name_symbols) { return NULL; } - return ht_pp_find(o->import_name_symbols, imp->name, NULL); + return ht_sp_find(o->import_name_symbols, imp->name, NULL); } RZ_API RzBinVirtualFile *rz_bin_object_get_virtual_file(RzBinObject *o, const char *name) { @@ -977,8 +977,8 @@ RZ_API RZ_OWN RzBinStrDb *rz_bin_string_database_new(RZ_NULLABLE RZ_OWN RzPVecto } db->pvec = pvector ? pvector : rz_pvector_new((RzPVectorFree)rz_bin_string_free); - db->phys = ht_up_new0(); - db->virt = ht_up_new0(); + db->phys = ht_up_new(NULL, NULL); + db->virt = ht_up_new(NULL, NULL); if (!db->pvec || !db->phys || !db->virt) { RZ_LOG_ERROR("rz_bin: Cannot allocate RzBinStrDb internal data structure.\n"); goto fail; diff --git a/librz/bin/bobj_process_class.c b/librz/bin/bobj_process_class.c index 85046964fb4..e98e633a1ba 100644 --- a/librz/bin/bobj_process_class.c +++ b/librz/bin/bobj_process_class.c @@ -14,7 +14,7 @@ static void process_class_method(RzBinObject *o, RzBinSymbol *method) { return; } - ht_pp_insert(o->glue_to_class_method, key, method); + ht_sp_insert(o->glue_to_class_method, key, method); free(key); ht_up_insert(o->vaddr_to_class_method, method->vaddr, method); @@ -30,7 +30,7 @@ static void process_class_field(RzBinObject *o, RzBinClassField *field) { return; } - ht_pp_insert(o->glue_to_class_field, key, field); + ht_sp_insert(o->glue_to_class_field, key, field); free(key); } @@ -46,9 +46,9 @@ static void process_handle_class(RzBinObject *o, RzBinClass *klass) { if (!klass->name) { klass->name = rz_str_dup("unknown_class"); } - RzBinClass *found = ht_pp_find(o->name_to_class_object, klass->name, NULL); + RzBinClass *found = ht_sp_find(o->name_to_class_object, klass->name, NULL); if (!found) { - ht_pp_insert(o->name_to_class_object, klass->name, klass); + ht_sp_insert(o->name_to_class_object, klass->name, klass); found = klass; } else { RZ_LOG_WARN("Found duplicated class: %s\n", klass->name); @@ -80,15 +80,15 @@ RZ_IPI void rz_bin_set_and_process_classes(RzBinFile *bf, RzBinObject *o) { } rz_warn_if_fail(o->classes->v.free_user); - ht_pp_free(o->name_to_class_object); - ht_pp_free(o->glue_to_class_method); - ht_pp_free(o->glue_to_class_field); + ht_sp_free(o->name_to_class_object); + ht_sp_free(o->glue_to_class_method); + ht_sp_free(o->glue_to_class_field); ht_up_free(o->vaddr_to_class_method); - o->name_to_class_object = ht_pp_new0(); - o->glue_to_class_method = ht_pp_new0(); - o->glue_to_class_field = ht_pp_new0(); - o->vaddr_to_class_method = ht_up_new0(); + o->name_to_class_object = ht_sp_new(HT_STR_DUP, NULL, NULL); + o->glue_to_class_method = ht_sp_new(HT_STR_DUP, NULL, NULL); + o->glue_to_class_field = ht_sp_new(HT_STR_DUP, NULL, NULL); + o->vaddr_to_class_method = ht_up_new(NULL, NULL); void **it; RzBinClass *element; diff --git a/librz/bin/bobj_process_section.c b/librz/bin/bobj_process_section.c index 99b2e90ed55..023919c5ff5 100644 --- a/librz/bin/bobj_process_section.c +++ b/librz/bin/bobj_process_section.c @@ -4,7 +4,7 @@ #include #include "i/private.h" -static void process_handle_section(RzBinSection *section, RzBinObject *o, HtPP *filter_db) { +static void process_handle_section(RzBinSection *section, RzBinObject *o, HtSP *filter_db) { // rebase physical address section->paddr += o->opts.loadaddr; @@ -14,8 +14,8 @@ static void process_handle_section(RzBinSection *section, RzBinObject *o, HtPP * } // check if section name was already found, then rename it. - if (!ht_pp_find(filter_db, section->name, NULL)) { - ht_pp_insert(filter_db, section->name, section); + if (!ht_sp_find(filter_db, section->name, NULL)) { + ht_sp_insert(filter_db, section->name, section); return; } @@ -33,7 +33,7 @@ RZ_IPI void rz_bin_set_and_process_sections(RzBinFile *bf, RzBinObject *o) { o->sections = rz_pvector_new((RzPVectorFree)rz_bin_section_free); } - HtPP *filter_db = bin->filter ? ht_pp_new0() : NULL; + HtSP *filter_db = bin->filter ? ht_sp_new(HT_STR_DUP, NULL, NULL) : NULL; void **it; RzBinSection *element; @@ -42,5 +42,5 @@ RZ_IPI void rz_bin_set_and_process_sections(RzBinFile *bf, RzBinObject *o) { process_handle_section(element, o, filter_db); } - ht_pp_free(filter_db); + ht_sp_free(filter_db); } diff --git a/librz/bin/bobj_process_symbol.c b/librz/bin/bobj_process_symbol.c index 619a16d86f5..1f17cadc956 100644 --- a/librz/bin/bobj_process_symbol.c +++ b/librz/bin/bobj_process_symbol.c @@ -72,8 +72,8 @@ static void process_handle_symbol(RzBinSymbol *symbol, RzBinObject *o, const RzD // add symbol to the 'import' map[name]symbol if (symbol->is_imported && RZ_STR_ISNOTEMPTY(symbol->name)) { - if (!ht_pp_find(o->import_name_symbols, symbol->name, NULL)) { - ht_pp_insert(o->import_name_symbols, symbol->name, symbol); + if (!ht_sp_find(o->import_name_symbols, symbol->name, NULL)) { + ht_sp_insert(o->import_name_symbols, symbol->name, symbol); } } @@ -94,8 +94,8 @@ RZ_IPI void rz_bin_process_symbols(RzBinFile *bf, RzBinObject *o, const RzDemang return; } - ht_pp_free(o->import_name_symbols); - o->import_name_symbols = ht_pp_new0(); + ht_sp_free(o->import_name_symbols); + o->import_name_symbols = ht_sp_new(HT_STR_DUP, NULL, NULL); RzBinProcessLanguage language_cb = rz_bin_process_language_symbol(o); diff --git a/librz/bin/dbginfo.c b/librz/bin/dbginfo.c index 10abdef9f9f..8b3fda435dd 100644 --- a/librz/bin/dbginfo.c +++ b/librz/bin/dbginfo.c @@ -277,7 +277,7 @@ static const char *read_line(const char *file, int line, RzBinSourceLineCache *c bool found = false; char *content = NULL; size_t sz = 0; - RzBinSourceLineCacheItem *item = ht_pp_find(cache->items, file, &found); + RzBinSourceLineCacheItem *item = ht_sp_find(cache->items, file, &found); if (found) { if (!(item && item->file_content)) { return NULL; @@ -287,7 +287,7 @@ static const char *read_line(const char *file, int line, RzBinSourceLineCache *c } else { content = rz_file_slurp(file, &sz); if (!content) { - ht_pp_insert(cache->items, file, NULL); + ht_sp_insert(cache->items, file, NULL); return NULL; } item = RZ_NEW0(RzBinSourceLineCacheItem); @@ -300,7 +300,7 @@ static const char *read_line(const char *file, int line, RzBinSourceLineCache *c if (!item->line_by_ln) { goto err; } - ht_pp_update(cache->items, file, item); + ht_sp_update(cache->items, file, item); rz_pvector_reserve(item->line_by_ln, line); cache_lines(item); diff --git a/librz/bin/dwarf/abbrev.c b/librz/bin/dwarf/abbrev.c index e94e4497642..03ed28b7c81 100644 --- a/librz/bin/dwarf/abbrev.c +++ b/librz/bin/dwarf/abbrev.c @@ -35,13 +35,6 @@ static void RzBinDwarfAbbrevTable_free(RzBinDwarfAbbrevTable *table) { free(table); } -static void htup_RzBinDwarfAbbrevTable_free(HtUPKv *kv) { - if (!kv) { - return; - } - RzBinDwarfAbbrevTable_free(kv->value); -} - static void RzBinDwarfAbbrevs_fini(RzBinDwarfAbbrev *abbrevs) { ht_up_free(abbrevs->by_offset); R_free(abbrevs->R); @@ -51,7 +44,7 @@ static bool RzBinDwarfAbbrevs_init(RzBinDwarfAbbrev *abbrevs) { if (!abbrevs) { return false; } - abbrevs->by_offset = ht_up_new(NULL, htup_RzBinDwarfAbbrevTable_free, NULL); + abbrevs->by_offset = ht_up_new(NULL, (HtUPFreeValue)RzBinDwarfAbbrevTable_free); if (!abbrevs->by_offset) { goto beach; } diff --git a/librz/bin/dwarf/endian_reader.c b/librz/bin/dwarf/endian_reader.c index 16c323b0620..ff145d584c2 100644 --- a/librz/bin/dwarf/endian_reader.c +++ b/librz/bin/dwarf/endian_reader.c @@ -146,7 +146,7 @@ RZ_IPI RzBinEndianReader *RzBinEndianReader_from_file(RzBinFile *binfile, const RzBinEndianReader *R = rz_bin_dwarf_section_reader(binfile, section); OK_OR(R, return NULL); - HtUP *relocations = ht_up_new0(); + HtUP *relocations = ht_up_new(NULL, NULL); OK_OR(relocations, R_free(R); return NULL); add_relocations(binfile, relocations, section); @@ -155,6 +155,10 @@ RZ_IPI RzBinEndianReader *RzBinEndianReader_from_file(RzBinFile *binfile, const } RZ_IPI ut64 R_relocate(RzBinEndianReader *R, ut64 offset, ut64 value) { + rz_return_val_if_fail(R, value); + if (!R->relocations) { + return value; + } const RzBinReloc *reloc = ht_up_find(R->relocations, offset, NULL); if (reloc) { RZ_LOG_DEBUG("Relocating 0x%" PFMT64x "\n", offset); diff --git a/librz/bin/dwarf/loclists.c b/librz/bin/dwarf/loclists.c index 0a72318fec0..57157fae8bd 100644 --- a/librz/bin/dwarf/loclists.c +++ b/librz/bin/dwarf/loclists.c @@ -300,8 +300,6 @@ RZ_API RzBinDwarfLocList *rz_bin_dwarf_loclists_get( return NULL; } -Ht_FREE_IMPL(UP, LocList, LocList_free); - /** * \brief Create a new RzBinDwarfLocListTable instance, * takes ownership of the buffers, and any of them must be non-NULL @@ -316,7 +314,7 @@ RZ_API RZ_OWN RzBinDwarfLocLists *rz_bin_dwarf_loclists_new(RzBinEndianReader *l RET_NULL_IF_FAIL(self); self->loclists = loclists; self->loc = loc; - self->by_offset = ht_up_new(NULL, HtUP_LocList_free, NULL); + self->by_offset = ht_up_new(NULL, (HtUPFreeValue)LocList_free); return self; } diff --git a/librz/bin/dwarf/macro.h b/librz/bin/dwarf/macro.h index 8b3b9e149c7..3cb3187a7de 100644 --- a/librz/bin/dwarf/macro.h +++ b/librz/bin/dwarf/macro.h @@ -50,7 +50,7 @@ #define SLE128_OR_GOTO(out, label) SLE128_OR(st64, out, goto label) #define Ht_FREE_IMPL(V, T, f) \ - static void Ht##V##_##T##_free(Ht##V##Kv *kv) { \ + static void Ht##V##_##T##_free(Ht##V##Kv *kv, RZ_UNUSED void *user) { \ f(kv->value); \ } diff --git a/librz/bin/dwarf/rnglists.c b/librz/bin/dwarf/rnglists.c index 84fc7ed98fb..19fc6ae0382 100644 --- a/librz/bin/dwarf/rnglists.c +++ b/librz/bin/dwarf/rnglists.c @@ -112,8 +112,6 @@ static void RngList_free(RzBinDwarfRngList *self) { free(self); } -Ht_FREE_IMPL(UP, RngList, RngList_free); - RZ_IPI void RngLists_free(RzBinDwarfRngLists *self) { if (!self) { return; @@ -278,7 +276,7 @@ RZ_API RZ_OWN RzBinDwarfRngLists *rz_bin_dwarf_rnglists_new( RET_NULL_IF_FAIL(self); self->rnglists = rnglists; self->ranges = ranges; - self->by_offset = ht_up_new(NULL, HtUP_RngList_free, NULL); + self->by_offset = ht_up_new(NULL, (HtUPFreeValue)RngList_free); return self; } diff --git a/librz/bin/dwarf/unit.c b/librz/bin/dwarf/unit.c index 6686c552969..50e528253ed 100644 --- a/librz/bin/dwarf/unit.c +++ b/librz/bin/dwarf/unit.c @@ -314,8 +314,8 @@ RZ_API RZ_BORROW RzBinDwarfAttr *rz_bin_dwarf_die_get_attr( static bool info_init(RzBinDwarfInfo *info) { rz_vector_init(&info->units, sizeof(RzBinDwarfCompUnit), (RzVectorFree)CU_fini, NULL); - info->offset_comp_dir = ht_up_new(NULL, NULL, NULL); - info->location_encoding = ht_up_new0(); + info->offset_comp_dir = ht_up_new(NULL, NULL); + info->location_encoding = ht_up_new(NULL, NULL); if (!info->offset_comp_dir) { goto beach; } @@ -361,9 +361,9 @@ RZ_API RZ_OWN RzBinDwarfInfo *rz_bin_dwarf_info_from_buf( }; ERR_IF_FAIL(CU_parse_all(&ctx)); - info->die_by_offset = ht_up_new_size(info->die_count, NULL, NULL, NULL); + info->die_by_offset = ht_up_new_size(info->die_count, NULL, NULL); ERR_IF_FAIL(info->die_by_offset); - info->unit_by_offset = ht_up_new_size(rz_vector_len(&info->units), NULL, NULL, NULL); + info->unit_by_offset = ht_up_new_size(rz_vector_len(&info->units), NULL, NULL); ERR_IF_FAIL(info->unit_by_offset); // build hashtable after whole parsing because of possible relocations diff --git a/librz/bin/format/coff/coff.c b/librz/bin/format/coff/coff.c index f2869196f6c..5c9887b1654 100644 --- a/librz/bin/format/coff/coff.c +++ b/librz/bin/format/coff/coff.c @@ -240,9 +240,9 @@ static int rz_bin_coff_init(struct rz_bin_coff_obj *obj, RzBuffer *buf, bool ver obj->b = rz_buf_ref(buf); obj->size = rz_buf_size(buf); obj->verbose = verbose; - obj->sym_ht = ht_up_new0(); - obj->imp_ht = ht_up_new0(); - obj->imp_index = ht_uu_new0(); + obj->sym_ht = ht_up_new(NULL, NULL); + obj->imp_ht = ht_up_new(NULL, NULL); + obj->imp_index = ht_uu_new(); if (!rz_bin_coff_init_hdr(obj)) { RZ_LOG_ERROR("failed to init hdr\n"); return false; diff --git a/librz/bin/format/elf/elf_dynamic.c b/librz/bin/format/elf/elf_dynamic.c index bde5ec82211..1a4eb7248ac 100644 --- a/librz/bin/format/elf/elf_dynamic.c +++ b/librz/bin/format/elf/elf_dynamic.c @@ -101,7 +101,7 @@ RZ_OWN RzBinElfDtDynamic *Elf_(rz_bin_elf_dt_dynamic_new)(RZ_NONNULL ELFOBJ *bin return NULL; } - result->info = ht_uu_new0(); + result->info = ht_uu_new(); if (!result->info) { Elf_(rz_bin_elf_dt_dynamic_free)(result); return NULL; diff --git a/librz/bin/format/elf/elf_relocs.c b/librz/bin/format/elf/elf_relocs.c index a9da79e7b0c..68bbba0f43a 100644 --- a/librz/bin/format/elf/elf_relocs.c +++ b/librz/bin/format/elf/elf_relocs.c @@ -206,7 +206,7 @@ static bool get_relocs_entry_from_sections(ELFOBJ *bin, RzVector /**/ *Elf_(rz_bin_elf_relocs_new)(RZ_NONNULL ELFOBJ *bin) { rz_return_val_if_fail(bin, NULL); - HtUU *set = ht_uu_new0(); + HtUU *set = ht_uu_new(); if (!set) { return NULL; } diff --git a/librz/bin/format/elf/elf_symbols.c b/librz/bin/format/elf/elf_symbols.c index d999c066169..77dc5facc4c 100644 --- a/librz/bin/format/elf/elf_symbols.c +++ b/librz/bin/format/elf/elf_symbols.c @@ -400,19 +400,19 @@ static bool get_gnu_debugdata_elf_symbols(ELFOBJ *bin, RzVector /*name, sym); + ht_sp_insert(name_set, sym->name, sym); } rz_vector_foreach(debug_symbols, sym) { bool found; - ht_pp_find(name_set, sym->name, &found); + ht_sp_find(name_set, sym->name, &found); if (found) { continue; } @@ -423,7 +423,7 @@ static bool get_gnu_debugdata_elf_symbols(ELFOBJ *bin, RzVector /*len = 0; res = true; - ht_pp_free(name_set); + ht_sp_free(name_set); debug_symbols_err: rz_vector_free(debug_symbols); debug_data_err: @@ -488,7 +488,7 @@ RZ_OWN RzVector /**/ *Elf_(rz_bin_elf_compute_symbols)(ELFOBJ *b return NULL; } - HtUU *set = ht_uu_new0(); + HtUU *set = ht_uu_new(); if (!set) { rz_vector_free(result); return NULL; diff --git a/librz/bin/format/le/le.c b/librz/bin/format/le/le.c index 0eb2ae78823..d2f55389025 100644 --- a/librz/bin/format/le/le.c +++ b/librz/bin/format/le/le.c @@ -191,7 +191,7 @@ static int le_import_cmp(LE_import *a, LE_import *b) { return rz_str_cmp(a->proc_name, b->proc_name, -1); } -static void le_free_import_kv(HtPPKv *kv) { +static void le_fini_import_kv(HtPPKv *kv) { le_import_free(kv->key); } @@ -261,8 +261,8 @@ static RZ_BORROW LE_import *le_add_import(rz_bin_le_obj_t *bin, if (!bin->le_import_ht) { HtPPOptions opt = { - .freefn = (HtPPKvFreeFunc)le_free_import_kv, - .cmp = (HtPPListComparator)le_import_cmp, + .finiKV = (HtPPFiniKv)le_fini_import_kv, + .cmp = (HtPPComparator)le_import_cmp, .hashfn = (HtPPHashFunction)le_import_hash, }; CHECK(bin->le_import_ht = ht_pp_new_opt(&opt)); diff --git a/librz/bin/format/mach0/dyldcache.c b/librz/bin/format/mach0/dyldcache.c index 9362483b964..8b1ec43ef1f 100644 --- a/librz/bin/format/mach0/dyldcache.c +++ b/librz/bin/format/mach0/dyldcache.c @@ -563,8 +563,8 @@ static int string_contains(const void *a, const void *b, void *user) { return !strstr((const char *)a, (const char *)b); } -static HtPU *create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, RzDyldCacheHeader *hdr) { - HtPU *path_to_idx = ht_pu_new0(); +static HtSU *create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, RzDyldCacheHeader *hdr) { + HtSU *path_to_idx = ht_su_new(HT_STR_DUP); if (!path_to_idx) { return NULL; } @@ -574,13 +574,13 @@ static HtPU *create_path_to_index(RzBuffer *cache_buf, cache_img_t *img, RzDyldC continue; } file[255] = 0; - ht_pu_insert(path_to_idx, file, (ut64)i); + ht_su_insert(path_to_idx, file, (ut64)i); } return path_to_idx; } -static void carve_deps_at_address(RzDyldCache *cache, cache_img_t *img, HtPU *path_to_idx, ut64 address, int *deps, bool printing) { +static void carve_deps_at_address(RzDyldCache *cache, cache_img_t *img, HtSU *path_to_idx, ut64 address, int *deps, bool printing) { ut64 pa = va2pa(address, cache->n_maps, cache->maps, cache->buf, 0, NULL, NULL); if (pa == UT64_MAX) { return; @@ -612,7 +612,7 @@ static void carve_deps_at_address(RzDyldCache *cache, cache_img_t *img, HtPU *pa break; } const char *key = (const char *)cursor + 24; - size_t dep_index = (size_t)ht_pu_find(path_to_idx, key, &found); + size_t dep_index = (size_t)ht_su_find(path_to_idx, key, &found); if (!found || dep_index >= cache->hdr->imagesCount) { RZ_LOG_WARN("alien dep '%s'\n", key); continue; @@ -667,7 +667,7 @@ static RzList /**/ *create_cache_bins(RzDyldCache *cache) { } if (target_libs) { - HtPU *path_to_idx = NULL; + HtSU *path_to_idx = NULL; size_t dep_array_count = 0; if (cache->accel) { dep_array_count = cache->accel->depListCount; @@ -737,7 +737,7 @@ static RzList /**/ *create_cache_bins(RzDyldCache *cache) { } } - ht_pu_free(path_to_idx); + ht_su_free(path_to_idx); RZ_FREE(dep_array); RZ_FREE(extras); } diff --git a/librz/bin/format/mach0/mach0.c b/librz/bin/format/mach0/mach0.c index 1d033a8e70e..c190ed492d1 100644 --- a/librz/bin/format/mach0/mach0.c +++ b/librz/bin/format/mach0/mach0.c @@ -23,7 +23,7 @@ typedef struct { struct symbol_t *symbols; int j; int symbols_count; - HtPP *hash; + HtSP *hash; } RSymCtx; typedef void (*RExportsIterator)(struct MACH0_(obj_t) * bin, const char *name, ut64 flags, ut64 offset, void *ctx); @@ -2294,15 +2294,15 @@ static bool parse_import_stub(struct MACH0_(obj_t) * bin, struct symbol_t *symbo return false; } -static int inSymtab(HtPP *hash, const char *name, ut64 addr) { +static int inSymtab(HtSP *hash, const char *name, ut64 addr) { bool found = false; char *key = rz_str_newf("%" PFMT64x ".%s", addr, name); - ht_pp_find(hash, key, &found); + ht_sp_find(hash, key, &found); if (found) { free(key); return true; } - ht_pp_insert(hash, key, "1"); + ht_sp_insert(hash, key, "1"); free(key); return false; } @@ -2521,7 +2521,7 @@ const struct symbol_t *MACH0_(get_symbols)(struct MACH0_(obj_t) * bin) { return bin->symbols; } - HtPP *hash = ht_pp_new0(); + HtSP *hash = ht_sp_new(HT_STR_DUP, NULL, NULL); if (!hash) { return NULL; } @@ -2541,13 +2541,13 @@ const struct symbol_t *MACH0_(get_symbols)(struct MACH0_(obj_t) * bin) { symbols_count += (bin->nsymtab + 1); if (SZT_MUL_OVFCHK(symbols_count, 2)) { RZ_LOG_ERROR("mach0: detected symbols count overflow\n"); - ht_pp_free(hash); + ht_sp_free(hash); return NULL; } symbols_size = symbols_count * 2; symbols = RZ_NEWS0(struct symbol_t, symbols_size); if (!symbols) { - ht_pp_free(hash); + ht_sp_free(hash); return NULL; } bin->main_addr = 0; @@ -2667,16 +2667,16 @@ const struct symbol_t *MACH0_(get_symbols)(struct MACH0_(obj_t) * bin) { } } } else if (!n_exports) { - ht_pp_free(hash); + ht_sp_free(hash); return NULL; } else { if (SZT_ADD_OVFCHK(symbols_count, 1)) { - ht_pp_free(hash); + ht_sp_free(hash); return NULL; } symbols_size = symbols_count + 1; if (!(symbols = RZ_NEWS0(struct symbol_t, symbols_size))) { - ht_pp_free(hash); + ht_sp_free(hash); return NULL; } } @@ -2689,7 +2689,7 @@ const struct symbol_t *MACH0_(get_symbols)(struct MACH0_(obj_t) * bin) { walk_exports(bin, assign_export_symbol_t, &sym_ctx); j = sym_ctx.j; } - ht_pp_free(hash); + ht_sp_free(hash); symbols[j].last = true; bin->symbols = symbols; return symbols; diff --git a/librz/bin/format/pe/pe_info.c b/librz/bin/format/pe/pe_info.c index 60091a421b4..dd06a0342ff 100644 --- a/librz/bin/format/pe/pe_info.c +++ b/librz/bin/format/pe/pe_info.c @@ -396,7 +396,7 @@ struct rz_bin_pe_lib_t *PE_(rz_bin_pe_get_libs)(RzBinPEObj *bin) { PE_(image_delay_import_directory) curr_delay_import_dir; PE_DWord name_off = 0; - HtPP *lib_map = NULL; + HtSS *lib_map = NULL; ut64 off; // cache value int index = 0; int len = 0; diff --git a/librz/bin/p/bin_symbols.c b/librz/bin/p/bin_symbols.c index 54120c1f2fb..9bcac044a02 100644 --- a/librz/bin/p/bin_symbols.c +++ b/librz/bin/p/bin_symbols.c @@ -358,7 +358,7 @@ static RzPVector /**/ *symbols(RzBinFile *bf) { rz_return_val_if_fail(res && bf->o && bf->o->bin_obj, res); RzCoreSymCacheElement *element = bf->o->bin_obj; size_t i; - HtUU *hash = ht_uu_new0(); + HtUU *hash = ht_uu_new(); if (!hash) { return res; } diff --git a/librz/bin/p/bin_xnu_kernelcache.c b/librz/bin/p/bin_xnu_kernelcache.c index d86d100d394..11662f96edd 100644 --- a/librz/bin/p/bin_xnu_kernelcache.c +++ b/librz/bin/p/bin_xnu_kernelcache.c @@ -104,7 +104,7 @@ static void handle_data_sections(RzBinSection *sect); static void symbols_from_mach0(RzPVector /**/ *ret, struct MACH0_(obj_t) * mach0, RzBinFile *bf, ut64 paddr, int ordinal); static RzList /**/ *resolve_syscalls(RzXNUKernelCacheObj *obj, ut64 enosys_addr); static RzList /**/ *resolve_mig_subsystem(RzXNUKernelCacheObj *obj); -static void symbols_from_stubs(RzPVector /**/ *ret, HtPP *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal); +static void symbols_from_stubs(RzPVector /**/ *ret, HtSS *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal); static RStubsInfo *get_stubs_info(struct MACH0_(obj_t) * mach0, ut64 paddr, RzXNUKernelCacheObj *obj); static int prot2perm(int x); @@ -1177,7 +1177,7 @@ static RzPVector /**/ *symbols(RzBinFile *bf) { symbols_from_mach0(ret, obj->mach0, bf, 0, 0); - HtPP *kernel_syms_by_addr = sdb_ht_new(); + HtSS *kernel_syms_by_addr = sdb_ht_new(); if (!kernel_syms_by_addr) { rz_pvector_free(ret); return NULL; @@ -1433,8 +1433,8 @@ static RzList /**/ *resolve_syscalls(RzXNUKernelCacheObj *obj, ut #define K_MIG_ROUTINE_SIZE (5 * 8) #define K_MIG_MAX_ROUTINES 100 -static HtPP *mig_hash_new(void) { - HtPP *hash = sdb_ht_new(); +static HtSS *mig_hash_new(void) { + HtSS *hash = sdb_ht_new(); if (!hash) { return NULL; } @@ -1455,7 +1455,7 @@ static RzList /**/ *resolve_mig_subsystem(RzXNUKernelCacheObj *ob return NULL; } - HtPP *mig_hash = NULL; + HtSS *mig_hash = NULL; RzList *subsystem = NULL; ut8 *data_const = NULL; ut64 data_const_offset = 0, data_const_size = 0, data_const_vaddr = 0; @@ -1616,7 +1616,7 @@ static ut64 extract_addr_from_code(ut8 *arm64_code, ut64 vaddr) { return addr; } -static void symbols_from_stubs(RzPVector /**/ *ret, HtPP *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal) { +static void symbols_from_stubs(RzPVector /**/ *ret, HtSS *kernel_syms_by_addr, RzXNUKernelCacheObj *obj, RzBinFile *bf, RKext *kext, int ordinal) { RStubsInfo *stubs_info = get_stubs_info(kext->mach0, kext->range.offset, obj); if (!stubs_info) { return; diff --git a/librz/config/config.c b/librz/config/config.c index 8f6e4382d79..265e012c03e 100644 --- a/librz/config/config.c +++ b/librz/config/config.c @@ -47,7 +47,7 @@ RZ_API void rz_config_node_free(RZ_NULLABLE void *n) { RZ_API RZ_BORROW RzConfigNode *rz_config_node_get(RzConfig *cfg, RZ_NONNULL const char *name) { rz_return_val_if_fail(cfg && RZ_STR_ISNOTEMPTY(name), NULL); - return ht_pp_find(cfg->ht, name, NULL); + return ht_sp_find(cfg->ht, name, NULL); } RZ_API bool rz_config_set_getter(RzConfig *cfg, const char *key, RzConfigCallback cb) { @@ -236,7 +236,7 @@ RZ_API RzConfigNode *rz_config_set_b(RzConfig *cfg, RZ_NONNULL const char *name, } node->flags = CN_RW | CN_BOOL; node->i_value = value ? 1 : 0; - ht_pp_insert(cfg->ht, node->name, node); + ht_sp_insert(cfg->ht, node->name, node); if (cfg->nodes) { rz_list_append(cfg->nodes, node); } @@ -326,7 +326,7 @@ RZ_API RzConfigNode *rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, c node->flags |= CN_BOOL; node->i_value = rz_str_is_true(value) ? 1 : 0; } - ht_pp_insert(cfg->ht, node->name, node); + ht_sp_insert(cfg->ht, node->name, node); rz_list_append(cfg->nodes, node); } else { eprintf("rz_config_set: unable to create a new RzConfigNode\n"); @@ -366,7 +366,7 @@ RZ_API bool rz_config_add_node(RZ_BORROW RzConfig *cfg, RZ_OWN RzConfigNode *nod rz_config_node_free(node); return false; } - ht_pp_insert(cfg->ht, node->name, node); + ht_sp_insert(cfg->ht, node->name, node); rz_list_append(cfg->nodes, node); return true; } @@ -393,7 +393,7 @@ RZ_API bool rz_config_rm(RzConfig *cfg, RZ_NONNULL const char *name) { rz_return_val_if_fail(RZ_STR_ISNOTEMPTY(name) && cfg, false); RzConfigNode *node = rz_config_node_get(cfg, name); if (node) { - ht_pp_delete(cfg->ht, node->name); + ht_sp_delete(cfg->ht, node->name); rz_list_delete_data(cfg->nodes, node); return true; } @@ -446,7 +446,7 @@ RZ_API RzConfigNode *rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, } node->flags = CN_RW | CN_INT; node->i_value = i; - ht_pp_insert(cfg->ht, node->name, node); + ht_sp_insert(cfg->ht, node->name, node); if (cfg->nodes) { rz_list_append(cfg->nodes, node); } @@ -492,7 +492,7 @@ RZ_API RzConfig *rz_config_new(void *user) { if (!cfg) { return NULL; } - cfg->ht = ht_pp_new0(); + cfg->ht = ht_sp_new(HT_STR_DUP, NULL, NULL); cfg->nodes = rz_list_newf((RzListFree)rz_config_node_free); if (!cfg->nodes) { RZ_FREE(cfg); @@ -513,7 +513,7 @@ RZ_API RzConfig *rz_config_clone(RzConfig *cfg) { } rz_list_foreach (cfg->nodes, iter, node) { RzConfigNode *nn = rz_config_node_clone(node); - ht_pp_insert(c->ht, node->name, nn); + ht_sp_insert(c->ht, node->name, nn); rz_list_append(c->nodes, nn); } c->lock = cfg->lock; @@ -524,7 +524,7 @@ RZ_API void rz_config_free(RzConfig *cfg) { if (cfg) { cfg->nodes->free = rz_config_node_free; rz_list_free(cfg->nodes); - ht_pp_free(cfg->ht); + ht_sp_free(cfg->ht); free(cfg); } } diff --git a/librz/config/serialize_config.c b/librz/config/serialize_config.c index f423f83d749..dc70b592e1d 100644 --- a/librz/config/serialize_config.c +++ b/librz/config/serialize_config.c @@ -26,12 +26,12 @@ RZ_API void rz_serialize_config_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *co typedef struct load_config_ctx_t { RzConfig *config; - HtPP *exclude; + HtSP *exclude; } LoadConfigCtx; static bool load_config_cb(void *user, const char *k, const char *v) { LoadConfigCtx *ctx = user; - if (ctx->exclude && ht_pp_find_kv(ctx->exclude, k, NULL)) { + if (ctx->exclude && ht_sp_find_kv(ctx->exclude, k, NULL)) { return true; } RzConfigNode *node = rz_config_node_get(ctx->config, k); @@ -49,15 +49,15 @@ RZ_API bool rz_serialize_config_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzConfig *co RZ_NULLABLE const char *const *exclude, RZ_NULLABLE RzSerializeResultInfo *res) { LoadConfigCtx ctx = { config, NULL }; if (exclude) { - ctx.exclude = ht_pp_new0(); + ctx.exclude = ht_sp_new(HT_STR_DUP, NULL, NULL); if (!ctx.exclude) { return false; } for (; *exclude; exclude++) { - ht_pp_insert(ctx.exclude, *exclude, NULL); + ht_sp_insert(ctx.exclude, *exclude, NULL); } } sdb_foreach(db, load_config_cb, &ctx); - ht_pp_free(ctx.exclude); + ht_sp_free(ctx.exclude); return true; } diff --git a/librz/cons/canvas.c b/librz/cons/canvas.c index 49e66b464ea..c842865834a 100644 --- a/librz/cons/canvas.c +++ b/librz/cons/canvas.c @@ -29,10 +29,6 @@ static int __getAnsiPiece(const char *p, char *chr) { return p - q; } -static void attribute_free_kv(HtUPKv *kv) { - free(kv->value); -} - static const char *__attributeAt(RzConsCanvas *c, int loc) { if (!c->color) { return NULL; @@ -259,7 +255,7 @@ RZ_API RzConsCanvas *rz_cons_canvas_new(int w, int h) { if (!rz_str_constpool_init(&c->constpool)) { goto beach; } - c->attrs = ht_up_new((HtUPDupValue)strdup, attribute_free_kv, NULL); + c->attrs = ht_up_new((HtUPDupValue)strdup, free); if (!c->attrs) { goto beach; } diff --git a/librz/cons/hud.c b/librz/cons/hud.c index d3f6a7da2c3..eaca7ec5a78 100644 --- a/librz/cons/hud.c +++ b/librz/cons/hud.c @@ -191,11 +191,6 @@ static RzList /**/ *hud_filter(RzList /**/ *list, char *user_inp return res; } -static void mht_free_kv(HtPPKv *kv) { - free(kv->key); - rz_list_free(kv->value); -} - // Display a list of entries in the hud, filtered and emphasized based on the user input. #define HUD_CACHE 0 @@ -204,7 +199,7 @@ RZ_API char *rz_cons_hud(RzList /**/ *list, const char *prompt) { char *selected_entry = NULL; RzListIter *iter; - HtPP *ht = ht_pp_new(NULL, (HtPPKvFreeFunc)mht_free_kv, (HtPPCalcSizeV)strlen); + HtSP *ht = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_list_free); RzLineHud *hud = (RzLineHud *)RZ_NEW(RzLineHud); hud->activate = 0; hud->vi = 0; @@ -234,12 +229,12 @@ RZ_API char *rz_cons_hud(RzList /**/ *list, const char *prompt) { RzList *filtered_list = NULL; bool found = false; - filtered_list = ht_pp_find(ht, user_input, &found); + filtered_list = ht_sp_find(ht, user_input, &found); if (!found) { filtered_list = hud_filter(list, user_input, hud->top_entry_n, &(hud->current_entry_n), &selected_entry); #if HUD_CACHE - ht_pp_insert(ht, user_input, filtered_list); + ht_sp_insert(ht, user_input, filtered_list); #endif } rz_list_foreach (filtered_list, iter, row) { @@ -277,7 +272,7 @@ RZ_API char *rz_cons_hud(RzList /**/ *list, const char *prompt) { rz_cons_show_cursor(true); rz_cons_enable_mouse(false); rz_cons_set_raw(false); - ht_pp_free(ht); + ht_sp_free(ht); return NULL; } diff --git a/librz/cons/line.c b/librz/cons/line.c index 9fbcd22c642..4115c987a06 100644 --- a/librz/cons/line.c +++ b/librz/cons/line.c @@ -135,7 +135,7 @@ RZ_API RzLineNSCompletionResult *rz_line_ns_completion_result_new(size_t start, } rz_pvector_init(&res->options, (RzPVectorFree)free); HtPPOptions opt = { 0 }; - opt.cmp = (HtPPListComparator)strcmp; + opt.cmp = (HtPPComparator)strcmp; opt.hashfn = (HtPPHashFunction)sdb_hash; res->options_ht = ht_pp_new_opt(&opt); res->start = start; diff --git a/librz/core/agraph.c b/librz/core/agraph.c index 1b645244803..be2a55ebc8b 100644 --- a/librz/core/agraph.c +++ b/librz/core/agraph.c @@ -907,7 +907,7 @@ static int is_valid_pos(const RzAGraph *g, int l, int pos) { return pos >= 0 && pos < g->layers[l].n_nodes; } -static void free_vertical_nodes_kv(HtPPKv *kv) { +static void fini_vertical_nodes_kv(HtPPKv *kv, RZ_UNUSED void *user) { rz_list_free(kv->value); } @@ -917,7 +917,7 @@ static void free_vertical_nodes_kv(HtPPKv *kv) { * to the same long edge */ static HtPP *compute_vertical_nodes(const RzAGraph *g) { HtPPOptions ht_opt = { 0 }; - ht_opt.freefn = free_vertical_nodes_kv; + ht_opt.finiKV = fini_vertical_nodes_kv; HtPP *res = ht_pp_new_opt(&ht_opt); if (!res) { return NULL; @@ -1135,7 +1135,7 @@ static int place_nodes_sel_p(int newval, int oldval, int is_first, int is_left) } /* places left/right the nodes of a class */ -static void place_nodes(const RzAGraph *g, const RzGraphNode *gn, int is_left, HtPP *v_nodes, HtPU *res, SetP *placed) { +static void place_nodes(const RzAGraph *g, const RzGraphNode *gn, int is_left, HtPP *v_nodes, HtPU *res, SetU *placed) { const RzList *lv = ht_pp_find(v_nodes, gn, NULL); int p = 0, v, is_first = true; const RzGraphNode *gk; @@ -1155,7 +1155,7 @@ static void place_nodes(const RzAGraph *g, const RzGraphNode *gn, int is_left, H } sibl_anode = get_anode(sibling); if (ak->klass == sibl_anode->klass) { - if (!set_p_contains(placed, sibling)) { + if (!set_u_contains(placed, (ut64)sibling)) { place_nodes(g, sibling, is_left, v_nodes, res, placed); } @@ -1174,7 +1174,7 @@ static void place_nodes(const RzAGraph *g, const RzGraphNode *gn, int is_left, H break; } ht_pu_update(res, gk, (ut64)(size_t)p); - set_p_add(placed, gk); + set_u_add(placed, (ut64)gk); } } @@ -1188,12 +1188,11 @@ static HtPU *compute_pos(const RzAGraph *g, int is_left, HtPP *v_nodes) { } HtPUOptions pu_opt = { 0 }; - HtPPOptions pp_opt = { 0 }; HtPU *res = ht_pu_new_opt(&pu_opt); - SetP *placed = (SetP *)ht_pp_new_opt(&pp_opt); + SetU *placed = set_u_new(); if (!res || !placed) { ht_pu_free(res); - set_p_free(placed); + set_u_free(placed); return NULL; } for (i = 0; i < n_classes; i++) { @@ -1201,7 +1200,7 @@ static HtPU *compute_pos(const RzAGraph *g, int is_left, HtPP *v_nodes) { const RzListIter *it; rz_list_foreach (classes[i], it, gn) { - if (!set_p_contains(placed, gn)) { + if (!set_u_contains(placed, (ut64)gn)) { place_nodes(g, gn, is_left, v_nodes, res, placed); } } @@ -1209,7 +1208,7 @@ static HtPU *compute_pos(const RzAGraph *g, int is_left, HtPP *v_nodes) { adjust_class(g, is_left, classes, res, i); } - set_p_free(placed); + set_u_free(placed); for (i = 0; i < n_classes; i++) { if (classes[i]) { rz_list_free(classes[i]); @@ -3572,24 +3571,12 @@ static void agraph_toggle_speed(RzAGraph *g, RzCore *core) { g->movspeed = g->movspeed == DEFAULT_SPEED ? alt : DEFAULT_SPEED; } -static void free_nodes_kv(HtPPKv *kv) { - RzANode *n = (RzANode *)kv->value; - if (!n->is_dummy) { +static void free_node(RzANode *n) { + if (n && !n->is_dummy) { agraph_node_free(n); } } -static HtPPOptions nodes_opt = { - .cmp = (HtPPListComparator)strcmp, - .hashfn = (HtPPHashFunction)sdb_hash, - .dupkey = NULL, - .dupvalue = NULL, - .calcsizeK = (HtPPCalcSizeK)strlen, - .calcsizeV = NULL, - .freefn = free_nodes_kv, - .elem_size = sizeof(HtPPKv), -}; - static void agraph_init(RzAGraph *g) { g->is_callgraph = false; g->is_il = false; @@ -3599,7 +3586,7 @@ static void agraph_init(RzAGraph *g) { g->show_node_body = true; g->force_update_seek = true; g->graph = rz_graph_new(); - g->nodes = ht_pp_new_opt(&nodes_opt); + g->nodes = ht_sp_new(HT_STR_CONST, NULL, (HtSPFreeValue)free_node); g->dummy_nodes = rz_list_newf((RzListFree)agraph_node_free); g->edgemode = 2; g->zoom = ZOOM_DEFAULT; @@ -3770,7 +3757,7 @@ RZ_API RzANode *rz_agraph_add_node(const RzAGraph *g, const char *title, const c res->shortcut_w = 0; res->gnode = rz_graph_add_node(g->graph, res); if (RZ_STR_ISNOTEMPTY(res->title) && !g->is_il) { - ht_pp_update(g->nodes, res->title, res); + ht_sp_update(g->nodes, res->title, res); char *s, *estr, *b; size_t len; sdb_array_add(g->db, "agraph.nodes", res->title, 0); @@ -3830,11 +3817,11 @@ RZ_API bool rz_agraph_del_node(const RzAGraph *g, const char *title) { rz_graph_del_node(g->graph, res->gnode); res->gnode = NULL; - ht_pp_delete(g->nodes, res->title); + ht_sp_delete(g->nodes, res->title); return true; } -static bool user_node_cb(struct g_cb *user, RZ_UNUSED const void *k, const void *v) { +static bool user_node_cb(struct g_cb *user, RZ_UNUSED const char *k, const void *v) { RzANodeCallback cb = user->node_cb; void *user_data = user->data; RzANode *n = (RzANode *)v; @@ -3844,7 +3831,7 @@ static bool user_node_cb(struct g_cb *user, RZ_UNUSED const void *k, const void return true; } -static bool user_edge_cb(struct g_cb *user, RZ_UNUSED const void *k, const void *v) { +static bool user_edge_cb(struct g_cb *user, RZ_UNUSED const char *k, const void *v) { RAEdgeCallback cb = user->edge_cb; RzAGraph *g = user->graph; void *user_data = user->data; @@ -3869,7 +3856,7 @@ RZ_API void rz_agraph_foreach(RzAGraph *g, RzANodeCallback cb, void *user) { .node_cb = cb, .data = user }; - ht_pp_foreach(g->nodes, (HtPPForeachCallback)user_node_cb, &u); + ht_sp_foreach(g->nodes, (HtSPForeachCallback)user_node_cb, &u); } RZ_API void rz_agraph_foreach_edge(RzAGraph *g, RAEdgeCallback cb, void *user) { @@ -3878,7 +3865,7 @@ RZ_API void rz_agraph_foreach_edge(RzAGraph *g, RAEdgeCallback cb, void *user) { .edge_cb = cb, .data = user }; - ht_pp_foreach(g->nodes, (HtPPForeachCallback)user_edge_cb, &u); + ht_sp_foreach(g->nodes, (HtSPForeachCallback)user_edge_cb, &u); } RZ_API RzANode *rz_agraph_get_first_node(const RzAGraph *g) { @@ -3892,7 +3879,7 @@ RZ_API RzANode *rz_agraph_get_node(const RzAGraph *g, const char *title) { if (!title_trunc) { return NULL; } - RzANode *node = ht_pp_find(g->nodes, title_trunc, NULL); + RzANode *node = ht_sp_find(g->nodes, title_trunc, NULL); free(title_trunc); return node; } @@ -3931,7 +3918,7 @@ RZ_API void rz_agraph_del_edge(const RzAGraph *g, RzANode *a, RzANode *b) { } RZ_API void rz_agraph_reset(RzAGraph *g) { - ht_pp_free(g->nodes); + ht_sp_free(g->nodes); rz_list_free(g->dummy_nodes); rz_graph_reset(g->graph); rz_agraph_set_title(g, NULL); @@ -3939,7 +3926,7 @@ RZ_API void rz_agraph_reset(RzAGraph *g) { if (g->edges) { rz_list_purge(g->edges); } - g->nodes = ht_pp_new_opt(&nodes_opt); + g->nodes = ht_sp_new(HT_STR_CONST, NULL, (HtSPFreeValue)free_node); g->dummy_nodes = rz_list_newf((RzListFree)agraph_node_free); g->update_seek_on = NULL; g->need_reload_nodes = false; @@ -3954,7 +3941,7 @@ RZ_API void rz_agraph_free(RzAGraph *g) { if (!g) { return; } - ht_pp_free(g->nodes); + ht_sp_free(g->nodes); rz_list_free(g->dummy_nodes); rz_graph_free(g->graph); rz_list_free(g->edges); diff --git a/librz/core/analysis_objc.c b/librz/core/analysis_objc.c index 94505a402e0..ae61c760945 100644 --- a/librz/core/analysis_objc.c +++ b/librz/core/analysis_objc.c @@ -45,10 +45,6 @@ static void array_add(RzCoreObjc *o, ut64 va, ut64 xrefs_to) { rz_vector_push(vec, &xrefs_to); } -static void kv_array_free(HtUPKv *kv) { - rz_vector_free(kv->value); -} - static inline bool isValid(ut64 addr) { return (addr != 0LL && addr != UT64_MAX); } @@ -203,7 +199,7 @@ static RzCoreObjc *core_objc_new(RzCore *core) { free(o); return NULL; } - o->up = ht_up_new(NULL, kv_array_free, NULL); + o->up = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); return o; } diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index 5a17d88c3ce..6ed5591112e 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -530,10 +530,6 @@ static int bb_cmpaddr(const void *_a, const void *_b, void *user) { return a->addr > b->addr ? 1 : (a->addr < b->addr ? -1 : 0); } -void free_op_cache_kv(HtUPKv *kv) { - rz_analysis_op_free(kv->value); -} - void handle_stack_canary(RzCore *core, RzAnalysisOp *aop, int cur_idx) { RzILTraceInstruction *prev_trace = rz_analysis_esil_get_instruction_trace( core->analysis->esil->trace, @@ -838,12 +834,10 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, H } // Reserve bigger ht to avoid rehashing - HtPPOptions opt; RzDebugTrace *dtrace = core->dbg->trace; - opt = dtrace->ht->opt; - ht_pp_free(dtrace->ht); - dtrace->ht = ht_pp_new_size(fcn->ninstr, opt.dupvalue, opt.freefn, opt.calcsizeV); - dtrace->ht->opt = opt; + HtSPOptions opt = dtrace->ht->opt; + ht_sp_free(dtrace->ht); + dtrace->ht = ht_sp_new_opt_size(&opt, fcn->ninstr); // Create a new context to store the return type propagation state struct ReturnTypeAnalysisCtx retctx = { @@ -878,7 +872,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, H ut64 addr = bb->addr; rz_reg_set_value(reg, r, addr); ht_up_free(op_cache); - op_cache = ht_up_new(NULL, free_op_cache_kv, NULL); + op_cache = ht_up_new(NULL, (HtUPFreeValue)rz_analysis_op_free); if (!op_cache) { break; } @@ -934,7 +928,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, H // excessive memory usage. if (op_cache->count > OP_CACHE_LIMIT) { ht_up_free(op_cache); - op_cache = ht_up_new(NULL, free_op_cache_kv, NULL); + op_cache = ht_up_new(NULL, (HtUPFreeValue)rz_analysis_op_free); if (!op_cache) { break; } diff --git a/librz/core/basefind.c b/librz/core/basefind.c index 82edef5541a..84e1ad8272b 100644 --- a/librz/core/basefind.c +++ b/librz/core/basefind.c @@ -166,7 +166,7 @@ static BaseFindArray *basefind_create_array_of_addresses(RzCore *core, RzBinStri static HtUU *basefind_create_pointer_map(RzCore *core, ut32 pointer_size) { rz_return_val_if_fail(pointer_size == sizeof(ut32) || pointer_size == sizeof(ut64), NULL); - HtUU *map = ht_uu_new0(); + HtUU *map = ht_uu_new(); if (!map) { RZ_LOG_ERROR("basefind: cannot allocate hashmap for pointer.\n"); return NULL; diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index f9c8befae15..a22efaf3bde 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -1767,7 +1767,7 @@ static bool analysis_path_exists(RzCore *core, ut64 from, ut64 to, RzList /**/ *analysis_graph_to(RzCore *core, ut64 addr, int depth, HtUP *avoid) { RzAnalysisFunction *cur_fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0); RzList *list = rz_list_new(); - HtUP *state = ht_up_new0(); + HtUP *state = ht_up_new(NULL, NULL); if (!list || !state || !cur_fcn) { rz_list_free(list); @@ -1811,7 +1811,7 @@ static RzList /**/ *analysis_graph_to(RzCore *core, ut64 addr RZ_API RzList /**/ *rz_core_analysis_graph_to(RzCore *core, ut64 addr, int n) { int depth = rz_config_get_i(core->config, "analysis.graph_depth"); RzList *path, *paths = rz_list_new(); - HtUP *avoid = ht_up_new0(); + HtUP *avoid = ht_up_new(NULL, NULL); while (n) { path = analysis_graph_to(core, addr, depth, avoid); if (path) { @@ -3216,7 +3216,7 @@ RZ_API void rz_core_analysis_paths(RzCore *core, ut64 from, ut64 to, bool follow return; } RzCoreAnalPaths rcap = { 0 }; - rcap.visited = ht_uu_new0(); + rcap.visited = ht_uu_new(); rcap.path = rz_list_new(); rcap.core = core; rcap.from = from; @@ -3701,7 +3701,7 @@ RZ_API void rz_core_analysis_propagate_noreturn(RzCore *core, ut64 addr) { return; } - HtUU *done = ht_uu_new0(); + HtUU *done = ht_uu_new(); if (!done) { rz_list_free(todo); return; @@ -4242,7 +4242,7 @@ RZ_API RZ_OWN RzList /**/ *rz_core_analysis_sigdb_list(RZ_NONNUL analysis_sigdb_add(sigs, user_sigdb, with_details); RzList *lst = rz_sign_sigdb_list(sigs); - sigs->entries->opt.freefn = NULL; + sigs->entries->opt.finiKV = NULL; rz_sign_sigdb_free(sigs); return lst; } @@ -4588,7 +4588,7 @@ RZ_IPI bool rz_core_analysis_types_propagation(RzCore *core) { // loop count of rz_core_analysis_type_match // TODO : figure out the reason to hold a `LOOP COUNT` in type_match // HtUU loop_count> - HtUU *loop_table = ht_uu_new0(); + HtUU *loop_table = ht_uu_new(); // Iterating Reverse so that we get function in top-bottom call order rz_list_foreach_prev(core->analysis->fcns, it, fcn) { diff --git a/librz/core/cannotated_code.c b/librz/core/cannotated_code.c index 12d6e258397..8b2e3f6ea8e 100644 --- a/librz/core/cannotated_code.c +++ b/librz/core/cannotated_code.c @@ -270,7 +270,7 @@ static bool foreach_offset_annotation(void *user, const ut64 offset, const void RZ_API void rz_core_annotated_code_print_comment_cmds(RzAnnotatedCode *code) { RzCodeAnnotation *annotation; - HtUP *ht = ht_up_new0(); + HtUP *ht = ht_up_new(NULL, NULL); rz_vector_foreach(&code->annotations, annotation) { if (annotation->type != RZ_CODE_ANNOTATION_TYPE_OFFSET) { continue; diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 5a97ff580e1..8fee618db60 100644 --- a/librz/core/cbin.c +++ b/librz/core/cbin.c @@ -1669,11 +1669,6 @@ RZ_API bool rz_core_bin_apply_resources(RzCore *core, RzBinFile *binfile) { return true; } -static void digests_ht_free(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - /** * \brief Create a hashtable of digests * @@ -1681,9 +1676,9 @@ static void digests_ht_free(HtPPKv *kv) { * Returns the hashtable with keys of digest names and values of * strings containing requested digests. * */ -RZ_API RZ_OWN HtPP *rz_core_bin_create_digests(RzCore *core, ut64 paddr, ut64 size, RzList /**/ *digests) { +RZ_API RZ_OWN HtSS *rz_core_bin_create_digests(RzCore *core, ut64 paddr, ut64 size, RzList /**/ *digests) { rz_return_val_if_fail(size && digests, NULL); - HtPP *r = ht_pp_new(NULL, digests_ht_free, NULL); + HtSS *r = ht_ss_new(HT_STR_DUP, HT_STR_OWN); if (!r) { return NULL; } @@ -1692,7 +1687,7 @@ RZ_API RZ_OWN HtPP *rz_core_bin_create_digests(RzCore *core, ut64 paddr, ut64 si rz_list_foreach (digests, it, digest) { ut8 *data = malloc(size); if (!data) { - ht_pp_free(r); + ht_ss_free(r); return NULL; } rz_io_pread_at(core->io, paddr, data, size); @@ -1700,7 +1695,7 @@ RZ_API RZ_OWN HtPP *rz_core_bin_create_digests(RzCore *core, ut64 paddr, ut64 si if (!chkstr) { continue; } - ht_pp_insert(r, digest, chkstr); + ht_ss_insert(r, digest, chkstr); free(data); } @@ -2349,7 +2344,7 @@ static ut64 get_section_addr(RzCore *core, RzBinObject *o, RzBinSection *section return rva(o, section->paddr, section->vaddr, va); } -static bool digests_pj_cb(void *user, const void *k, const void *v) { +static bool digests_pj_cb(void *user, const char *k, const char *v) { rz_return_val_if_fail(user && k && v, false); PJ *pj = user; pj_ks(pj, k, v); @@ -2392,13 +2387,13 @@ static void sections_print_json(RzCore *core, PJ *pj, RzBinObject *o, RzBinSecti pj_kn(pj, "align", section->align); } if (hashes && section->size > 0) { - HtPP *digests = rz_core_bin_create_digests(core, section->paddr, section->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, section->paddr, section->size, hashes); if (!digests) { pj_end(pj); return; } - ht_pp_foreach(digests, digests_pj_cb, pj); - ht_pp_free(digests); + ht_ss_foreach(digests, digests_pj_cb, pj); + ht_ss_free(digests); } pj_end(pj); } @@ -2432,7 +2427,7 @@ static bool sections_print_table(RzCore *core, RzTable *t, RzBinObject *o, RzBin } bool result = false; if (hashes && section->size > 0) { - HtPP *digests = rz_core_bin_create_digests(core, section->paddr, section->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, section->paddr, section->size, hashes); if (!digests) { goto cleanup; } @@ -2440,12 +2435,12 @@ static bool sections_print_table(RzCore *core, RzTable *t, RzBinObject *o, RzBin char *hash; bool found = false; rz_list_foreach (hashes, it, hash) { - char *digest = ht_pp_find(digests, hash, &found); + char *digest = ht_ss_find(digests, hash, &found); if (found && t) { rz_table_add_row_columnsf(t, "s", digest); } } - ht_pp_free(digests); + ht_ss_free(digests); } result = true; cleanup: @@ -5026,7 +5021,7 @@ static void bin_resources_print_standard(RzCore *core, RzList /**/ *hash rz_cons_printf(" type: %s\n", resource->type); rz_cons_printf(" language: %s\n", resource->language); if (hashes && resource->size > 0) { - HtPP *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); if (!digests) { return; } @@ -5034,12 +5029,12 @@ static void bin_resources_print_standard(RzCore *core, RzList /**/ *hash char *hash = NULL; bool found = false; rz_list_foreach (hashes, it, hash) { - char *digest = ht_pp_find(digests, hash, &found); + char *digest = ht_ss_find(digests, hash, &found); if (found) { rz_cons_printf(" %s: %s\n", hash, digest); } } - ht_pp_free(digests); + ht_ss_free(digests); } } @@ -5047,7 +5042,7 @@ static void bin_resources_print_table(RzCore *core, RzCmdStateOutput *state, RzL rz_table_add_rowf(state->d.t, "dssXxss", resource->index, resource->name, resource->type, resource->vaddr, resource->size, resource->language, resource->time); if (hashes && resource->size > 0) { - HtPP *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); if (!digests) { return; } @@ -5055,12 +5050,12 @@ static void bin_resources_print_table(RzCore *core, RzCmdStateOutput *state, RzL char *hash; bool found = false; rz_list_foreach (hashes, it, hash) { - char *digest = ht_pp_find(digests, hash, &found); + char *digest = ht_ss_find(digests, hash, &found); if (found && state->d.t) { rz_table_add_row_columnsf(state->d.t, "s", digest); } } - ht_pp_free(digests); + ht_ss_free(digests); } } @@ -5074,7 +5069,7 @@ static void bin_resources_print_json(RzCore *core, RzCmdStateOutput *state, RzLi pj_ks(state->d.pj, "lang", resource->language); pj_ks(state->d.pj, "timestamp", resource->time); if (hashes && resource->size > 0) { - HtPP *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); + HtSS *digests = rz_core_bin_create_digests(core, resource->vaddr, resource->size, hashes); if (!digests) { goto end; } @@ -5082,12 +5077,12 @@ static void bin_resources_print_json(RzCore *core, RzCmdStateOutput *state, RzLi char *hash; bool found = false; rz_list_foreach (hashes, it, hash) { - char *digest = ht_pp_find(digests, hash, &found); + char *digest = ht_ss_find(digests, hash, &found); if (found && state->d.pj) { pj_ks(state->d.pj, hash, digest); } } - ht_pp_free(digests); + ht_ss_free(digests); } end: pj_end(state->d.pj); diff --git a/librz/core/cgraph.c b/librz/core/cgraph.c index a24bc85e0c8..90529bd3f8d 100644 --- a/librz/core/cgraph.c +++ b/librz/core/cgraph.c @@ -355,7 +355,7 @@ static RZ_OWN RzGraph /**/ *rz_core_graph_function_bbs(RZ_NON if (!hc) { goto fail; } - cache = ht_up_new0(); + cache = ht_up_new(NULL, NULL); if (!cache) { goto fail; } @@ -890,7 +890,7 @@ RZ_API RZ_OWN RzGraph /**/ *rz_core_graph_icfg(RZ_NONNULL RzC return NULL; } - HtUU *graph_idx = ht_uu_new0(); + HtUU *graph_idx = ht_uu_new(); RzListIter *it; const RzAnalysisFunction *fcn; rz_list_foreach (fcns, it, fcn) { @@ -1040,7 +1040,7 @@ RZ_API RZ_OWN RzGraph /**/ *rz_core_graph_cfg(RZ_NONNULL RzCo } // Visited instructions. Indexed by instruction address, value is index in graph. - HtUU *nodes_visited = ht_uu_new0(); + HtUU *nodes_visited = ht_uu_new(); // Addresses to visit. RzVector *to_visit = rz_vector_new(sizeof(ut64), NULL, NULL); diff --git a/librz/core/cmd/cmd.c b/librz/core/cmd/cmd.c index c6337a7b99f..df11a7a4da9 100644 --- a/librz/core/cmd/cmd.c +++ b/librz/core/cmd/cmd.c @@ -5157,7 +5157,7 @@ RZ_API RzCmd *rz_core_cmd_new(RzCore *core, bool has_cons) { TSLanguage *lang = tree_sitter_rzcmd(); res->language = lang; - res->ts_symbols_ht = ht_up_new0(); + res->ts_symbols_ht = ht_up_new(NULL, NULL); struct ts_data_symbol_map *entry = map_ts_stmt_handlers; while (entry->name) { TSSymbol symbol = ts_language_symbol_for_name(lang, entry->name, strlen(entry->name), true); diff --git a/librz/core/cmd/cmd_analysis.c b/librz/core/cmd/cmd_analysis.c index 285f94c7eb2..c2f4c981082 100644 --- a/librz/core/cmd/cmd_analysis.c +++ b/librz/core/cmd/cmd_analysis.c @@ -3506,7 +3506,7 @@ static void xrefs_graph(RzCore *core, ut64 addr, int level, HtUU *ht, RzOutputMo } RZ_IPI RzCmdStatus rz_analysis_xrefs_graph_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { - HtUU *ht = ht_uu_new0(); + HtUU *ht = ht_uu_new(); if (!ht) { return RZ_CMD_STATUS_ERROR; } @@ -4178,13 +4178,13 @@ RZ_IPI RzCmdStatus rz_analysis_function_import_list_del_handler(RzCore *core, in return RZ_CMD_STATUS_OK; } -static void ht_inc(HtPU *ht, const char *key) { +static void ht_inc(HtSU *ht, const char *key) { bool found; - HtPUKv *kv = ht_pu_find_kv(ht, key, &found); + HtSUKv *kv = ht_su_find_kv(ht, key, &found); if (kv) { kv->value++; } else { - ht_pu_insert(ht, key, 1); + ht_su_insert(ht, key, 1); } } @@ -4194,7 +4194,7 @@ enum STATS_MODE { STATS_MODE_TYPE }; -static void update_stat_for_op(RzCore *core, HtPU *ht, ut64 addr, int mode) { +static void update_stat_for_op(RzCore *core, HtSU *ht, ut64 addr, int mode) { RzAnalysisOp *op = rz_core_analysis_op(core, addr, RZ_ANALYSIS_OP_MASK_BASIC | RZ_ANALYSIS_OP_MASK_HINT | RZ_ANALYSIS_OP_MASK_DISASM); if (!op) { return; @@ -4220,7 +4220,7 @@ static void update_stat_for_op(RzCore *core, HtPU *ht, ut64 addr, int mode) { rz_analysis_op_free(op); } -static void gather_opcode_stat_for_fcn(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, int mode) { +static void gather_opcode_stat_for_fcn(RzCore *core, HtSU *ht, RzAnalysisFunction *fcn, int mode) { void **iter; RzAnalysisBlock *bb; rz_pvector_foreach (fcn->bbs, iter) { @@ -4238,11 +4238,11 @@ static bool list_keys_cb(RzList /**/ *list, char *k, RZ_UNUSED ut64 v) { return true; } -static void print_stats(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, RzCmdStateOutput *state) { +static void print_stats(RzCore *core, HtSU *ht, RzAnalysisFunction *fcn, RzCmdStateOutput *state) { const char *name; RzListIter *iter; RzList *list = rz_list_newf(NULL); - ht_pu_foreach(ht, (HtPUForeachCallback)list_keys_cb, list); + ht_su_foreach(ht, (HtSUForeachCallback)list_keys_cb, list); rz_list_sort(list, (RzListComparator)strcmp, NULL); if (state->mode == RZ_OUTPUT_MODE_TABLE) { RzTable *t = state->d.t; @@ -4260,13 +4260,13 @@ static void print_stats(RzCore *core, HtPU *ht, RzAnalysisFunction *fcn, RzCmdSt } rz_pvector_push(items, strdup(fcn->name)); rz_list_foreach (list, iter, name) { - int nv = (int)ht_pu_find(ht, name, NULL); + int nv = (int)ht_su_find(ht, name, NULL); rz_pvector_push(items, rz_str_newf("%d", nv)); } rz_table_add_row_vec(t, items); } else { rz_list_foreach (list, iter, name) { - ut32 nv = (ut32)ht_pu_find(ht, name, NULL); + ut32 nv = (ut32)ht_su_find(ht, name, NULL); rz_cons_printf("%4u %s\n", nv, name); } } @@ -4282,19 +4282,19 @@ RZ_IPI RzCmdStatus rz_analysis_function_opcode_stat_handler(RzCore *core, int ar if (!fcn) { return RZ_CMD_STATUS_ERROR; } - HtPU *ht = ht_pu_new0(); + HtSU *ht = ht_su_new(HT_STR_DUP); if (!ht) { return RZ_CMD_STATUS_ERROR; } gather_opcode_stat_for_fcn(core, ht, fcn, mode); print_stats(core, ht, fcn, state); - ht_pu_free(ht); + ht_su_free(ht); return RZ_CMD_STATUS_OK; } -static bool add_keys_to_set_cb(HtPU *ht, const char *k, RZ_UNUSED const ut64 v) { +static bool add_keys_to_set_cb(HtSU *ht, const char *k, RZ_UNUSED const ut64 v) { if (strcmp(k, ".addr")) { - ht_pu_insert(ht, k, 1); + ht_su_insert(ht, k, 1); } return true; } @@ -4309,7 +4309,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_all_opcode_stat_handler(RzCore *core, in mode = !strcmp(argv[1], "family") ? STATS_MODE_FML : STATS_MODE_TYPE; } RzList *keys = rz_list_newf(NULL); - HtPU *keys_set = ht_pu_new0(); + HtSU *keys_set = ht_su_new(HT_STR_DUP); RzList *dbs = rz_list_newf((RzListFree)ht_pu_free); if (!keys || !keys_set || !dbs) { goto exit; @@ -4318,21 +4318,21 @@ RZ_IPI RzCmdStatus rz_analysis_function_all_opcode_stat_handler(RzCore *core, in RzListIter *iter; RzAnalysisFunction *fcn; rz_list_foreach (core->analysis->fcns, iter, fcn) { - HtPU *db = ht_pu_new0(); + HtSU *db = ht_su_new(HT_STR_DUP); if (!db) { break; } gather_opcode_stat_for_fcn(core, db, fcn, mode); - ht_pu_insert(db, ".addr", fcn->addr); + ht_su_insert(db, ".addr", fcn->addr); rz_list_append(dbs, db); } - HtPU *db; + HtSU *db; rz_list_foreach (dbs, iter, db) { - ht_pu_foreach(db, (HtPUForeachCallback)add_keys_to_set_cb, keys_set); + ht_su_foreach(db, (HtSUForeachCallback)add_keys_to_set_cb, keys_set); } - ht_pu_foreach(keys_set, (HtPUForeachCallback)list_keys_cb, keys); + ht_su_foreach(keys_set, (HtSUForeachCallback)list_keys_cb, keys); rz_list_sort(keys, (RzListComparator)strcmp, NULL); RzTable *t = state->d.t; @@ -4352,12 +4352,12 @@ RZ_IPI RzCmdStatus rz_analysis_function_all_opcode_stat_handler(RzCore *core, in if (!items) { break; } - ut64 fcnAddr = ht_pu_find(db, ".addr", NULL); + ut64 fcnAddr = ht_su_find(db, ".addr", NULL); RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, fcnAddr); rz_pvector_push(items, fcn ? strdup(fcn->name) : strdup("")); rz_pvector_push(items, fcn ? rz_str_newf("0x%08" PFMT64x, fcnAddr) : strdup("0")); rz_list_foreach (keys, iter, key) { - ut32 n = (ut32)ht_pu_find(db, key, NULL); + ut32 n = (ut32)ht_su_find(db, key, NULL); rz_pvector_push(items, rz_str_newf("%u", n)); } rz_table_add_row_vec(t, items); @@ -4366,7 +4366,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_all_opcode_stat_handler(RzCore *core, in exit: rz_list_free(keys); rz_list_free(dbs); - ht_pu_free(keys_set); + ht_su_free(keys_set); return res; } diff --git a/librz/core/cmd/cmd_api.c b/librz/core/cmd/cmd_api.c index 8a0e869d4c8..e037adacd84 100644 --- a/librz/core/cmd/cmd_api.c +++ b/librz/core/cmd/cmd_api.c @@ -137,7 +137,7 @@ static void cmd_desc_unset_parent(RzCmdDesc *cd) { static void cmd_desc_remove_from_ht_cmds(RzCmd *cmd, RzCmdDesc *cd) { void **it_cd; - ht_pp_delete(cmd->ht_cmds, cd->name); + ht_sp_delete(cmd->ht_cmds, cd->name); rz_cmd_desc_children_foreach(cd, it_cd) { RzCmdDesc *child_cd = *it_cd; cmd_desc_remove_from_ht_cmds(cmd, child_cd); @@ -167,7 +167,7 @@ static RzCmdDesc *create_cmd_desc(RzCmd *cmd, RzCmdDesc *parent, RzCmdDescType t res->n_children = 0; res->help = help ? help : ¬_defined_help; rz_pvector_init(&res->children, (RzPVectorFree)cmd_desc_free); - if (ht_insert && !ht_pp_insert(cmd->ht_cmds, name, res)) { + if (ht_insert && !ht_sp_insert(cmd->ht_cmds, name, res)) { goto err; } cmd_desc_set_parent(cmd, res, parent); @@ -200,11 +200,6 @@ static void macro_free(RzCmdMacro *macro) { free(macro); } -static void free_macro_kv(HtPPKv *kv) { - free(kv->key); - macro_free(kv->value); -} - /** * \brief Create a generic instance of RzCmd. * @@ -224,8 +219,8 @@ RZ_API RzCmd *rz_cmd_new(RzCore *core, bool has_cons) { } cmd->core = core; cmd->nullcallback = NULL; - cmd->macros = ht_pp_new(NULL, free_macro_kv, NULL); - cmd->ht_cmds = ht_pp_new0(); + cmd->macros = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)macro_free); + cmd->ht_cmds = ht_sp_new(HT_STR_DUP, NULL, NULL); cmd->root_cmd_desc = create_cmd_desc(cmd, NULL, RZ_CMD_DESC_TYPE_GROUP, "", &root_help, true); rz_cmd_alias_init(cmd); return cmd; @@ -238,13 +233,13 @@ RZ_API RzCmd *rz_cmd_free(RzCmd *cmd) { } ht_up_free(cmd->ts_symbols_ht); rz_cmd_alias_free(cmd); - ht_pp_free(cmd->ht_cmds); + ht_sp_free(cmd->ht_cmds); for (i = 0; i < NCMDS; i++) { if (cmd->cmds[i]) { RZ_FREE(cmd->cmds[i]); } } - ht_pp_free(cmd->macros); + ht_sp_free(cmd->macros); cmd_desc_free(cmd->root_cmd_desc); free(cmd); return NULL; @@ -335,7 +330,7 @@ static RzCmdDesc *cmd_get_desc_best(RzCmd *cmd, const char *cmd_identifier, bool char last_letter = '\0', o_last_letter = end_cmdid > cmdid ? *(end_cmdid - 1) : '\0'; // match longer commands first while (*cmdid) { - RzCmdDesc *cd = ht_pp_find(cmd->ht_cmds, cmdid, NULL); + RzCmdDesc *cd = ht_sp_find(cmd->ht_cmds, cmdid, NULL); if (cd) { switch (cd->type) { case RZ_CMD_DESC_TYPE_ARGV: @@ -1609,7 +1604,7 @@ RZ_API bool rz_cmd_macro_add(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name, goto err; } } - return ht_pp_insert(cmd->macros, macro->name, macro); + return ht_sp_insert(cmd->macros, macro->name, macro); err: macro_free(macro); @@ -1628,7 +1623,7 @@ RZ_API bool rz_cmd_macro_add(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name, RZ_API bool rz_cmd_macro_update(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name, const char **args, RZ_NONNULL const char *code) { rz_return_val_if_fail(cmd && name && args && code, false); - RzCmdMacro *macro = ht_pp_find(cmd->macros, name, NULL); + RzCmdMacro *macro = ht_sp_find(cmd->macros, name, NULL); if (!macro) { return false; } @@ -1685,7 +1680,7 @@ RZ_API bool rz_cmd_macro_update(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *na RZ_API bool rz_cmd_macro_rm(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name) { rz_return_val_if_fail(cmd && name, false); - return ht_pp_delete(cmd->macros, name); + return ht_sp_delete(cmd->macros, name); } /** @@ -1698,10 +1693,10 @@ RZ_API bool rz_cmd_macro_rm(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name) RZ_API const RzCmdMacro *rz_cmd_macro_get(RZ_NONNULL RzCmd *cmd, RZ_NONNULL const char *name) { rz_return_val_if_fail(cmd && name, false); - return ht_pp_find(cmd->macros, name, NULL); + return ht_sp_find(cmd->macros, name, NULL); } -static bool macros_to_list(void *user, const void *key, const void *value) { +static bool macros_to_list(void *user, RZ_UNUSED const char *key, const void *value) { RzList *res = (RzList *)user; rz_list_append(res, (void *)value); return true; @@ -1720,7 +1715,7 @@ RZ_API RZ_OWN RzList /**/ *rz_cmd_macro_list(RZ_NONNULL RzCmd *cmd if (!res) { return NULL; } - ht_pp_foreach(cmd->macros, macros_to_list, res); + ht_sp_foreach(cmd->macros, macros_to_list, res); return res; } @@ -1817,7 +1812,7 @@ struct macro_foreach_t { void *user; }; -static bool macro_foreach_cb(void *user, const void *key, const void *value) { +static bool macro_foreach_cb(void *user, RZ_UNUSED const char *key, const void *value) { struct macro_foreach_t *u = (struct macro_foreach_t *)user; RzCmdMacro *macro = (RzCmdMacro *)value; return u->cb(u->cmd, macro, u->user); @@ -1838,7 +1833,7 @@ RZ_API void rz_cmd_macro_foreach(RZ_NONNULL RzCmd *cmd, RzCmdForeachMacroCb cb, .user = user, .cb = cb, }; - ht_pp_foreach(cmd->macros, macro_foreach_cb, &u); + ht_sp_foreach(cmd->macros, macro_foreach_cb, &u); } /* RzCmdParsedArgs */ diff --git a/librz/core/cmd/cmd_eval.c b/librz/core/cmd/cmd_eval.c index 3812fb66cab..0062a0df92c 100644 --- a/librz/core/cmd/cmd_eval.c +++ b/librz/core/cmd/cmd_eval.c @@ -108,13 +108,13 @@ RZ_API bool rz_core_theme_load(RzCore *core, const char *name) { return !failed; } -static void list_themes_in_path(HtPU *themes, const char *path) { +static void list_themes_in_path(HtSU *themes, const char *path) { RzListIter *iter; const char *fn; RzList *files = rz_sys_dir(path); rz_list_foreach (files, iter, fn) { if (*fn && *fn != '.') { - ht_pu_insert(themes, fn, 1); + ht_su_insert(themes, fn, 1); } } rz_list_free(files); @@ -124,7 +124,7 @@ RZ_API char *rz_core_theme_get(RzCore *core) { return core->curtheme; } -static bool dict2keylist(void *user, const void *key, const ut64 value) { +static bool dict2keylist(void *user, const char *key, const ut64 value) { RzList *list = (RzList *)user; rz_list_append(list, strdup(key)); return true; @@ -139,7 +139,7 @@ static bool dict2keylist(void *user, const void *key, const ut64 value) { RZ_API RZ_OWN RzList /**/ *rz_core_theme_list(RZ_NONNULL RzCore *core) { rz_return_val_if_fail(core, NULL); - HtPU *themes = ht_pu_new0(); + HtSU *themes = ht_su_new(HT_STR_DUP); if (!themes) { return NULL; } @@ -164,10 +164,10 @@ RZ_API RZ_OWN RzList /**/ *rz_core_theme_list(RZ_NONNULL RzCore *core) { RzList *list = rz_list_newf(free); rz_list_append(list, strdup("default")); - ht_pu_foreach(themes, dict2keylist, list); + ht_su_foreach(themes, dict2keylist, list); rz_list_sort(list, (RzListComparator)strcmp, NULL); - ht_pu_free(themes); + ht_su_free(themes); return list; } diff --git a/librz/core/cmd/cmd_info.c b/librz/core/cmd/cmd_info.c index e53fb280a14..58e6d0ff350 100644 --- a/librz/core/cmd/cmd_info.c +++ b/librz/core/cmd/cmd_info.c @@ -51,7 +51,7 @@ static bool is_equal_file_hashes(RzPVector /**/ *lfile_hashes, return true; } -static bool source_file_collect_cb(void *user, const void *k, const void *v) { +static bool source_file_collect_cb(void *user, const char *k, const void *v) { RzPVector *r = user; char *f = strdup(k); if (f) { @@ -84,7 +84,7 @@ static bool print_source_info(RzCore *core, PrintSourceInfoType type, RzCmdState switch (type) { case PRINT_SOURCE_INFO_FILES: { // collect all filenames uniquely - HtPP *files = ht_pp_new0(); + HtSP *files = ht_sp_new(HT_STR_DUP, NULL, NULL); if (!files) { return false; } @@ -93,14 +93,14 @@ static bool print_source_info(RzCore *core, PrintSourceInfoType type, RzCmdState if (!s->line || !s->file) { continue; } - ht_pp_insert(files, s->file, NULL); + ht_sp_insert(files, s->file, NULL); } // sort them alphabetically RzPVector sorter; rz_pvector_init(&sorter, free); - ht_pp_foreach(files, source_file_collect_cb, &sorter); + ht_sp_foreach(files, source_file_collect_cb, &sorter); rz_pvector_sort(&sorter, (RzPVectorComparator)compare_string, NULL); - ht_pp_free(files); + ht_sp_free(files); // print them! if (state->mode == RZ_OUTPUT_MODE_JSON) { pj_a(state->d.pj); diff --git a/librz/core/cmd/cmd_regs.c b/librz/core/cmd/cmd_regs.c index 9a9877f9c76..9479d10157c 100644 --- a/librz/core/cmd/cmd_regs.c +++ b/librz/core/cmd/cmd_regs.c @@ -419,7 +419,7 @@ RZ_IPI void rz_regs_show_valgroup(RzCore *core, RzReg *reg, RzCmdRegSync sync_cb RzListIter *iter; RzRegItem *r; - HtUP *db = ht_up_new0(); + HtUP *db = ht_up_new(NULL, NULL); rz_list_foreach (list, iter, r) { if (r->size != core->rasm->bits) { continue; diff --git a/librz/core/core_private.h b/librz/core/core_private.h index 023435cf60d..47cde23234c 100644 --- a/librz/core/core_private.h +++ b/librz/core/core_private.h @@ -310,7 +310,7 @@ typedef struct rz_panels_t { Sdb *db; Sdb *rotate_db; Sdb *almighty_db; - HtPP *mht; + HtSP *mht; RzPanelsMode mode; RzPanelsMode prevMode; RzPanelsLayout layout; diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 4064cffd1e0..c19bb6620b7 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -556,14 +556,6 @@ static void RzBinSourceLineCacheItem_free(RzBinSourceLineCacheItem *x) { free(x); } -static void RzBinSourceLineCacheItem_HtPPKv_free(HtPPKv *x) { - if (!x) { - return; - } - free(x->key); - RzBinSourceLineCacheItem_free(x->value); -} - static RzDisasmState *ds_init(RzCore *core) { RzDisasmState *ds = RZ_NEW0(RzDisasmState); if (!ds) { @@ -633,7 +625,7 @@ static RzDisasmState *ds_init(RzCore *core) { ds->debuginfo.file = rz_config_get_b(core->config, "asm.debuginfo.file"); ds->debuginfo.abspath = rz_config_get_b(core->config, "asm.debuginfo.abspath"); ds->debuginfo.lines = rz_config_get_b(core->config, "asm.debuginfo.lines"); - ds->debuginfo.cache.items = ht_pp_new(NULL, RzBinSourceLineCacheItem_HtPPKv_free, NULL); + ds->debuginfo.cache.items = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)RzBinSourceLineCacheItem_free); ds->show_lines_call = ds->show_lines ? rz_config_get_b(core->config, "asm.lines.call") : false; ds->show_lines_ret = ds->show_lines ? rz_config_get_b(core->config, "asm.lines.ret") : false; @@ -837,7 +829,7 @@ static void ds_free(RzDisasmState *ds) { ds_reflines_fini(ds); ds_print_esil_analysis_fini(ds); sdb_free(ds->ssa); - ht_pp_free(ds->debuginfo.cache.items); + ht_sp_free(ds->debuginfo.cache.items); free(ds->comment); free(ds->line); free(ds->line_col); diff --git a/librz/core/tui/panels.c b/librz/core/tui/panels.c index 22362ba6d3a..d3640d1351e 100644 --- a/librz/core/tui/panels.c +++ b/librz/core/tui/panels.c @@ -4211,12 +4211,12 @@ void __add_menu(RzCore *core, const char *parent, const char *name, RzPanelsMenu return; } if (parent) { - void *addr = ht_pp_find(panels->mht, parent, NULL); + void *addr = ht_sp_find(panels->mht, parent, NULL); p_item = (RzPanelsMenuItem *)addr; - ht_pp_insert(panels->mht, rz_strf(tmpbuf, "%s.%s", parent, name), item); + ht_sp_insert(panels->mht, rz_strf(tmpbuf, "%s.%s", parent, name), item); } else { p_item = panels->panels_menu->root; - ht_pp_insert(panels->mht, rz_strf(tmpbuf, "%s", name), item); + ht_sp_insert(panels->mht, rz_strf(tmpbuf, "%s", name), item); } item->n_sub = 0; item->selectedIndex = 0; @@ -4247,13 +4247,13 @@ void __add_menu(RzCore *core, const char *parent, const char *name, RzPanelsMenu void __update_menu(RzCore *core, const char *parent, RZ_NULLABLE RzPanelMenuUpdateCallback cb) { RzCoreVisual *visual = core->visual; RzPanels *panels = visual->panels; - void *addr = ht_pp_find(panels->mht, parent, NULL); + void *addr = ht_sp_find(panels->mht, parent, NULL); RzPanelsMenuItem *p_item = (RzPanelsMenuItem *)addr; int i; char tmpbuf[512]; for (i = 0; i < p_item->n_sub; i++) { RzPanelsMenuItem *sub = p_item->sub[i]; - ht_pp_delete(visual->panels->mht, rz_strf(tmpbuf, "%s.%s", parent, sub->name)); + ht_sp_delete(visual->panels->mht, rz_strf(tmpbuf, "%s.%s", parent, sub->name)); } p_item->sub = NULL; p_item->n_sub = 0; @@ -5106,11 +5106,6 @@ void __step_over_almighty_cb(void *user, RZ_UNUSED RzPanel *panel, RZ_UNUSED con __step_over_cb(user); } -void __mht_free_kv(HtPPKv *kv) { - free(kv->key); - __free_menu_item((RzPanelsMenuItem *)kv->value); -} - bool __init(RzCore *core, RzPanels *panels, int w, int h) { panels->panel = NULL; panels->n_panels = 0; @@ -5129,7 +5124,7 @@ bool __init(RzCore *core, RzPanels *panels, int w, int h) { panels->db = sdb_new0(); panels->rotate_db = sdb_new0(); panels->almighty_db = sdb_new0(); - panels->mht = ht_pp_new(NULL, (HtPPKvFreeFunc)__mht_free_kv, (HtPPCalcSizeV)strlen); + panels->mht = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)__free_menu_item); panels->prevMode = PANEL_MODE_DEFAULT; panels->name = NULL; panels->first_run = true; diff --git a/librz/debug/debug.c b/librz/debug/debug.c index 25019008a30..9a4474f3a92 100644 --- a/librz/debug/debug.c +++ b/librz/debug/debug.c @@ -366,10 +366,6 @@ static const char *rz_debug_str_callback(RzNum *userptr, ut64 off, int *ok) { return NULL; } -void free_tracenodes_kv(HtUPKv *kv) { - free(kv->value); -} - RZ_API RZ_OWN RzDebug *rz_debug_new(RZ_BORROW RZ_NONNULL RzBreakpointContext *bp_ctx) { rz_return_val_if_fail(bp_ctx, NULL); RzDebug *dbg = RZ_NEW0(RzDebug); @@ -394,7 +390,7 @@ RZ_API RZ_OWN RzDebug *rz_debug_new(RZ_BORROW RZ_NONNULL RzBreakpointContext *bp dbg->pid = -1; dbg->tid = -1; dbg->tree = rz_tree_new(); - dbg->tracenodes = ht_up_new(NULL, free_tracenodes_kv, NULL); + dbg->tracenodes = ht_up_new(NULL, free); dbg->swstep = false; dbg->stop_all_threads = false; dbg->trace = rz_debug_trace_new(); @@ -424,7 +420,7 @@ RZ_API RZ_OWN RzDebug *rz_debug_new(RZ_BORROW RZ_NONNULL RzBreakpointContext *bp RZ_API void rz_debug_tracenodes_reset(RzDebug *dbg) { ht_up_free(dbg->tracenodes); - dbg->tracenodes = ht_up_new(NULL, free_tracenodes_kv, NULL); + dbg->tracenodes = ht_up_new(NULL, free); } RZ_API RzDebug *rz_debug_free(RzDebug *dbg) { diff --git a/librz/debug/dsession.c b/librz/debug/dsession.c index 8bf2f707467..5a8ed0ba00f 100644 --- a/librz/debug/dsession.c +++ b/librz/debug/dsession.c @@ -26,10 +26,6 @@ static void rz_debug_checkpoint_fini(void *element, void *user) { rz_list_free(checkpoint->snaps); } -static void htup_vector_free(HtUPKv *kv) { - rz_vector_free(kv->value); -} - RZ_API RzDebugSession *rz_debug_session_new(void) { RzDebugSession *session = RZ_NEW0(RzDebugSession); if (!session) { @@ -41,12 +37,12 @@ RZ_API RzDebugSession *rz_debug_session_new(void) { rz_debug_session_free(session); return NULL; } - session->registers = ht_up_new(NULL, htup_vector_free, NULL); + session->registers = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); if (!session->registers) { rz_debug_session_free(session); return NULL; } - session->memory = ht_up_new(NULL, htup_vector_free, NULL); + session->memory = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); if (!session->memory) { rz_debug_session_free(session); return NULL; diff --git a/librz/debug/trace.c b/librz/debug/trace.c index 0836eb1871d..0d14ea9b718 100644 --- a/librz/debug/trace.c +++ b/librz/debug/trace.c @@ -18,7 +18,7 @@ RZ_API RzDebugTrace *rz_debug_trace_new(void) { return NULL; } t->traces->free = free; - t->ht = ht_pp_new0(); + t->ht = ht_sp_new(HT_STR_DUP, NULL, NULL); if (!t->ht) { rz_debug_trace_free(t); return NULL; @@ -32,7 +32,7 @@ RZ_API void rz_debug_trace_free(RzDebugTrace *trace) { } rz_list_purge(trace->traces); free(trace->traces); - ht_pp_free(trace->ht); + ht_sp_free(trace->ht); RZ_FREE(trace); } @@ -214,7 +214,7 @@ RZ_API void rz_debug_trace_at(RzDebug *dbg, const char *str) { RZ_API RzDebugTracepoint *rz_debug_trace_get(RzDebug *dbg, ut64 addr) { char tmpbuf[64]; int tag = dbg->trace->tag; - return ht_pp_find(dbg->trace->ht, + return ht_sp_find(dbg->trace->ht, rz_strf(tmpbuf, "trace.%d.%" PFMT64x, tag, addr), NULL); } @@ -292,7 +292,7 @@ RZ_API RzDebugTracepoint *rz_debug_trace_add(RzDebug *dbg, ut64 addr, int size) tp->count = ++dbg->trace->count; tp->times = 1; rz_list_append(dbg->trace->traces, tp); - ht_pp_update(dbg->trace->ht, + ht_sp_update(dbg->trace->ht, rz_strf(tmpbuf, "trace.%d.%" PFMT64x, tag, addr), tp); return tp; } @@ -300,8 +300,8 @@ RZ_API RzDebugTracepoint *rz_debug_trace_add(RzDebug *dbg, ut64 addr, int size) RZ_API void rz_debug_trace_reset(RzDebug *dbg) { RzDebugTrace *t = dbg->trace; rz_list_purge(t->traces); - ht_pp_free(t->ht); - t->ht = ht_pp_new0(); + ht_sp_free(t->ht); + t->ht = ht_sp_new(HT_STR_DUP, NULL, NULL); t->traces = rz_list_new(); t->traces->free = free; } diff --git a/librz/diff/diff.c b/librz/diff/diff.c index 4bf15da7d67..b9a071efb74 100644 --- a/librz/diff/diff.c +++ b/librz/diff/diff.c @@ -131,7 +131,7 @@ static bool set_a(RzDiff *diff, const void *a, ut32 a_size) { return true; } -static void free_hits(HtPPKv *kv) { +static void fini_hits_kv(HtPPKv *kv, RZ_UNUSED void *user) { rz_list_free(kv->value); } @@ -146,12 +146,19 @@ static bool set_b(RzDiff *diff, const void *b, ut32 b_size) { RzDiffMethodIgnore ignore = diff->methods.ignore; /* we need to generate the hits list for B */ + HtPPOptions opts = { + .cmp = diff->methods.compare, + .hashfn = diff->methods.elem_hash, + .dupkey = NULL, // avoid to duplicate key + .dupvalue = NULL, + .calcsizeK = default_ksize, + .calcsizeV = NULL, + .finiKV = fini_hits_kv, + .finiKV_user = NULL, + .elem_size = 0, + }; ht_pp_free(diff->b_hits); - diff->b_hits = ht_pp_new(NULL, free_hits, NULL); - diff->b_hits->opt.cmp /* */ = diff->methods.compare; - diff->b_hits->opt.calcsizeK /**/ = default_ksize; - diff->b_hits->opt.dupkey /* */ = NULL; // avoid to duplicate key - diff->b_hits->opt.hashfn /* */ = diff->methods.elem_hash; + diff->b_hits = ht_pp_new_opt(&opts); for (ut64 i = 0; i < diff->b_size; ++i) { const void *elem = elem_at(diff->b, i); @@ -378,7 +385,7 @@ static RzDiffMatch *find_longest_match(RzDiff *diff, Block *block) { ut32 hit_b = b_low; ut32 hit_size = 0; - len_map = ht_uu_new0(); + len_map = ht_uu_new(); if (!len_map) { RZ_LOG_ERROR("find_longest_match: cannot allocate len_map\n"); goto find_longest_match_fail; @@ -386,7 +393,7 @@ static RzDiffMatch *find_longest_match(RzDiff *diff, Block *block) { for (ut32 a_pos = a_low; a_pos < a_hi; ++a_pos) { elem_a = elem_at(a, a_pos); - tmp = ht_uu_new0(); + tmp = ht_uu_new(); if (!tmp) { RZ_LOG_ERROR("find_longest_match: cannot allocate tmp\n"); goto find_longest_match_fail; diff --git a/librz/flag/flag.c b/librz/flag/flag.c index 35ee385c090..1baee1dff65 100644 --- a/librz/flag/flag.c +++ b/librz/flag/flag.c @@ -50,7 +50,7 @@ static ut64 num_callback(RzNum *user, const char *name, int *ok) { if (ok) { *ok = 0; } - RzFlagItem *item = ht_pp_find(f->ht_name, name, NULL); + RzFlagItem *item = ht_sp_find(f->ht_name, name, NULL); if (item) { // NOTE: to avoid warning infinite loop here we avoid recursivity if (item->alias) { @@ -171,8 +171,8 @@ static bool update_flag_item_name(RzFlag *f, RzFlagItem *item, const char *newna return false; } bool res = (item->name) - ? ht_pp_update_key(f->ht_name, item->name, fname) - : ht_pp_insert(f->ht_name, fname, item); + ? ht_sp_update_key(f->ht_name, item->name, fname) + : ht_sp_insert(f->ht_name, fname, item); if (res) { set_name(item, fname); return true; @@ -181,11 +181,6 @@ static bool update_flag_item_name(RzFlag *f, RzFlagItem *item, const char *newna return false; } -static void ht_free_flag(HtPPKv *kv) { - free(kv->key); - rz_flag_item_free(kv->value); -} - static bool count_flags(RzFlagItem *fi, void *user) { int *count = (int *)user; (*count)++; @@ -229,7 +224,7 @@ RZ_API RzFlag *rz_flag_new(void) { } f->zones = NULL; f->tags = sdb_new0(); - f->ht_name = ht_pp_new(NULL, ht_free_flag, NULL); + f->ht_name = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_flag_item_free); f->by_off = rz_skiplist_new(flag_skiplist_free, flag_skiplist_cmp); rz_list_free(f->zones); new_spaces(f); @@ -270,7 +265,7 @@ RZ_API void rz_flag_item_free(RzFlagItem *item) { RZ_API RzFlag *rz_flag_free(RzFlag *f) { rz_return_val_if_fail(f, NULL); rz_skiplist_free(f->by_off); - ht_pp_free(f->ht_name); + ht_sp_free(f->ht_name); sdb_free(f->tags); rz_spaces_fini(&f->spaces); rz_num_free(f->num); @@ -308,7 +303,7 @@ RZ_API bool rz_flag_exist_at(RzFlag *f, const char *flag_prefix, ut16 fp_size, u * Otherwise, NULL is returned. */ RZ_API RzFlagItem *rz_flag_get(RzFlag *f, const char *name) { rz_return_val_if_fail(f, NULL); - RzFlagItem *r = ht_pp_find(f->ht_name, name, NULL); + RzFlagItem *r = ht_sp_find(f->ht_name, name, NULL); return r ? evalFlag(f, r) : NULL; } @@ -711,7 +706,7 @@ RZ_API int rz_flag_rename(RzFlag *f, RzFlagItem *item, const char *name) { RZ_API bool rz_flag_unset(RzFlag *f, RzFlagItem *item) { rz_return_val_if_fail(f && item, false); remove_offsetmap(f, item); - ht_pp_delete(f->ht_name, item->name); + ht_sp_delete(f->ht_name, item->name); return true; } @@ -733,7 +728,7 @@ struct unset_off_foreach_t { ut64 offset; }; -static bool unset_off_foreach(void *user, const void *k, const void *v) { +static bool unset_off_foreach(void *user, const char *k, const void *v) { struct unset_off_foreach_t *u = (struct unset_off_foreach_t *)user; RzFlagItem *fi = (RzFlagItem *)v; if (u->offset == fi->offset) { @@ -749,7 +744,7 @@ static bool unset_off_foreach(void *user, const void *k, const void *v) { RZ_API bool rz_flag_unset_all_off(RzFlag *f, ut64 off) { rz_return_val_if_fail(f, false); struct unset_off_foreach_t u = { f, off }; - ht_pp_foreach(f->ht_name, unset_off_foreach, &u); + ht_sp_foreach(f->ht_name, unset_off_foreach, &u); return true; } @@ -783,15 +778,15 @@ RZ_API int rz_flag_unset_glob(RzFlag *f, const char *glob) { * returns true if the item is found and unset, false otherwise. */ RZ_API bool rz_flag_unset_name(RzFlag *f, const char *name) { rz_return_val_if_fail(f, false); - RzFlagItem *item = ht_pp_find(f->ht_name, name, NULL); + RzFlagItem *item = ht_sp_find(f->ht_name, name, NULL); return item && rz_flag_unset(f, item); } /* unset all flag items in the RzFlag f */ RZ_API void rz_flag_unset_all(RzFlag *f) { rz_return_if_fail(f); - ht_pp_free(f->ht_name); - f->ht_name = ht_pp_new(NULL, ht_free_flag, NULL); + ht_sp_free(f->ht_name); + f->ht_name = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_flag_item_free); rz_skiplist_purge(f->by_off); rz_spaces_fini(&f->spaces); new_spaces(f); diff --git a/librz/il/definitions/variable.c b/librz/il/definitions/variable.c index 56b9a886576..f554c77dbcc 100644 --- a/librz/il/definitions/variable.c +++ b/librz/il/definitions/variable.c @@ -39,16 +39,6 @@ RZ_API void rz_il_variable_free(RZ_NULLABLE RzILVar *var) { // Variable Set -static void var_ht_free(HtPPKv *kv) { - free(kv->key); - rz_il_variable_free(kv->value); -} - -static void val_ht_free(HtPPKv *kv) { - free(kv->key); - rz_il_value_free(kv->value); -} - /** * Initialize \p vs as an empty variable set * @@ -60,13 +50,13 @@ static void val_ht_free(HtPPKv *kv) { RZ_API bool rz_il_var_set_init(RzILVarSet *vs) { rz_return_val_if_fail(vs, false); memset(vs, 0, sizeof(*vs)); - vs->vars = ht_pp_new(NULL, var_ht_free, NULL); + vs->vars = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_il_variable_free); if (!vs->vars) { return false; } - vs->contents = ht_pp_new(NULL, val_ht_free, NULL); + vs->contents = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_il_value_free); if (!vs->contents) { - ht_pp_free(vs->vars); + ht_sp_free(vs->vars); vs->vars = NULL; return false; } @@ -74,8 +64,8 @@ RZ_API bool rz_il_var_set_init(RzILVarSet *vs) { } RZ_API void rz_il_var_set_fini(RzILVarSet *vs) { - ht_pp_free(vs->vars); - ht_pp_free(vs->contents); + ht_sp_free(vs->vars); + ht_sp_free(vs->contents); } RZ_API void rz_il_var_set_reset(RzILVarSet *vs) { @@ -89,14 +79,14 @@ RZ_API void rz_il_var_set_reset(RzILVarSet *vs) { */ RZ_API RZ_BORROW RzILVar *rz_il_var_set_create_var(RzILVarSet *vs, const char *name, RzILSortPure sort) { rz_return_val_if_fail(vs && name, NULL); - if (ht_pp_find(vs->vars, name, NULL)) { + if (ht_sp_find(vs->vars, name, NULL)) { return NULL; } RzILVar *var = rz_il_variable_new(name, sort); if (!var) { return NULL; } - ht_pp_insert(vs->vars, name, var); + ht_sp_insert(vs->vars, name, var); return var; } @@ -106,14 +96,14 @@ RZ_API RZ_BORROW RzILVar *rz_il_var_set_create_var(RzILVarSet *vs, const char *n */ RZ_API RZ_OWN RZ_NULLABLE RzILVal *rz_il_var_set_remove_var(RzILVarSet *vs, const char *name) { rz_return_val_if_fail(vs && name, NULL); - ht_pp_delete(vs->vars, name); - HtPPKv *kv = ht_pp_find_kv(vs->contents, name, NULL); + ht_sp_delete(vs->vars, name); + HtSPKv *kv = ht_sp_find_kv(vs->contents, name, NULL); if (!kv) { return NULL; } RzILVal *r = kv->value; kv->value = NULL; - ht_pp_delete(vs->contents, name); + ht_sp_delete(vs->contents, name); return r; } @@ -128,7 +118,7 @@ RZ_API RZ_OWN RZ_NULLABLE RzILVal *rz_il_var_set_remove_var(RzILVarSet *vs, cons */ RZ_API bool rz_il_var_set_bind(RzILVarSet *vs, const char *name, RZ_OWN RzILVal *val) { rz_return_val_if_fail(vs && name && val, false); - RzILVar *var = ht_pp_find(vs->vars, name, NULL); + RzILVar *var = ht_sp_find(vs->vars, name, NULL); if (!var || !rz_il_sort_pure_eq(var->sort, rz_il_value_get_sort(val))) { if (!var) { RZ_LOG_ERROR("Attempted to bind value to non-existent variable \"%s\"\n", name); @@ -138,7 +128,7 @@ RZ_API bool rz_il_var_set_bind(RzILVarSet *vs, const char *name, RZ_OWN RzILVal rz_il_value_free(val); return false; } - ht_pp_update(vs->contents, name, val); + ht_sp_update(vs->contents, name, val); return true; } @@ -146,10 +136,10 @@ RZ_API bool rz_il_var_set_bind(RzILVarSet *vs, const char *name, RZ_OWN RzILVal * Get the definition of the variable called \p name */ RZ_API RZ_BORROW RzILVar *rz_il_var_set_get(RzILVarSet *vs, const char *name) { - return ht_pp_find(vs->vars, name, NULL); + return ht_sp_find(vs->vars, name, NULL); } -static bool vars_collect_cb(void *user, const void *k, const void *v) { +static bool vars_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { rz_pvector_push(user, (void *)v); return true; } @@ -163,7 +153,7 @@ RZ_API RZ_OWN RzPVector /**/ *rz_il_var_set_get_all(RzILVarSet *vs) { if (!r) { return NULL; } - ht_pp_foreach(vs->vars, vars_collect_cb, r); + ht_sp_foreach(vs->vars, vars_collect_cb, r); return r; } @@ -172,7 +162,7 @@ RZ_API RZ_OWN RzPVector /**/ *rz_il_var_set_get_all(RzILVarSet *vs) { */ RZ_API RZ_BORROW RzILVal *rz_il_var_set_get_value(RzILVarSet *vs, const char *name) { rz_return_val_if_fail(vs && name, NULL); - return ht_pp_find(vs->contents, name, NULL); + return ht_sp_find(vs->contents, name, NULL); } /** diff --git a/librz/il/il_validate.c b/librz/il/il_validate.c index f191a0dabfa..a74cec42f8b 100644 --- a/librz/il/il_validate.c +++ b/librz/il/il_validate.c @@ -11,20 +11,11 @@ * Global (immutable) context */ struct rz_il_validate_global_context_t { - HtPP /**/ *global_vars; + HtSP /**/ *global_vars; HtUU /**/ *mems; ut32 pc_len; }; /* RzILValidateGlobalContext */ -static void var_kv_free(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - -static void var_kv_unown_free(HtPPKv *kv) { - free(kv->key); -} - /** * Create a new global context for validation * Vars and mems can be added manually with rz_il_validate_global_context_add_* functions. @@ -36,14 +27,14 @@ RZ_API RzILValidateGlobalContext *rz_il_validate_global_context_new_empty(ut32 p return NULL; } ctx->pc_len = pc_len; - ctx->global_vars = ht_pp_new(NULL, var_kv_free, NULL); + ctx->global_vars = ht_sp_new(HT_STR_DUP, NULL, free); if (!ctx->global_vars) { free(ctx); return NULL; } - ctx->mems = ht_uu_new0(); + ctx->mems = ht_uu_new(); if (!ctx->mems) { - ht_pp_free(ctx->global_vars); + ht_sp_free(ctx->global_vars); free(ctx); return NULL; } @@ -60,7 +51,7 @@ RZ_API void rz_il_validate_global_context_add_var(RzILValidateGlobalContext *ctx return; } *hts = sort; - ht_pp_update(ctx->global_vars, name, hts); + ht_sp_update(ctx->global_vars, name, hts); } /** @@ -100,7 +91,7 @@ RZ_API void rz_il_validate_global_context_free(RzILValidateGlobalContext *ctx) { if (!ctx) { return; } - ht_pp_free(ctx->global_vars); + ht_sp_free(ctx->global_vars); ht_uu_free(ctx->mems); free(ctx); } @@ -114,20 +105,20 @@ typedef struct { * This must always be a superset of `local_vars_available`. * This owns all values, local_vars_available borrows them. */ - HtPP /**/ *local_vars_known; + HtSP /**/ *local_vars_known; - HtPP /**/ *local_vars_available; ///< vars that can be accessed right now + HtSP /**/ *local_vars_available; ///< vars that can be accessed right now } LocalContext; static bool local_context_init(LocalContext *ctx, const RzILValidateGlobalContext *global_ctx) { ctx->global_ctx = global_ctx; - ctx->local_vars_known = ht_pp_new(NULL, var_kv_free, NULL); + ctx->local_vars_known = ht_sp_new(HT_STR_DUP, NULL, free); if (!ctx->local_vars_known) { return false; } - ctx->local_vars_available = ht_pp_new(NULL, var_kv_unown_free, NULL); + ctx->local_vars_available = ht_sp_new(HT_STR_DUP, NULL, NULL); if (!ctx->local_vars_available) { - ht_pp_free(ctx->local_vars_known); + ht_sp_free(ctx->local_vars_known); ctx->local_vars_known = NULL; return false; } @@ -135,29 +126,29 @@ static bool local_context_init(LocalContext *ctx, const RzILValidateGlobalContex } static void local_context_fini(LocalContext *ctx) { - ht_pp_free(ctx->local_vars_known); - ht_pp_free(ctx->local_vars_available); + ht_sp_free(ctx->local_vars_known); + ht_sp_free(ctx->local_vars_available); ctx->local_vars_known = NULL; ctx->local_vars_available = NULL; } -static bool local_var_copy_known_cb(RZ_NONNULL void *user, const void *k, const void *v) { +static bool local_var_copy_known_cb(RZ_NONNULL void *user, const char *k, const void *v) { LocalContext *dst = user; RzILSortPure *sort = RZ_NEW(RzILSortPure); if (!sort) { return false; } *sort = *(RzILSortPure *)v; - ht_pp_update(dst->local_vars_known, k, sort); + ht_sp_update(dst->local_vars_known, k, sort); return true; } -static bool local_var_copy_avail_cb(RZ_NONNULL void *user, const void *k, const void *v) { +static bool local_var_copy_avail_cb(RZ_NONNULL void *user, const char *k, const void *v) { LocalContext *dst = user; - RzILSortPure *sort = ht_pp_find(dst->local_vars_known, k, NULL); + RzILSortPure *sort = ht_sp_find(dst->local_vars_known, k, NULL); // known is superset of avail, so we can assert this: rz_return_val_if_fail(sort && rz_il_sort_pure_eq(*sort, *(RzILSortPure *)v), false); - ht_pp_update(dst->local_vars_available, k, sort); + ht_sp_update(dst->local_vars_available, k, sort); return true; } @@ -165,8 +156,8 @@ static bool local_context_copy(LocalContext *dst, LocalContext *src) { if (!local_context_init(dst, src->global_ctx)) { return false; } - ht_pp_foreach(src->local_vars_known, local_var_copy_known_cb, dst); - ht_pp_foreach(src->local_vars_available, local_var_copy_avail_cb, dst); + ht_sp_foreach(src->local_vars_known, local_var_copy_known_cb, dst); + ht_sp_foreach(src->local_vars_available, local_var_copy_avail_cb, dst); return true; } @@ -179,10 +170,10 @@ typedef struct { } LocalContextMeet; // called on src, take the union of the known types or fail if they don't agree -static bool local_var_meet_known_cb(RZ_NONNULL void *user, const void *k, const void *v) { +static bool local_var_meet_known_cb(RZ_NONNULL void *user, const char *k, const void *v) { LocalContextMeet *meet = user; RzILSortPure src_sort = *(RzILSortPure *)v; - RzILSortPure *dst_sort = ht_pp_find(meet->dst->local_vars_known, k, NULL); + RzILSortPure *dst_sort = ht_sp_find(meet->dst->local_vars_known, k, NULL); if (dst_sort && !rz_il_sort_pure_eq(src_sort, *dst_sort)) { char *src_sort_s = rz_il_sort_pure_stringify(src_sort); char *dst_sort_s = rz_il_sort_pure_stringify(*dst_sort); @@ -200,17 +191,17 @@ static bool local_var_meet_known_cb(RZ_NONNULL void *user, const void *k, const return false; } *dst_sort = src_sort; - ht_pp_update(meet->dst->local_vars_known, k, dst_sort); + ht_sp_update(meet->dst->local_vars_known, k, dst_sort); } return true; } // called on dst, remove all vars from dst that do not appear in src (intersection) -static bool local_var_meet_avail_cb(RZ_NONNULL void *user, const void *k, const void *v) { +static bool local_var_meet_avail_cb(RZ_NONNULL void *user, const char *k, const void *v) { LocalContextMeet *meet = user; - RzILSortPure *src_sort = ht_pp_find(meet->src->local_vars_available, k, NULL); + RzILSortPure *src_sort = ht_sp_find(meet->src->local_vars_available, k, NULL); if (!src_sort) { - ht_pp_delete(meet->dst->local_vars_available, k); + ht_sp_delete(meet->dst->local_vars_available, k); } return true; } @@ -236,11 +227,11 @@ static bool local_context_meet(RZ_INOUT LocalContext *a, RZ_IN LocalContext *b, .dst = a, .src = b }; - ht_pp_foreach(b->local_vars_known, local_var_meet_known_cb, &meet); + ht_sp_foreach(b->local_vars_known, local_var_meet_known_cb, &meet); if (meet.failed) { return false; } - ht_pp_foreach(a->local_vars_available, local_var_meet_avail_cb, &meet); + ht_sp_foreach(a->local_vars_available, local_var_meet_avail_cb, &meet); return true; } @@ -296,13 +287,13 @@ VALIDATOR_PURE(var) { VALIDATOR_ASSERT(args->v, "Var name of var op is NULL.\n"); switch (args->kind) { case RZ_IL_VAR_KIND_GLOBAL: { - RzILSortPure *sort = ht_pp_find(ctx->global_ctx->global_vars, args->v, NULL); + RzILSortPure *sort = ht_sp_find(ctx->global_ctx->global_vars, args->v, NULL); VALIDATOR_ASSERT(sort, "Global variable \"%s\" referenced by var op does not exist.\n", args->v); *sort_out = *sort; return true; } case RZ_IL_VAR_KIND_LOCAL: { - RzILSortPure *sort = ht_pp_find(ctx->local_vars_available, args->v, NULL); + RzILSortPure *sort = ht_sp_find(ctx->local_vars_available, args->v, NULL); VALIDATOR_ASSERT(sort, "Local variable \"%s\" is not available at var op.\n", args->v); *sort_out = *sort; return true; @@ -926,7 +917,7 @@ VALIDATOR_EFFECT(set) { VALIDATOR_ASSERT(args->v, "Var name of set op is NULL.\n"); RzILSortPure sx; VALIDATOR_DESCEND_PURE(args->x, &sx); - RzILSortPure *sort = ht_pp_find( + RzILSortPure *sort = ht_sp_find( args->is_local ? ctx->local_vars_known : ctx->global_ctx->global_vars, args->v, NULL); VALIDATOR_ASSERT(args->is_local || sort, "Global variable \"%s\" referenced by set op does not exist.\n", args->v); if (sort && !rz_il_sort_pure_eq(*sort, sx)) { @@ -946,9 +937,9 @@ VALIDATOR_EFFECT(set) { return false; } *sort = sx; - ht_pp_update(ctx->local_vars_known, args->v, sort); + ht_sp_update(ctx->local_vars_known, args->v, sort); } - ht_pp_update(ctx->local_vars_available, args->v, sort); + ht_sp_update(ctx->local_vars_available, args->v, sort); } *type_out = RZ_IL_TYPE_EFFECT_DATA; return true; @@ -1077,7 +1068,7 @@ static bool validate_effect(VALIDATOR_EFFECT_ARGS) { * \return whether the given op is valid under \p ctx */ RZ_API bool rz_il_validate_effect(RZ_NULLABLE RzILOpEffect *op, RZ_NONNULL RzILValidateGlobalContext *ctx, - RZ_NULLABLE RZ_OUT HtPP /**/ **local_var_sorts_out, + RZ_NULLABLE RZ_OUT HtSP /**/ **local_var_sorts_out, RZ_NULLABLE RZ_OUT RzILTypeEffect *type_out, RZ_NULLABLE RZ_OUT RzILValidateReport *report_out) { LocalContext local_ctx; diff --git a/librz/il/il_vm.c b/librz/il/il_vm.c index 0f205aab2cd..dc153857f1e 100644 --- a/librz/il/il_vm.c +++ b/librz/il/il_vm.c @@ -13,11 +13,6 @@ extern RZ_IPI RzILOpPureHandler rz_il_op_handler_pure_table_default[RZ_IL_OP_PURE_MAX]; extern RZ_IPI RzILOpEffectHandler rz_il_op_handler_effect_table_default[RZ_IL_OP_EFFECT_MAX]; -static void free_label_kv(HtPPKv *kv) { - free(kv->key); - rz_il_effect_label_free(kv->value); -} - /** * initiate an empty VM * \param vm RzILVM, pointer to an empty VM @@ -41,18 +36,7 @@ RZ_API bool rz_il_vm_init(RzILVM *vm, ut64 start_addr, ut32 addr_size, bool big_ } rz_pvector_init(&vm->vm_memory, (RzPVectorFree)rz_il_mem_free); - // Key : string - // Val : RzILEffectLabel - // Do not dump it since its single signed here, and will be free in `close` - HtPPOptions lbl_options = { 0 }; - lbl_options.cmp = (HtPPListComparator)strcmp; - lbl_options.hashfn = (HtPPHashFunction)sdb_hash; - lbl_options.dupkey = (HtPPDupKey)strdup; - lbl_options.dupvalue = NULL; - lbl_options.freefn = (HtPPKvFreeFunc)free_label_kv; - lbl_options.elem_size = sizeof(HtPPKv); - lbl_options.calcsizeK = (HtPPCalcSizeK)strlen; - vm->vm_global_label_table = ht_pp_new_opt(&lbl_options); + vm->vm_global_label_table = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_il_effect_label_free); if (!vm->vm_global_label_table) { RZ_LOG_ERROR("RzIL: cannot allocate VM label hashmap\n"); rz_il_vm_fini(vm); @@ -97,7 +81,7 @@ RZ_API void rz_il_vm_fini(RzILVM *vm) { rz_pvector_fini(&vm->vm_memory); - ht_pp_free(vm->vm_global_label_table); + ht_sp_free(vm->vm_global_label_table); vm->vm_global_label_table = NULL; free(vm->op_handler_pure_table); @@ -275,7 +259,7 @@ RZ_API RZ_BORROW RzILVal *rz_il_vm_get_var_value(RZ_NONNULL RzILVM *vm, RzILVarK RZ_API RZ_BORROW RzBitVector *rz_il_hash_find_addr_by_lblname(RZ_NONNULL RzILVM *vm, RZ_NONNULL const char *lbl_name) { rz_return_val_if_fail(vm && lbl_name, NULL); bool found = false; - RzILEffectLabel *label = ht_pp_find(vm->vm_global_label_table, lbl_name, &found); + RzILEffectLabel *label = ht_sp_find(vm->vm_global_label_table, lbl_name, &found); if (!found) { return NULL; } @@ -290,12 +274,12 @@ RZ_API RZ_BORROW RzBitVector *rz_il_hash_find_addr_by_lblname(RZ_NONNULL RzILVM */ RZ_API RZ_BORROW RzILEffectLabel *rz_il_vm_find_label_by_name(RZ_NONNULL RzILVM *vm, RZ_NONNULL const char *lbl_name) { rz_return_val_if_fail(vm && lbl_name, NULL); - return ht_pp_find(vm->vm_global_label_table, lbl_name, NULL); + return ht_sp_find(vm->vm_global_label_table, lbl_name, NULL); } RZ_API void rz_il_vm_add_label(RZ_NONNULL RzILVM *vm, RZ_NONNULL RzILEffectLabel *label) { rz_return_if_fail(vm && label); - ht_pp_update(vm->vm_global_label_table, label->label_id, label); + ht_sp_update(vm->vm_global_label_table, label->label_id, label); } /** @@ -335,7 +319,7 @@ RZ_API RZ_BORROW RzILEffectLabel *rz_il_vm_create_label_lazy(RZ_NONNULL RzILVM * */ RZ_API RZ_BORROW RzILEffectLabel *rz_il_vm_update_label(RZ_NONNULL RzILVM *vm, RZ_NONNULL char *name, RZ_NONNULL RZ_BORROW RzBitVector *addr) { rz_return_val_if_fail(vm && name && addr, NULL); - RzILEffectLabel *lbl = ht_pp_find(vm->vm_global_label_table, name, NULL); + RzILEffectLabel *lbl = ht_sp_find(vm->vm_global_label_table, name, NULL); if (lbl->addr) { rz_bv_free(lbl->addr); } diff --git a/librz/include/meson.build b/librz/include/meson.build index 47a90bcfd4f..77fd0bc9417 100644 --- a/librz/include/meson.build +++ b/librz/include/meson.build @@ -125,6 +125,9 @@ rz_util_files = [ 'rz_util/ht_pu.h', 'rz_util/ht_up.h', 'rz_util/ht_uu.h', + 'rz_util/ht_sp.h', + 'rz_util/ht_ss.h', + 'rz_util/ht_su.h', 'rz_util/set.h', ] install_headers(rz_util_files, install_dir: join_paths(rizin_incdir, 'rz_util')) diff --git a/librz/include/rz_agraph.h b/librz/include/rz_agraph.h index 59770363569..7d168e00a69 100644 --- a/librz/include/rz_agraph.h +++ b/librz/include/rz_agraph.h @@ -50,7 +50,7 @@ typedef struct rz_ascii_graph_t { const RzGraphNode *curnode; char *title; Sdb *db; - HtPP *nodes; // HT with title(key)=RzANode*(value) + HtSP *nodes; // HT with title(key)=RzANode*(value) RzList /**/ *dummy_nodes; int layout; diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index bd9cf62de0b..31c97a4cfde 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -153,7 +153,7 @@ typedef struct rz_analysis_function_t { const char *cc; // calling convention, should come from RzAnalysis.constpool ut64 addr; HtUP /**/ *labels; - HtPP /**/ *label_addrs; + HtSP /**/ *label_addrs; RzPVector /**/ vars; RzType *ret_type; HtUP /*>*/ *inst_vars; // offset of instructions => the variables they access @@ -454,7 +454,7 @@ typedef struct { HtUP /**/ *callable_by_offset; ///< Store all callables parsed from DWARF by DIE offset HtUP /**/ *type_by_offset; ///< Store all RzType parsed from DWARF by DIE offset HtUP /**/ *base_type_by_offset; ///< Store all RzBaseType parsed from DWARF by DIE offset - HtPP /*>*/ *base_types_by_name; ///< Store all RzBaseType parsed from DWARF by DIE offset + HtSP /*>*/ *base_types_by_name; ///< Store all RzBaseType parsed from DWARF by DIE offset DWARF_RegisterMapping dwarf_register_mapping; ///< Store the mapping function between DWARF registers number and register name in current architecture RzBinDWARF *dw; ///< Holds ownership of RzBinDwarf, avoid releasing it prematurely SetU *visited; @@ -474,7 +474,7 @@ typedef struct rz_analysis_t { RBTree bb_tree; // all basic blocks by address. They can overlap each other, but must never start at the same address. RzList /**/ *fcns; HtUP *ht_addr_fun; // address => function - HtPP *ht_name_fun; // name => function + HtSP *ht_name_fun; // name => function RzReg *reg; ut8 *last_disasm_reg; RzSyscall *syscall; @@ -527,7 +527,7 @@ typedef struct rz_analysis_t { RzList /**/ *leaddrs; RzPlatformTarget *arch_target; RzPlatformTargetIndex *platform_target; - HtPP *ht_global_var; // global variables + HtSP *ht_global_var; // global variables RBTree global_var_tree; // global variables by address. must not overlap RzHash *hash; RzAnalysisDebugInfo *debug_info; ///< store all debug info parsed from DWARF, etc.. @@ -1157,7 +1157,7 @@ typedef struct rz_analysis_esil_t { ut64 cur; // used for carry-flagging and borrow-flagging ut8 lastsz; // in bits //used for signature-flag /* native ops and custom ops */ - HtPP *ops; + HtSP *ops; RzStrBuf current_opstr; RzIDStorage *sources; HtUP *interrupts; diff --git a/librz/include/rz_asm.h b/librz/include/rz_asm.h index a5235bd5b3e..020d8ed1fb6 100644 --- a/librz/include/rz_asm.h +++ b/librz/include/rz_asm.h @@ -6,6 +6,7 @@ #define RZ_ASM_H #include +#include #include #include // only for binding, no hard dep required #include @@ -119,7 +120,7 @@ typedef struct rz_asm_t { bool immsign; // Print signed immediates as negative values, not their unsigned representation. bool immdisp; // Display immediates with # symbol (for arm architectures). false = show hashs bool utf8; // Flag for plugins: Use utf-8 characters. - HtPP *flags; + HtSS *flags; int seggrn; bool pseudo; } RzAsm; diff --git a/librz/include/rz_bin.h b/librz/include/rz_bin.h index 8b7f306ab2c..a43d5d7efca 100644 --- a/librz/include/rz_bin.h +++ b/librz/include/rz_bin.h @@ -302,16 +302,16 @@ typedef struct rz_bin_object_t { * \brief Acceleration structure for fast access of the symbol for a given import. * This associates the name of every symbol where is_imported == true to the symbol itself. */ - HtPP /**/ *import_name_symbols; // currently only used for imports, but could be extended to all symbols if needed. + HtSP /**/ *import_name_symbols; // currently only used for imports, but could be extended to all symbols if needed. RzPVector /**/ *entries; RzPVector /**/ *fields; RzPVector /**/ *libs; RzBinRelocStorage *relocs; RzBinStrDb *strings; RzPVector /**/ *classes; - HtPP /**/ *name_to_class_object; - HtPP /**/ *glue_to_class_method; - HtPP /**/ *glue_to_class_field; + HtSP /**/ *name_to_class_object; + HtSP /**/ *glue_to_class_method; + HtSP /**/ *glue_to_class_field; HtUP /**/ *vaddr_to_class_method; RzBinSourceLineInfo *lines; RzPVector /**/ *mem; diff --git a/librz/include/rz_bin_source_line.h b/librz/include/rz_bin_source_line.h index 55d40570c88..de3fa1b2814 100644 --- a/librz/include/rz_bin_source_line.h +++ b/librz/include/rz_bin_source_line.h @@ -92,7 +92,7 @@ typedef struct { } RzBinSourceLineCacheItem; typedef struct { - HtPP /**/ *items; + HtSP /**/ *items; } RzBinSourceLineCache; typedef struct { diff --git a/librz/include/rz_cmd.h b/librz/include/rz_cmd.h index 44910fd7acc..21aa19354da 100644 --- a/librz/include/rz_cmd.h +++ b/librz/include/rz_cmd.h @@ -475,11 +475,11 @@ typedef struct rz_cmd_t { RzCmdNullCb nullcallback; RzCmdItem *cmds[UT8_MAX]; RzCmdAlias aliases; - HtPP *macros; ///< Map of macros (char *)name -> RzCmdMacro + HtSP *macros; ///< Map of macros (char *)name -> RzCmdMacro void *language; // used to store TSLanguage * HtUP *ts_symbols_ht; RzCmdDesc *root_cmd_desc; - HtPP *ht_cmds; + HtSP *ht_cmds; /** * True if a rz_cons_instance exists. When used from RzCore this is * commonly true. However, it can be used in tests to avoid access to diff --git a/librz/include/rz_config.h b/librz/include/rz_config.h index 39816814365..37224416a12 100644 --- a/librz/include/rz_config.h +++ b/librz/include/rz_config.h @@ -54,7 +54,7 @@ typedef struct rz_config_t { void *user; RzNum *num; RzList /**/ *nodes; - HtPP *ht; + HtSP *ht; } RzConfig; typedef struct rz_config_hold_num_t { diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index fde32e7b85d..ae562e95af9 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -898,7 +898,7 @@ RZ_API bool rz_core_bin_rebase(RZ_NONNULL RzCore *core, ut64 baddr); RZ_API void rz_core_bin_export_info(RzCore *core, int mode); RZ_API bool rz_core_binfiles_print(RzCore *core, RzCmdStateOutput *state); RZ_API bool rz_core_binfiles_delete(RzCore *core, RzBinFile *bf); -RZ_API RZ_OWN HtPP *rz_core_bin_create_digests(RzCore *core, ut64 paddr, ut64 size, RzList /**/ *digests); +RZ_API RZ_OWN HtSS *rz_core_bin_create_digests(RzCore *core, ut64 paddr, ut64 size, RzList /**/ *digests); RZ_API void rz_core_bin_print_source_line_sample(RzCore *core, const RzBinSourceLineSample *s, RzCmdStateOutput *state); RZ_API void rz_core_bin_print_source_line_info(RzCore *core, const RzBinSourceLineInfo *li, RzCmdStateOutput *state); diff --git a/librz/include/rz_debug.h b/librz/include/rz_debug.h index b372652d1dd..b0df51a6353 100644 --- a/librz/include/rz_debug.h +++ b/librz/include/rz_debug.h @@ -225,7 +225,7 @@ typedef struct rz_debug_trace_t { int dup; char *addresses; // TODO: add range here - HtPP *ht; + HtSP *ht; } RzDebugTrace; typedef struct rz_debug_tracepoint_t { diff --git a/librz/include/rz_flag.h b/librz/include/rz_flag.h index bd8e47f32c7..f6000495cb3 100644 --- a/librz/include/rz_flag.h +++ b/librz/include/rz_flag.h @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -49,7 +50,7 @@ typedef struct rz_flag_t { Sdb *tags; RzNum *num; RzSkipList *by_off; /* flags sorted by offset, value=RzFlagsAtOffset */ - HtPP *ht_name; /* hashmap key=item name, value=RzFlagItem * */ + HtSP *ht_name; /* hashmap key=item name, value=RzFlagItem * */ RzList /**/ *zones; } RzFlag; diff --git a/librz/include/rz_il/definitions/variable.h b/librz/include/rz_il/definitions/variable.h index 881bf3e543d..799d7a6c75e 100644 --- a/librz/include/rz_il/definitions/variable.h +++ b/librz/include/rz_il/definitions/variable.h @@ -7,6 +7,7 @@ #define RZ_IL_VARIABLE_H #include +#include #include #ifdef __cplusplus @@ -29,8 +30,8 @@ RZ_API void rz_il_variable_free(RZ_NULLABLE RzILVar *var); * This is meant only as a low-level container to be used in RzILVM. */ typedef struct rz_il_var_set_t { - HtPP /**/ *vars; - HtPP /**/ *contents; + HtSP /**/ *vars; + HtSP /**/ *contents; } RzILVarSet; RZ_API bool rz_il_var_set_init(RzILVarSet *vs); diff --git a/librz/include/rz_il/rz_il_validate.h b/librz/include/rz_il/rz_il_validate.h index aa97f1055a3..d200fff7be8 100644 --- a/librz/include/rz_il/rz_il_validate.h +++ b/librz/include/rz_il/rz_il_validate.h @@ -35,7 +35,7 @@ RZ_API void rz_il_validate_global_context_free(RzILValidateGlobalContext *ctx); RZ_API bool rz_il_validate_pure(RZ_NULLABLE RzILOpPure *op, RZ_NONNULL RzILValidateGlobalContext *ctx, RZ_NULLABLE RZ_OUT RzILSortPure *sort_out, RZ_NULLABLE RZ_OUT RzILValidateReport *report_out); RZ_API bool rz_il_validate_effect(RZ_NULLABLE RzILOpEffect *op, RZ_NONNULL RzILValidateGlobalContext *ctx, - RZ_NULLABLE RZ_OUT HtPP /**/ **local_var_sorts_out, + RZ_NULLABLE RZ_OUT HtSP /**/ **local_var_sorts_out, RZ_NULLABLE RZ_OUT RzILTypeEffect *type_out, RZ_NULLABLE RZ_OUT RzILValidateReport *report_out); diff --git a/librz/include/rz_il/rz_il_vm.h b/librz/include/rz_il/rz_il_vm.h index 3922d770214..2b8dbccae8b 100644 --- a/librz/include/rz_il/rz_il_vm.h +++ b/librz/include/rz_il/rz_il_vm.h @@ -9,6 +9,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -41,8 +42,8 @@ struct rz_il_vm_t { RzPVector /**/ vm_memory; ///< Memories available in the VM, by their index. May be sparse (contain NULLs). ut32 val_count, lab_count; ///< count for VM predefined things ut32 addr_size; ///< size of address space - HtPP *vm_global_label_table; ///< Hashtable to maintain the label and address - HtPP *vm_local_label_table; ///< Hashtable to maintain the label and address + HtSP *vm_global_label_table; ///< Hashtable to maintain the label and address + HtSP *vm_local_label_table; ///< Hashtable to maintain the label and address RzBitVector *pc; ///< Program Counter of VM RzILOpPureHandler *op_handler_pure_table; ///< Array of Handler, handler can be indexed by opcode RzILOpEffectHandler *op_handler_effect_table; ///< Array of Handler, handler can be indexed by opcode diff --git a/librz/include/rz_lib.h b/librz/include/rz_lib.h index c25b0e64f88..295edf4923f 100644 --- a/librz/include/rz_lib.h +++ b/librz/include/rz_lib.h @@ -3,7 +3,7 @@ #include "rz_types.h" #include "rz_list.h" -#include +#include #if __UNIX__ #include @@ -103,7 +103,7 @@ typedef struct rz_lib_t { char *symnamefunc; RzList /**/ *plugins; RzList /**/ *handlers; - HtPU *opened_dirs; ///< Hashtable to keep track of already opened directories + HtSU *opened_dirs; ///< Hashtable to keep track of already opened directories } RzLib; #define RZ_PLUGIN_CHECK_AND_ADD(plugins, plugin, py_type) \ diff --git a/librz/include/rz_list.h b/librz/include/rz_list.h index 2e77e8c4f06..0befc559e9f 100644 --- a/librz/include/rz_list.h +++ b/librz/include/rz_list.h @@ -3,6 +3,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/librz/include/rz_reg.h b/librz/include/rz_reg.h index 4a14c22853e..e060b5b14a6 100644 --- a/librz/include/rz_reg.h +++ b/librz/include/rz_reg.h @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -136,7 +137,7 @@ typedef struct rz_reg_set_t { RzRegArena *arena; RzList /**/ *pool; ///< RzRegArena RzList /**/ *regs; ///< RzRegItem - HtPP *ht_regs; ///< name:RzRegItem + HtSP *ht_regs; ///< name:RzRegItem RzListIter /**/ *cur; ut32 maskregstype; ///< which type of regs has this register set (logic mask with 1 << RZ_REG_TYPE_XXX) } RzRegSet; diff --git a/librz/include/rz_type.h b/librz/include/rz_type.h index df1fd3cbaa3..bd9a970eebf 100644 --- a/librz/include/rz_type.h +++ b/librz/include/rz_type.h @@ -30,9 +30,9 @@ typedef struct rz_type_parser_t RzTypeParser; typedef struct rz_type_db_t { void *user; - HtPP /**/ *types; //< name -> base type - HtPP /**/ *formats; //< name -> `pf` format - HtPP /**/ *callables; //< name -> RzCallable (function type) + HtSP /**/ *types; //< name -> base type + HtSS /**/ *formats; //< name -> `pf` format + HtSP /**/ *callables; //< name -> RzCallable (function type) RzTypeTarget *target; RzTypeParser *parser; RzNum *num; @@ -333,7 +333,7 @@ RZ_API ut64 rz_type_db_struct_member_offset(RZ_NONNULL const RzTypeDB *typedb, R // Type parser low-level API RZ_API RZ_OWN RzTypeParser *rz_type_parser_new(void); -RZ_API RZ_OWN RzTypeParser *rz_type_parser_init(HtPP *types, HtPP *callables); +RZ_API RZ_OWN RzTypeParser *rz_type_parser_init(HtSP *types, HtSP *callables); RZ_API void rz_type_parser_free(RZ_NONNULL RzTypeParser *parser); RZ_API void rz_type_parser_free_purge(RZ_NONNULL RzTypeParser *parser); diff --git a/librz/include/rz_util/ht_inc.h b/librz/include/rz_util/ht_inc.h index 53d5f4aff01..abcb18a1884 100644 --- a/librz/include/rz_util/ht_inc.h +++ b/librz/include/rz_util/ht_inc.h @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2016-2018 crowell // SPDX-FileCopyrightText: 2016-2018 pancake // SPDX-FileCopyrightText: 2016-2018 ret2libc +// SPDX-FileCopyrightText: 2024 pelijah // SPDX-License-Identifier: BSD-3-Clause #ifndef HT_TYPE @@ -16,6 +17,7 @@ #undef HT_NULL_VALUE #if HT_TYPE == 1 +// Hash table HtPP that has void* as key and void* as value #define HtName_(name) name##PP #define Ht_(name) ht_pp_##name #define HT_(name) HtPP##name @@ -24,6 +26,7 @@ #define KEY_TO_HASH(x) ((ut32)(uintptr_t)(x)) #define HT_NULL_VALUE NULL #elif HT_TYPE == 2 +// Hash table HtPU that has void* as key and ut64 as value #define HtName_(name) name##UP #define Ht_(name) ht_up_##name #define HT_(name) HtUP##name @@ -32,6 +35,7 @@ #define KEY_TO_HASH(x) ((ut32)(x)) #define HT_NULL_VALUE 0 #elif HT_TYPE == 3 +// Hash table HtUU that has ut64 as key and ut64 as value #define HtName_(name) name##UU #define Ht_(name) ht_uu_##name #define HT_(name) HtUU##name @@ -39,7 +43,8 @@ #define VALUE_TYPE ut64 #define KEY_TO_HASH(x) ((ut32)(x)) #define HT_NULL_VALUE 0 -#else +#elif HT_TYPE == 4 +// Hash table HtPU that has void* as key and ut64 as value #define HtName_(name) name##PU #define Ht_(name) ht_pu_##name #define HT_(name) HtPU##name @@ -47,9 +52,44 @@ #define VALUE_TYPE ut64 #define KEY_TO_HASH(x) ((ut32)(uintptr_t)(x)) #define HT_NULL_VALUE 0 +#elif HT_TYPE == 5 +// Hash table HtSP that has C-string as key and void* as value +#define HtName_(name) name##SP +#define Ht_(name) ht_sp_##name +#define HT_(name) HtSP##name +#define KEY_TYPE char * +#define VALUE_TYPE void * +#define KEY_TO_HASH(x) ((ut32)(uintptr_t)(x)) +#define HT_NULL_VALUE NULL +#elif HT_TYPE == 6 +// Hash table HtSS that has C-string as key and C-string as value +#define HtName_(name) name##SS +#define Ht_(name) ht_ss_##name +#define HT_(name) HtSS##name +#define KEY_TYPE char * +#define VALUE_TYPE char * +#define KEY_TO_HASH(x) ((ut32)(uintptr_t)(x)) +#define HT_NULL_VALUE NULL +#elif HT_TYPE == 7 +// Hash table HtSU that has C-string as key and ut64 as value +#define HtName_(name) name##SU +#define Ht_(name) ht_su_##name +#define HT_(name) HtSU##name +#define KEY_TYPE char * +#define VALUE_TYPE ut64 +#define KEY_TO_HASH(x) ((ut32)(uintptr_t)(x)) +#define HT_NULL_VALUE 0 +#endif + +#ifndef HT_STR_OPTION_DEFINED +#define HT_STR_OPTION_DEFINED +typedef enum { + HT_STR_DUP = 0, ///< String is copied when inserting into HT + HT_STR_OWN, ///< String ownership is transferred when inserting into HT + HT_STR_CONST ///< String is treated as constant and not copied when inserting into HT +} HtStrOption; #endif -#include "ls.h" #include /* Kv represents a single key/value element in the hashtable */ @@ -61,71 +101,79 @@ typedef struct Ht_(kv) { } HT_(Kv); -typedef void (*HT_(KvFreeFunc))(HT_(Kv) *); +typedef void (*HT_(FiniKv))(HT_(Kv) *kv, void *user); typedef KEY_TYPE (*HT_(DupKey))(const KEY_TYPE); typedef VALUE_TYPE (*HT_(DupValue))(const VALUE_TYPE); +typedef void (*HT_(FreeValue))(VALUE_TYPE val); typedef ut32 (*HT_(CalcSizeK))(const KEY_TYPE); typedef ut32 (*HT_(CalcSizeV))(const VALUE_TYPE); typedef ut32 (*HT_(HashFunction))(const KEY_TYPE); -typedef int (*HT_(ListComparator))(const KEY_TYPE, const KEY_TYPE); +typedef int (*HT_(Comparator))(const KEY_TYPE, const KEY_TYPE); typedef bool (*HT_(ForeachCallback))(void *user, const KEY_TYPE, const VALUE_TYPE); typedef struct Ht_(bucket_t) { - HT_(Kv) * arr; + HT_(Kv) *arr; ut32 count; } HT_(Bucket); -/* Options contain all the settings of the hashtable */ +/** + * Options contain all the settings of the hashtable. + */ typedef struct Ht_(options_t) { - HT_(ListComparator) - cmp; // Function for comparing values. Returns 0 if eq. - HT_(HashFunction) - hashfn; // Function for hashing items in the hash table. - HT_(DupKey) - dupkey; // Function for making a copy of key - HT_(DupValue) - dupvalue; // Function for making a copy of value - HT_(CalcSizeK) - calcsizeK; // Function to determine the key's size - HT_(CalcSizeV) - calcsizeV; // Function to determine the value's size - HT_(KvFreeFunc) - freefn; // Function to free the keyvalue store - size_t elem_size; // Size of each HtKv element (useful for subclassing like SdbKv) + HT_(Comparator) cmp; ///< RZ_NULLABLE. Function for comparing keys. + ///< Returns 0 if keys are equal. + ///< Function is invoked only if == operator applied to keys returns false. + HT_(HashFunction) hashfn; ///< RZ_NULLABLE. Function for hashing items in the hash table. + ///< If NULL KEY_TO_HASH macro is used. + HT_(DupKey) dupkey; ///< RZ_NULLABLE. Function for making a copy of key. + ///< If NULL simple assignment operator is used. + HT_(DupValue) dupvalue; ///< RZ_NULLABLE. Function for making a copy of value. + ///< If NULL simple assignment operator is used. + HT_(CalcSizeK) calcsizeK; ///< RZ_NULLABLE. Function to determine the key's size. + ///< If NULL zero value is used as a size. + ///< Key sizes are checked on equality during keys comparsion as a pre-check. + HT_(CalcSizeV) calcsizeV; ///< RZ_NULLABLE. Function to determine the value's size. + ///< If NULL zero value is used as a size. + ///< Not required for common scenarios. Could be used in subclasses. + HT_(FiniKv) finiKV; ///< RZ_NULLABLE. Function to clean up the key-value store. + void *finiKV_user; ///< RZ_NULLABLE. User data which is passed into finiKV. + size_t elem_size; ///< Size of each HtKv element (useful for subclassing like SdbKv). + ///< Zero value means to use default size of HtKv. } HT_(Options); /* Ht is the hashtable structure */ typedef struct Ht_(t) { - ut32 size; // size of the hash table in buckets. - ut32 count; // number of stored elements. - HT_(Bucket) * table; // Actual table. + ut32 size; ///< Size of the hash table in buckets. + ut32 count; ///< Number of stored elements. + HT_(Bucket) *table; ///< Actual table. ut32 prime_idx; - HT_(Options) - opt; + HT_(Options) opt; } HtName_(Ht); // Create a new Ht with the provided Options -RZ_API HtName_(Ht) * Ht_(new_opt)(HT_(Options) * opt); +RZ_API RZ_OWN HtName_(Ht) *Ht_(new_opt)(RZ_NONNULL HT_(Options) *opt); +// Create a new Ht with the provided Options and initial size +RZ_API RZ_OWN HtName_(Ht) *Ht_(new_opt_size)(RZ_NONNULL HT_(Options) *opt, ut32 initial_size); // Destroy a hashtable and all of its entries. -RZ_API void Ht_(free)(HtName_(Ht) * ht); +RZ_API void Ht_(free)(RZ_NULLABLE HtName_(Ht) *ht); // Insert a new Key-Value pair into the hashtable. If the key already exists, returns false. -RZ_API bool Ht_(insert)(HtName_(Ht) * ht, const KEY_TYPE key, VALUE_TYPE value); +RZ_API bool Ht_(insert)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, VALUE_TYPE value); // Insert a new Key-Value pair into the hashtable, or updates the value if the key already exists. -RZ_API bool Ht_(update)(HtName_(Ht) * ht, const KEY_TYPE key, VALUE_TYPE value); +RZ_API bool Ht_(update)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, VALUE_TYPE value); // Update the key of an element in the hashtable -RZ_API bool Ht_(update_key)(HtName_(Ht) * ht, const KEY_TYPE old_key, const KEY_TYPE new_key); +RZ_API bool Ht_(update_key)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE old_key, const KEY_TYPE new_key); // Delete a key from the hashtable. -RZ_API bool Ht_(delete)(HtName_(Ht) * ht, const KEY_TYPE key); +RZ_API bool Ht_(delete)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key); // Find the value corresponding to the matching key. -RZ_API VALUE_TYPE Ht_(find)(HtName_(Ht) * ht, const KEY_TYPE key, bool *found); +RZ_API VALUE_TYPE Ht_(find)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, RZ_NULLABLE bool *found); // Iterates over all elements in the hashtable, calling the cb function on each Kv. // If the cb returns false, the iteration is stopped. // cb should not modify the hashtable. // NOTE: cb can delete the current element, but it should be avoided -RZ_API void Ht_(foreach)(HtName_(Ht) * ht, HT_(ForeachCallback) cb, void *user); +RZ_API void Ht_(foreach)(RZ_NONNULL HtName_(Ht) *ht, RZ_NONNULL HT_(ForeachCallback) cb, RZ_NULLABLE void *user); -RZ_API HT_(Kv) * Ht_(find_kv)(HtName_(Ht) * ht, const KEY_TYPE key, bool *found); -RZ_API bool Ht_(insert_kv)(HtName_(Ht) * ht, HT_(Kv) * kv, bool update); +RZ_API RZ_BORROW HT_(Kv) *Ht_(find_kv)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, RZ_NULLABLE bool *found); +RZ_API bool Ht_(insert_kv)(RZ_NONNULL HtName_(Ht) *ht, RZ_NONNULL HT_(Kv) *kv, bool update); diff --git a/librz/include/rz_util/ht_pp.h b/librz/include/rz_util/ht_pp.h index baf566884f0..389b9ad9dae 100644 --- a/librz/include/rz_util/ht_pp.h +++ b/librz/include/rz_util/ht_pp.h @@ -3,23 +3,19 @@ // SPDX-FileCopyrightText: 2016-2018 ret2libc // SPDX-License-Identifier: BSD-3-Clause -#ifndef SDB_HT_PP_H -#define SDB_HT_PP_H +#ifndef HT_PP_H +#define HT_PP_H #ifdef __cplusplus extern "C" { #endif -/* - * This header provides an hashtable HtPP that has void* as key and void* as - * value. The API functions starts with "ht_pp_" and the types starts with "HtPP". +/** \file + * This header provides an hash table HtPP that has void* as key and void* as value. + * The API functions starts with "ht_pp_" and the types starts with "HtPP". */ #define HT_TYPE 1 #include - -RZ_API HtName_(Ht) * Ht_(new0)(void); -RZ_API HtName_(Ht) * Ht_(new)(HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) valueSize); -RZ_API HtName_(Ht) * Ht_(new_size)(ut32 initial_size, HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) valueSize); #undef HT_TYPE #ifdef __cplusplus diff --git a/librz/include/rz_util/ht_pu.h b/librz/include/rz_util/ht_pu.h index 551930b91d4..d9750870796 100644 --- a/librz/include/rz_util/ht_pu.h +++ b/librz/include/rz_util/ht_pu.h @@ -3,21 +3,19 @@ // SPDX-FileCopyrightText: 2016-2018 ret2libc // SPDX-License-Identifier: BSD-3-Clause -#ifndef SDB_HT_PU_H -#define SDB_HT_PU_H +#ifndef HT_PU_H +#define HT_PU_H #ifdef __cplusplus extern "C" { #endif -/* - * This header provides an hashtable HtPU that has void* as key and ut64 as - * value. The API functions starts with "ht_pu_" and the types starts with "HtPU". +/** \file + * This header provides an hash table HtPU that has void* as key and ut64 as value. + * The API functions starts with "ht_pu_" and the types starts with "HtPU". */ #define HT_TYPE 4 #include - -RZ_API HtName_(Ht) * Ht_(new0)(void); #undef HT_TYPE #ifdef __cplusplus diff --git a/librz/include/rz_util/ht_sp.h b/librz/include/rz_util/ht_sp.h new file mode 100644 index 00000000000..bea09f2247a --- /dev/null +++ b/librz/include/rz_util/ht_sp.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2024 pelijah +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef HT_SP_H +#define HT_SP_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + * This header provides an hash table HtSP that has C-string as key and void* as value. + * The API functions starts with "ht_sp_" and the types starts with "HtSP". + */ +#define HT_TYPE 5 +#include + +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(HtStrOption key_opt, RZ_NULLABLE HT_(DupValue) dup_val, RZ_NULLABLE HT_(FreeValue) free_val); +#undef HT_TYPE + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/librz/include/rz_util/ht_ss.h b/librz/include/rz_util/ht_ss.h new file mode 100644 index 00000000000..0ec1c04640c --- /dev/null +++ b/librz/include/rz_util/ht_ss.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2024 pelijah +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef HT_SS_H +#define HT_SS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + * This header provides an hash table HtSS that has C-string as key and C-string as value. + * The API functions starts with "ht_ss_" and the types starts with "HtSS". + */ +#define HT_TYPE 6 +#include + +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(HtStrOption key_opt, HtStrOption val_opt); +#undef HT_TYPE + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/librz/include/rz_util/ht_su.h b/librz/include/rz_util/ht_su.h new file mode 100644 index 00000000000..672127a66da --- /dev/null +++ b/librz/include/rz_util/ht_su.h @@ -0,0 +1,25 @@ +// SPDX-FileCopyrightText: 2024 pelijah +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef HT_SU_H +#define HT_SU_H + +#ifdef __cplusplus +extern "C" { +#endif + +/** \file + * This header provides an hash table HtSU that has C-string as key and ut64 as value. + * The API functions starts with "ht_su_" and the types starts with "HtSU". + */ +#define HT_TYPE 7 +#include + +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(HtStrOption key_opt); +#undef HT_TYPE + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/librz/include/rz_util/ht_up.h b/librz/include/rz_util/ht_up.h index ef7e0632f52..7878ef7d08d 100644 --- a/librz/include/rz_util/ht_up.h +++ b/librz/include/rz_util/ht_up.h @@ -1,25 +1,25 @@ // SPDX-FileCopyrightText: 2016-2018 crowell // SPDX-FileCopyrightText: 2016-2018 pancake // SPDX-FileCopyrightText: 2016-2018 ret2libc +// SPDX-FileCopyrightText: 2024 pelijah // SPDX-License-Identifier: BSD-3-Clause -#ifndef SDB_HT_UP_H -#define SDB_HT_UP_H +#ifndef HT_UP_H +#define HT_UP_H #ifdef __cplusplus extern "C" { #endif -/* - * This header provides an hashtable HtUP that has ut64 as key and void* as - * value. The API functions starts with "ht_up_" and the types starts with "HtUP". +/** \file + * This header provides an hash table HtUP that has ut64 as key and void* as value. + * The API functions starts with "ht_up_" and the types starts with "HtUP". */ #define HT_TYPE 2 #include -RZ_API HtName_(Ht) * Ht_(new0)(void); -RZ_API HtName_(Ht) * Ht_(new)(HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) valueSize); -RZ_API HtName_(Ht) * Ht_(new_size)(ut32 initial_size, HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) valueSize); +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(RZ_NULLABLE HT_(DupValue) valdup, RZ_NULLABLE HT_(FreeValue) valfree); +RZ_API RZ_OWN HtName_(Ht) *Ht_(new_size)(ut32 initial_size, RZ_NULLABLE HT_(DupValue) valdup, RZ_NULLABLE HT_(FreeValue) valfree); #undef HT_TYPE #ifdef __cplusplus diff --git a/librz/include/rz_util/ht_uu.h b/librz/include/rz_util/ht_uu.h index a9e53bc2390..ca48a85a497 100644 --- a/librz/include/rz_util/ht_uu.h +++ b/librz/include/rz_util/ht_uu.h @@ -3,21 +3,21 @@ // SPDX-FileCopyrightText: 2016-2018 ret2libc // SPDX-License-Identifier: BSD-3-Clause -#ifndef SDB_HT_H_ -#define SDB_HT_H_ +#ifndef HT_UU_H +#define HT_UU_H #ifdef __cplusplus extern "C" { #endif -/* - * This header provides an hashtable Ht that has ut64 as key and ut64 as - * value. The API functions starts with "ht_" and the types starts with "Ht". +/** \file + * This header provides an hash table HtUU that has ut64 as key and ut64 as value. + * The API functions starts with "ht_uu" and the types starts with "HtUU". */ #define HT_TYPE 3 #include -RZ_API HtName_(Ht) * Ht_(new0)(void); +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(void); #undef HT_TYPE #ifdef __cplusplus diff --git a/librz/include/rz_util/rz_serialize.h b/librz/include/rz_util/rz_serialize.h index f026da12562..6410f92d473 100644 --- a/librz/include/rz_util/rz_serialize.h +++ b/librz/include/rz_util/rz_serialize.h @@ -5,6 +5,7 @@ #define RZ_SERIALIZE_H #include +#include #include /** @@ -43,18 +44,18 @@ static inline void rz_serialize_result_info_free(RzSerializeResultInfo *info) { * This enables string values to be used in a switch/case-like * fashion. */ -typedef HtPP RzKeyParser; +typedef HtSP RzKeyParser; static inline RzKeyParser *rz_key_parser_new(void) { - return ht_pp_new0(); + return ht_sp_new(HT_STR_DUP, NULL, NULL); } static inline void rz_key_parser_free(RzKeyParser *parser) { - ht_pp_free(parser); + ht_sp_free(parser); } static inline void rz_key_parser_add(RzKeyParser *parser, const char *key, int val) { - ht_pp_insert(parser, key, (void *)(size_t)val); + ht_sp_insert(parser, key, (void *)(size_t)val); } #define RZ_KEY_PARSER_UNKNOWN -1 @@ -66,7 +67,7 @@ static inline void rz_key_parser_add(RzKeyParser *parser, const char *key, int v */ #define RZ_KEY_PARSER_SWITCH(parser, key) \ bool key_parser_found = false; \ - int key_parser_v = (int)(size_t)ht_pp_find(parser, key, &key_parser_found); \ + int key_parser_v = (int)(size_t)ht_sp_find(parser, key, &key_parser_found); \ if (!key_parser_found) { \ key_parser_v = RZ_KEY_PARSER_UNKNOWN; \ } \ diff --git a/librz/include/rz_util/rz_str_constpool.h b/librz/include/rz_util/rz_str_constpool.h index 6ac5dd7b2c7..68dfee3361a 100644 --- a/librz/include/rz_util/rz_str_constpool.h +++ b/librz/include/rz_util/rz_str_constpool.h @@ -2,7 +2,7 @@ #define RZ_STR_CONSTPOOL_H #include -#include +#include #include @@ -16,7 +16,7 @@ extern "C" { */ typedef struct rz_str_constpool_t { - HtPP *ht; + HtSP *ht; } RzStrConstPool; RZ_API bool rz_str_constpool_init(RzStrConstPool *pool); diff --git a/librz/include/rz_util/rz_th_ht.h b/librz/include/rz_util/rz_th_ht.h index d3293567f94..23eed7aa55f 100644 --- a/librz/include/rz_util/rz_th_ht.h +++ b/librz/include/rz_util/rz_th_ht.h @@ -10,6 +10,9 @@ #include #include #include +#include +#include +#include #ifdef __cplusplus extern "C" { @@ -20,8 +23,7 @@ extern "C" { #define rz_th_ht_header(name, type, ktype, vtype) \ typedef struct rz_th_##name##_t RzThread##type; \ RZ_API void rz_th_##name##_free(RzThread##type *ht); \ - RZ_API RzThread##type *rz_th_##name##_new0(void); \ - RZ_API RzThread##type *rz_th_##name##_new_opt(type##Options *opt); \ + RZ_API RzThread##type *rz_th_##name##_new(type *table); \ RZ_API bool rz_th_##name##_insert(RzThread##type *ht, const ktype key, vtype value); \ RZ_API bool rz_th_##name##_update(RzThread##type *ht, const ktype key, vtype value); \ RZ_API bool rz_th_##name##_delete(RzThread##type *ht, const ktype key); \ @@ -33,6 +35,9 @@ rz_th_ht_header(ht_pp, HtPP, void *, void *); rz_th_ht_header(ht_up, HtUP, ut64, void *); rz_th_ht_header(ht_uu, HtUU, ut64, ut64); rz_th_ht_header(ht_pu, HtPU, void *, ut64); +rz_th_ht_header(ht_sp, HtSP, char *, void *); +rz_th_ht_header(ht_ss, HtSS, char *, char *); +rz_th_ht_header(ht_su, HtSU, char *, ut64); #endif /* RZ_API */ diff --git a/librz/include/rz_util/set.h b/librz/include/rz_util/set.h index 4f79a5c0d79..f8287a96f9f 100644 --- a/librz/include/rz_util/set.h +++ b/librz/include/rz_util/set.h @@ -1,31 +1,32 @@ // SPDX-FileCopyrightText: pancake +// SPDX-FileCopyrightText: 2024 pelijah // SPDX-License-Identifier: MIT #ifndef SDB_SET_H #define SDB_SET_H -#include +#include #include #ifdef __cplusplus extern "C" { #endif -typedef HtPP SetP; +typedef HtSP SetS; -RZ_API SetP *set_p_new(void); -RZ_API void set_p_add(SetP *p, const void *u); -RZ_API bool set_p_contains(SetP *s, const void *u); -RZ_API void set_p_delete(SetP *s, const void *u); -RZ_API void set_p_free(SetP *p); +RZ_API RZ_OWN SetS *set_s_new(HtStrOption opt); +RZ_API void set_s_add(RZ_NONNULL SetS *set, const char *str); +RZ_API bool set_s_contains(RZ_NONNULL SetS *set, const char *str); +RZ_API void set_s_delete(RZ_NONNULL SetS *set, const char *str); +RZ_API void set_s_free(RZ_NULLABLE SetS *set); typedef HtUP SetU; -RZ_API SetU *set_u_new(void); -RZ_API void set_u_add(SetU *p, ut64 u); -RZ_API bool set_u_contains(SetU *s, ut64 u); -RZ_API void set_u_delete(SetU *s, ut64 u); -RZ_API void set_u_free(SetU *p); +RZ_API RZ_OWN SetU *set_u_new(void); +RZ_API void set_u_add(RZ_NONNULL SetU *set, ut64 u); +RZ_API bool set_u_contains(RZ_NONNULL SetU *set, ut64 u); +RZ_API void set_u_delete(RZ_NONNULL SetU *set, ut64 u); +RZ_API void set_u_free(RZ_NULLABLE SetU *set); #ifdef __cplusplus } diff --git a/librz/io/p_cache.c b/librz/io/p_cache.c index b6439647c5f..29e9d1e4a92 100644 --- a/librz/io/p_cache.c +++ b/librz/io/p_cache.c @@ -72,15 +72,11 @@ const ut64 cleanup_masks[] = { 0x7fffffffffffffff }; -static void pcache_kv_free(HtUPKv *kv) { - free(kv->value); -} - RZ_API bool rz_io_desc_cache_init(RzIODesc *desc) { if (!desc || desc->cache) { return false; } - return (desc->cache = ht_up_new(NULL, pcache_kv_free, NULL)) ? true : false; + return (desc->cache = ht_up_new(NULL, free)) ? true : false; } RZ_API int rz_io_desc_cache_write(RzIODesc *desc, ut64 paddr, const ut8 *buf, size_t len) { diff --git a/librz/main/rz-asm.c b/librz/main/rz-asm.c index e81e639a624..bd2a1de98d1 100644 --- a/librz/main/rz-asm.c +++ b/librz/main/rz-asm.c @@ -410,8 +410,8 @@ static void print_buf(RzAsmState *as, char *str) { } } -static bool print_label(void *user, const void *k, const void *v) { - printf("f label.%s @ %s\n", (const char *)k, (const char *)v); +static bool print_label(void *user, const char *k, const char *v) { + printf("f label.%s @ %s\n", k, v); return true; } @@ -513,7 +513,7 @@ static int print_assembly_output(RzAsmState *as, const char *buf, ut64 offset, u if (rad) { printf("f entry @ $$\n"); printf("f label.main @ $$ + 1\n"); - ht_pp_foreach(as->a->flags, print_label, NULL); + ht_ss_foreach(as->a->flags, print_label, NULL); } return ret; } diff --git a/librz/reg/profile.c b/librz/reg/profile.c index 71c622b79e1..e902198c6aa 100644 --- a/librz/reg/profile.c +++ b/librz/reg/profile.c @@ -353,13 +353,13 @@ static void add_item_to_regset(RZ_BORROW RzReg *reg, RZ_BORROW RzRegItem *item) reg->regset[t].regs = rz_list_newf((RzListFree)rz_reg_item_free); } if (!reg->regset[t].ht_regs) { - reg->regset[t].ht_regs = ht_pp_new0(); + reg->regset[t].ht_regs = ht_sp_new(HT_STR_DUP, NULL, NULL); } // Dynamically update the list of supported bit sizes reg->bits |= item->size; rz_list_append(reg->regset[t].regs, item); - ht_pp_insert(reg->regset[t].ht_regs, item->name, item); + ht_sp_insert(reg->regset[t].ht_regs, item->name, item); // Update the overall type of registers into a regset if (item->type == RZ_REG_TYPE_ANY) { diff --git a/librz/reg/reg.c b/librz/reg/reg.c index e8ef95c8f97..b3876b38524 100644 --- a/librz/reg/reg.c +++ b/librz/reg/reg.c @@ -210,7 +210,7 @@ RZ_API void rz_reg_free_internal(RzReg *reg, bool init) { } } for (i = 0; i < RZ_REG_TYPE_LAST; i++) { - ht_pp_free(reg->regset[i].ht_regs); + ht_sp_free(reg->regset[i].ht_regs); reg->regset[i].ht_regs = NULL; if (!reg->regset[i].pool) { continue; @@ -366,10 +366,10 @@ RZ_API RzRegItem *rz_reg_get(RzReg *reg, const char *name, int type) { e = type + 1; } for (; i < e; i++) { - HtPP *pp = reg->regset[i].ht_regs; - if (pp) { + HtSP *ht = reg->regset[i].ht_regs; + if (ht) { bool found = false; - RzRegItem *item = ht_pp_find(pp, name, &found); + RzRegItem *item = ht_sp_find(ht, name, &found); if (found) { return item; } diff --git a/librz/sign/flirt.c b/librz/sign/flirt.c index d51c08c4799..b427f3cc971 100644 --- a/librz/sign/flirt.c +++ b/librz/sign/flirt.c @@ -360,7 +360,7 @@ static bool try_rename_function(RzAnalysis *analysis, RzAnalysisFunction *fcn, c if (fcn->type == RZ_ANALYSIS_FCN_TYPE_SYM) { // do not rename if is a symbol but check if // another function has the same name - return ht_pp_find(analysis->ht_name_fun, name, NULL) == NULL; + return ht_sp_find(analysis->ht_name_fun, name, NULL) == NULL; } return rz_analysis_function_rename(fcn, name); } diff --git a/librz/sign/sigdb.c b/librz/sign/sigdb.c index 518f48c13ca..884dfc81e8b 100644 --- a/librz/sign/sigdb.c +++ b/librz/sign/sigdb.c @@ -187,7 +187,7 @@ RZ_API bool rz_sign_sigdb_merge(RZ_NONNULL RzSigDb *db, RZ_NONNULL RzSigDb *db2) .src = db2, .dst = db, }; - db2->entries->opt.freefn = NULL; + db2->entries->opt.finiKV = NULL; ht_pu_foreach(db2->entries, sigdb_move_entry, &opt); return true; } @@ -247,7 +247,7 @@ static ut32 sigdb_entry_hash(const void *k) { return r; } -static void ht_pu_sigdb_freekv(HtPUKv *kv) { +static void ht_pu_sigdb_finikv(HtPUKv *kv, RZ_UNUSED void *user) { if (!kv) { return; } @@ -265,7 +265,7 @@ RZ_API RZ_OWN RzSigDb *rz_sign_sigdb_new(void) { HtPUOptions opt = { 0 }; opt.cmp = sigdb_entry_cmp, opt.hashfn = sigdb_entry_hash, - opt.freefn = ht_pu_sigdb_freekv; + opt.finiKV = ht_pu_sigdb_finikv; db->entries = ht_pu_new_opt(&opt); if (!db->entries) { free(db); diff --git a/librz/syscall/syscall.c b/librz/syscall/syscall.c index e689278a32b..f5497d57f73 100644 --- a/librz/syscall/syscall.c +++ b/librz/syscall/syscall.c @@ -30,10 +30,6 @@ RZ_API RZ_OWN RzSysregItem *rz_sysreg_item_new(RZ_NULLABLE const char *name) { return sysregitem; } -static void free_port_kv(HtUPKv *kv) { - rz_sysreg_item_free(kv->value); -} - /** * \brief Creates a new RzSysregDB type */ @@ -42,7 +38,7 @@ RZ_API RzSysregsDB *rz_sysregs_db_new() { if (!sysregdb) { return NULL; } - sysregdb->port = ht_up_new(NULL, free_port_kv, NULL); + sysregdb->port = ht_up_new(NULL, (HtUPFreeValue)rz_sysreg_item_free); if (!sysregdb->port) { free(sysregdb); return NULL; diff --git a/librz/type/base.c b/librz/type/base.c index 3ac3470eab1..8dbe822855d 100644 --- a/librz/type/base.c +++ b/librz/type/base.c @@ -58,7 +58,7 @@ RZ_API RZ_BORROW RzBaseType *rz_type_db_get_base_type(const RzTypeDB *typedb, RZ rz_return_val_if_fail(typedb && name, NULL); bool found = false; - RzBaseType *btype = ht_pp_find(typedb->types, name, &found); + RzBaseType *btype = ht_sp_find(typedb->types, name, &found); if (!found || !btype) { return NULL; } @@ -73,7 +73,7 @@ RZ_API RZ_BORROW RzBaseType *rz_type_db_get_base_type(const RzTypeDB *typedb, RZ */ RZ_API bool rz_type_db_delete_base_type(RzTypeDB *typedb, RZ_NONNULL RzBaseType *type) { rz_return_val_if_fail(typedb && type && type->name, false); - ht_pp_delete(typedb->types, type->name); + ht_sp_delete(typedb->types, type->name); return true; } @@ -82,7 +82,7 @@ struct list_kind { RzBaseTypeKind kind; }; -static bool base_type_kind_collect_cb(void *user, const void *k, const void *v) { +static bool base_type_kind_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { struct list_kind *l = user; RzBaseType *btype = (RzBaseType *)v; if (l->kind == btype->kind) { @@ -101,11 +101,11 @@ RZ_API RZ_OWN RzList /**/ *rz_type_db_get_base_types_of_kind(const rz_return_val_if_fail(typedb, NULL); RzList *types = rz_list_new(); struct list_kind lk = { types, kind }; - ht_pp_foreach(typedb->types, base_type_kind_collect_cb, &lk); + ht_sp_foreach(typedb->types, base_type_kind_collect_cb, &lk); return types; } -static bool base_type_collect_cb(void *user, const void *k, const void *v) { +static bool base_type_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { rz_return_val_if_fail(user && k && v, false); RzList *l = user; rz_list_append(l, (void *)v); @@ -120,7 +120,7 @@ static bool base_type_collect_cb(void *user, const void *k, const void *v) { RZ_API RZ_OWN RzList /**/ *rz_type_db_get_base_types(const RzTypeDB *typedb) { rz_return_val_if_fail(typedb, NULL); RzList *types = rz_list_new(); - ht_pp_foreach(typedb->types, base_type_collect_cb, types); + ht_sp_foreach(typedb->types, base_type_collect_cb, types); return types; } @@ -269,7 +269,7 @@ RZ_API RZ_OWN RzBaseType *rz_type_base_type_new(RzBaseTypeKind kind) { */ RZ_API bool rz_type_db_save_base_type(const RzTypeDB *typedb, RzBaseType *type) { rz_return_val_if_fail(typedb && type && type->name, false); - if (!ht_pp_insert(typedb->types, type->name, (void *)type)) { + if (!ht_sp_insert(typedb->types, type->name, (void *)type)) { rz_type_base_type_free(type); return false; } @@ -284,7 +284,7 @@ RZ_API bool rz_type_db_save_base_type(const RzTypeDB *typedb, RzBaseType *type) */ RZ_API bool rz_type_db_update_base_type(const RzTypeDB *typedb, RzBaseType *type) { rz_return_val_if_fail(typedb && type && type->name, false); - if (!ht_pp_update(typedb->types, type->name, (void *)type)) { + if (!ht_sp_update(typedb->types, type->name, (void *)type)) { rz_type_base_type_free(type); return false; } diff --git a/librz/type/format.c b/librz/type/format.c index b4b528fbb98..1049dee6cd0 100644 --- a/librz/type/format.c +++ b/librz/type/format.c @@ -1901,7 +1901,7 @@ static char *get_format_type(const char fmt, const char arg) { RZ_API const char *rz_type_db_format_get(const RzTypeDB *typedb, const char *name) { rz_return_val_if_fail(typedb && name, NULL); bool found = false; - const char *result = ht_pp_find(typedb->formats, name, &found); + const char *result = ht_ss_find(typedb->formats, name, &found); if (!found || !result) { // eprintf("Cannot find format \"%s\"\n", name); return NULL; @@ -1912,15 +1912,15 @@ RZ_API const char *rz_type_db_format_get(const RzTypeDB *typedb, const char *nam RZ_API void rz_type_db_format_set(RzTypeDB *typedb, const char *name, const char *fmt) { rz_return_if_fail(typedb && name && fmt); // TODO: We should check if the file format is valid (e.g. syntax) before storing it - ht_pp_insert(typedb->formats, name, strdup(fmt)); + ht_ss_insert(typedb->formats, name, strdup(fmt)); } -static bool format_collect_cb(void *user, const void *k, const void *v) { +static bool format_collect_cb(void *user, const char *k, const char *v) { rz_return_val_if_fail(user && k && v, false); RzList *l = user; RzTypeFormat *fmt = RZ_NEW0(RzTypeFormat); - fmt->name = (const char *)k; - fmt->body = (const char *)v; + fmt->name = k; + fmt->body = v; rz_list_append(l, fmt); return true; } @@ -1928,13 +1928,13 @@ static bool format_collect_cb(void *user, const void *k, const void *v) { RZ_API RZ_OWN RzList /**/ *rz_type_db_format_all(RzTypeDB *typedb) { rz_return_val_if_fail(typedb, NULL); RzList *formats = rz_list_new(); - ht_pp_foreach(typedb->formats, format_collect_cb, formats); + ht_ss_foreach(typedb->formats, format_collect_cb, formats); return formats; } RZ_API void rz_type_db_format_delete(RzTypeDB *typedb, const char *name) { rz_return_if_fail(typedb && name); - ht_pp_delete(typedb->formats, name); + ht_ss_delete(typedb->formats, name); } static int rz_type_format_data_internal(const RzTypeDB *typedb, RzPrint *p, RzStrBuf *outbuf, ut64 seek, const ut8 *b, const int len, diff --git a/librz/type/function.c b/librz/type/function.c index e4b1701944a..306798953e6 100644 --- a/librz/type/function.c +++ b/librz/type/function.c @@ -149,7 +149,7 @@ RZ_API bool rz_type_func_save(RzTypeDB *typedb, RZ_NONNULL RzCallable *callable) if (rz_type_func_exist(typedb, callable->name)) { return false; } - ht_pp_insert(typedb->callables, callable->name, callable); + ht_sp_insert(typedb->callables, callable->name, callable); return true; } @@ -161,7 +161,7 @@ RZ_API bool rz_type_func_save(RzTypeDB *typedb, RZ_NONNULL RzCallable *callable) */ RZ_API bool rz_type_func_update(RzTypeDB *typedb, RZ_NONNULL RzCallable *callable) { rz_return_val_if_fail(typedb && callable && callable->name, false); - if (!ht_pp_update(typedb->callables, callable->name, (void *)callable)) { + if (!ht_sp_update(typedb->callables, callable->name, (void *)callable)) { rz_type_callable_free(callable); return false; } @@ -177,7 +177,7 @@ RZ_API bool rz_type_func_update(RzTypeDB *typedb, RZ_NONNULL RzCallable *callabl RZ_API RZ_BORROW RzCallable *rz_type_func_get(RzTypeDB *typedb, RZ_NONNULL const char *name) { rz_return_val_if_fail(typedb && name, NULL); bool found = false; - RzCallable *callable = ht_pp_find(typedb->callables, name, &found); + RzCallable *callable = ht_sp_find(typedb->callables, name, &found); if (!found || !callable) { RZ_LOG_DEBUG("Cannot find function type \"%s\"\n", name); return NULL; @@ -193,20 +193,16 @@ RZ_API RZ_BORROW RzCallable *rz_type_func_get(RzTypeDB *typedb, RZ_NONNULL const */ RZ_API bool rz_type_func_delete(RzTypeDB *typedb, RZ_NONNULL const char *name) { rz_return_val_if_fail(typedb && name, false); - ht_pp_delete(typedb->callables, name); + ht_sp_delete(typedb->callables, name); return true; } -static void callables_ht_free(HtPPKv *kv) { - rz_type_callable_free(kv->value); -} - /** * \brief Removes all RzCallable types */ RZ_API void rz_type_func_delete_all(RzTypeDB *typedb) { - ht_pp_free(typedb->callables); - typedb->callables = ht_pp_new(NULL, callables_ht_free, NULL); + ht_sp_free(typedb->callables); + typedb->callables = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_type_callable_free); } /** @@ -218,7 +214,7 @@ RZ_API void rz_type_func_delete_all(RzTypeDB *typedb) { RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name) { rz_return_val_if_fail(typedb && name, false); bool found = false; - return ht_pp_find(typedb->callables, name, &found) && found; + return ht_sp_find(typedb->callables, name, &found) && found; } /** @@ -574,7 +570,7 @@ RZ_API bool rz_type_func_noreturn_drop(RzTypeDB *typedb, RZ_NONNULL const char * // Listing function types -static bool function_names_collect_cb(void *user, const void *k, const void *v) { +static bool function_names_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { RzList *l = (RzList *)user; RzCallable *callable = (RzCallable *)v; rz_list_append(l, strdup(callable->name)); @@ -589,11 +585,11 @@ static bool function_names_collect_cb(void *user, const void *k, const void *v) RZ_API RZ_OWN RzList /**/ *rz_type_function_names(RzTypeDB *typedb) { rz_return_val_if_fail(typedb, NULL); RzList *result = rz_list_newf(free); - ht_pp_foreach(typedb->callables, function_names_collect_cb, result); + ht_sp_foreach(typedb->callables, function_names_collect_cb, result); return result; } -static bool noreturn_function_names_collect_cb(void *user, const void *k, const void *v) { +static bool noreturn_function_names_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { RzList *l = (RzList *)user; RzCallable *callable = (RzCallable *)v; if (callable->noret) { @@ -610,6 +606,6 @@ static bool noreturn_function_names_collect_cb(void *user, const void *k, const RZ_API RZ_OWN RzList /**/ *rz_type_noreturn_function_names(RzTypeDB *typedb) { rz_return_val_if_fail(typedb, NULL); RzList *noretl = rz_list_newf(free); - ht_pp_foreach(typedb->callables, noreturn_function_names_collect_cb, noretl); + ht_sp_foreach(typedb->callables, noreturn_function_names_collect_cb, noretl); return noretl; } diff --git a/librz/type/parser/c_cpp_parser.c b/librz/type/parser/c_cpp_parser.c index d3d0e9e5cac..966990ec5b0 100644 --- a/librz/type/parser/c_cpp_parser.c +++ b/librz/type/parser/c_cpp_parser.c @@ -30,20 +30,20 @@ TSLanguage *tree_sitter_c(); // implemented by the `tree-sitter-cpp` library. // TSLanguage *tree_sitter_cpp(); -CParserState *c_parser_state_new(HtPP *base_types, HtPP *callable_types) { +CParserState *c_parser_state_new(HtSP *base_types, HtSP *callable_types) { CParserState *state = RZ_NEW0(CParserState); if (!base_types) { - state->types = ht_pp_new0(); + state->types = ht_sp_new(HT_STR_DUP, NULL, NULL); } else { state->types = base_types; } if (!callable_types) { - state->callables = ht_pp_new0(); + state->callables = ht_sp_new(HT_STR_DUP, NULL, NULL); } else { state->callables = callable_types; } // Forward definitions require to have a special hashtable - state->forward = ht_pp_new0(); + state->forward = ht_sp_new(HT_STR_DUP, NULL, NULL); // Initializing error/warning/debug messages buffers state->errors = rz_strbuf_new(""); state->warnings = rz_strbuf_new(""); @@ -53,9 +53,9 @@ CParserState *c_parser_state_new(HtPP *base_types, HtPP *callable_types) { } void c_parser_state_free(CParserState *state) { - ht_pp_free(state->forward); - ht_pp_free(state->types); - ht_pp_free(state->callables); + ht_sp_free(state->forward); + ht_sp_free(state->types); + ht_sp_free(state->callables); rz_strbuf_free(state->debug); rz_strbuf_free(state->warnings); rz_strbuf_free(state->errors); @@ -64,7 +64,7 @@ void c_parser_state_free(CParserState *state) { } void c_parser_state_free_keep_ht(CParserState *state) { - ht_pp_free(state->forward); + ht_sp_free(state->forward); rz_strbuf_free(state->debug); rz_strbuf_free(state->warnings); rz_strbuf_free(state->errors); @@ -112,7 +112,7 @@ RZ_API RZ_OWN RzTypeParser *rz_type_parser_new() { * \param type RzBaseTypes hashtable to preload into the parser state * \param type RzCallable hashtable to preload into the parser state */ -RZ_API RZ_OWN RzTypeParser *rz_type_parser_init(HtPP *types, HtPP *callables) { +RZ_API RZ_OWN RzTypeParser *rz_type_parser_init(HtSP *types, HtSP *callables) { RzTypeParser *parser = RZ_NEW0(RzTypeParser); if (!parser) { return NULL; diff --git a/librz/type/parser/types_parser.h b/librz/type/parser/types_parser.h index 38e9c09561d..1758949eecc 100644 --- a/librz/type/parser/types_parser.h +++ b/librz/type/parser/types_parser.h @@ -10,9 +10,9 @@ typedef struct { typedef struct { bool verbose; - HtPP *types; - HtPP *callables; - HtPP *forward; + HtSP *types; + HtSP *callables; + HtSP *forward; RzStrBuf *errors; RzStrBuf *warnings; RzStrBuf *debug; @@ -24,7 +24,7 @@ typedef struct { RzType *type; } ParserTypePair; -CParserState *c_parser_state_new(HtPP *base_types, HtPP *callable_types); +CParserState *c_parser_state_new(HtSP *base_types, HtSP *callable_types); void c_parser_state_free(CParserState *state); int parse_type_nodes_save(CParserState *state, TSNode node, const char *text); diff --git a/librz/type/parser/types_storage.c b/librz/type/parser/types_storage.c index bd6a6b7542a..2bcfeee363a 100644 --- a/librz/type/parser/types_storage.c +++ b/librz/type/parser/types_storage.c @@ -16,7 +16,7 @@ RzBaseType *c_parser_base_type_find(CParserState *state, RZ_NONNULL const char *name) { bool found = false; - RzBaseType *base_type = ht_pp_find(state->types, name, &found); + RzBaseType *base_type = ht_sp_find(state->types, name, &found); if (!found || !base_type) { return NULL; } @@ -25,7 +25,7 @@ RzBaseType *c_parser_base_type_find(CParserState *state, RZ_NONNULL const char * bool c_parser_base_type_is_forward_definition(CParserState *state, RZ_NONNULL const char *name) { bool found = false; - ht_pp_find(state->forward, name, &found); + ht_sp_find(state->forward, name, &found); return found; } @@ -43,7 +43,7 @@ bool c_parser_base_type_store(CParserState *state, RZ_NONNULL const char *name, } // We store only RzBaseType part of the type pair - ht_pp_insert(state->types, name, tpair->btype); + ht_sp_insert(state->types, name, tpair->btype); return true; } @@ -63,7 +63,7 @@ bool c_parser_forward_definition_store(CParserState *state, RZ_NONNULL const cha } // We store only the type name - ht_pp_insert(state->forward, name, NULL); + ht_sp_insert(state->forward, name, NULL); return true; } @@ -76,7 +76,7 @@ bool c_parser_forward_definition_remove(CParserState *state, RZ_NONNULL const ch return false; } - ht_pp_delete(state->forward, name); + ht_sp_delete(state->forward, name); return true; } @@ -84,7 +84,7 @@ bool c_parser_forward_definition_remove(CParserState *state, RZ_NONNULL const ch RzCallable *c_parser_callable_type_find(CParserState *state, RZ_NONNULL const char *name) { bool found = false; - RzCallable *callable = ht_pp_find(state->callables, name, &found); + RzCallable *callable = ht_sp_find(state->callables, name, &found); if (!found || !callable) { return NULL; } @@ -106,7 +106,7 @@ bool c_parser_callable_type_store(CParserState *state, RZ_NONNULL const char *na return false; } - ht_pp_insert(state->callables, name, type->callable); + ht_sp_insert(state->callables, name, type->callable); parser_debug(state, "Stored \"%s\" callable type\n", name); return true; } @@ -807,7 +807,7 @@ RZ_OWN RzType *c_parser_new_callable(CParserState *state, RZ_NONNULL const char } // We check if there is already a callable in the hashtable with the same name bool found = false; - RzCallable *callable = ht_pp_find(state->callables, name, &found); + RzCallable *callable = ht_sp_find(state->callables, name, &found); if (!found || !callable) { // If not found - create a new one callable = RZ_NEW0(RzCallable); diff --git a/librz/type/serialize_functions.c b/librz/type/serialize_functions.c index 511afabc387..966f7c6d804 100644 --- a/librz/type/serialize_functions.c +++ b/librz/type/serialize_functions.c @@ -14,9 +14,9 @@ * * \param newly_added list of strings where str is appended if it has been added to the cache in this pass */ -static RzType *parse_type_string_cached(RzTypeParser *parser, HtPP *cache, const char *str, char **error_msg, RZ_OUT RzList /**/ *newly_added) { +static RzType *parse_type_string_cached(RzTypeParser *parser, HtSP *cache, const char *str, char **error_msg, RZ_OUT RzList /**/ *newly_added) { rz_return_val_if_fail(str, NULL); - RzType *r = ht_pp_find(cache, str, NULL); + RzType *r = ht_sp_find(cache, str, NULL); if (r) { *error_msg = NULL; return rz_type_clone(r); @@ -25,22 +25,22 @@ static RzType *parse_type_string_cached(RzTypeParser *parser, HtPP *cache, const if (r) { char *reminder = strdup(str); if (reminder) { - ht_pp_insert(cache, str, r); + ht_sp_insert(cache, str, r); rz_list_push(newly_added, reminder); } } return r; } -static void type_string_cache_rollback(HtPP *cache, RzList /**/ *newly_added) { +static void type_string_cache_rollback(HtSP *cache, RzList /**/ *newly_added) { RzListIter *it; char *s; rz_list_foreach (newly_added, it, s) { - ht_pp_delete(cache, s); + ht_sp_delete(cache, s); } } -static RzCallable *get_callable_type(RzTypeDB *typedb, Sdb *sdb, const char *name, HtPP *type_str_cache) { +static RzCallable *get_callable_type(RzTypeDB *typedb, Sdb *sdb, const char *name, HtSP *type_str_cache) { rz_return_val_if_fail(typedb && sdb && RZ_STR_ISNOTEMPTY(name), NULL); RzList *cache_newly_added = rz_list_newf(free); @@ -133,7 +133,7 @@ static bool filter_func(void *user, const char *k, const char *v) { static bool sdb_load_callables(RzTypeDB *typedb, Sdb *sdb) { rz_return_val_if_fail(typedb && sdb, false); - HtPP *type_str_cache = ht_pp_new0(); // cache from a known C type extr to its RzType representation for skipping the parser if possible + HtSP *type_str_cache = ht_sp_new(HT_STR_DUP, NULL, NULL); // cache from a known C type extr to its RzType representation for skipping the parser if possible if (!type_str_cache) { return false; } @@ -145,11 +145,11 @@ static bool sdb_load_callables(RzTypeDB *typedb, Sdb *sdb) { // eprintf("loading function: \"%s\"\n", sdbkv_key(kv)); callable = get_callable_type(typedb, sdb, sdbkv_key(kv), type_str_cache); if (callable) { - ht_pp_update(typedb->callables, callable->name, callable); + ht_sp_update(typedb->callables, callable->name, callable); RZ_LOG_DEBUG("inserting the \"%s\" callable type\n", callable->name); } } - ht_pp_free(type_str_cache); + ht_sp_free(type_str_cache); ls_free(l); return true; } @@ -243,7 +243,7 @@ struct typedb_sdb { Sdb *sdb; }; -static bool export_callable_cb(void *user, const void *k, const void *v) { +static bool export_callable_cb(void *user, RZ_UNUSED const char *k, const void *v) { struct typedb_sdb *s = user; RzCallable *callable = (RzCallable *)v; save_callable(s->typedb, s->sdb, callable); @@ -252,7 +252,7 @@ static bool export_callable_cb(void *user, const void *k, const void *v) { static bool callable_export_sdb(RZ_NONNULL Sdb *db, RZ_NONNULL const RzTypeDB *typedb) { struct typedb_sdb tdb = { typedb, db }; - ht_pp_foreach(typedb->callables, export_callable_cb, &tdb); + ht_sp_foreach(typedb->callables, export_callable_cb, &tdb); return true; } diff --git a/librz/type/serialize_types.c b/librz/type/serialize_types.c index 5a5648c3fe6..377bf4222d3 100644 --- a/librz/type/serialize_types.c +++ b/librz/type/serialize_types.c @@ -336,15 +336,15 @@ bool sdb_load_base_types(RzTypeDB *typedb, Sdb *sdb) { tpair = get_atomic_type(typedb, sdb, sdbkv_key(kv)); } if (tpair && tpair->type) { - ht_pp_update(typedb->types, tpair->type->name, tpair->type); + ht_sp_update(typedb->types, tpair->type->name, tpair->type); // If the SDB provided the preferred type format then we store it char *format = tpair->format ? tpair->format : NULL; // Format is not always defined, e.g. for types like "void" or anonymous types if (format) { - ht_pp_update(typedb->formats, tpair->type->name, format); + ht_ss_update(typedb->formats, tpair->type->name, format); RZ_LOG_DEBUG("inserting the \"%s\" type & format: \"%s\"\n", tpair->type->name, format); } else { - ht_pp_delete(typedb->formats, tpair->type->name); + ht_ss_delete(typedb->formats, tpair->type->name); } } else if (tpair) { free(tpair->format); @@ -602,7 +602,7 @@ struct typedb_sdb { Sdb *sdb; }; -static bool export_base_type_cb(void *user, const void *k, const void *v) { +static bool export_base_type_cb(void *user, RZ_UNUSED const char *k, const void *v) { struct typedb_sdb *s = user; RzBaseType *btype = (RzBaseType *)v; sdb_save_base_type(s->typedb, s->sdb, btype); @@ -611,7 +611,7 @@ static bool export_base_type_cb(void *user, const void *k, const void *v) { static bool types_export_sdb(RZ_NONNULL Sdb *db, RZ_NONNULL const RzTypeDB *typedb) { struct typedb_sdb tdb = { typedb, db }; - ht_pp_foreach(typedb->types, export_base_type_cb, &tdb); + ht_sp_foreach(typedb->types, export_base_type_cb, &tdb); return true; } diff --git a/librz/type/type.c b/librz/type/type.c index 51496c6e35c..0256e4de61d 100644 --- a/librz/type/type.c +++ b/librz/type/type.c @@ -9,25 +9,6 @@ #include #include -static void types_ht_free(HtPPKv *kv) { - free(kv->key); - rz_type_base_type_free(kv->value); -} - -static void types_ht_free_keep_val(HtPPKv *kv) { - free(kv->key); -} - -static void formats_ht_free(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - -static void callables_ht_free(HtPPKv *kv) { - free(kv->key); - rz_type_callable_free(kv->value); -} - /** * \brief Creates a new instance of the RzTypeDB * @@ -46,15 +27,15 @@ RZ_API RzTypeDB *rz_type_db_new() { return NULL; } typedb->target->default_type = strdup("int"); - typedb->types = ht_pp_new(NULL, types_ht_free, NULL); + typedb->types = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_type_base_type_free); if (!typedb->types) { goto rz_type_db_new_fail; } - typedb->formats = ht_pp_new(NULL, formats_ht_free, NULL); + typedb->formats = ht_ss_new(HT_STR_DUP, HT_STR_OWN); if (!typedb->formats) { goto rz_type_db_new_fail; } - typedb->callables = ht_pp_new(NULL, callables_ht_free, NULL); + typedb->callables = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_type_callable_free); if (!typedb->callables) { goto rz_type_db_new_fail; } @@ -68,9 +49,9 @@ RZ_API RzTypeDB *rz_type_db_new() { rz_type_db_new_fail: free((void *)typedb->target->default_type); free(typedb->target); - ht_pp_free(typedb->types); - ht_pp_free(typedb->formats); - ht_pp_free(typedb->callables); + ht_sp_free(typedb->types); + ht_ss_free(typedb->formats); + ht_sp_free(typedb->callables); free(typedb); return NULL; } @@ -82,9 +63,9 @@ RZ_API RzTypeDB *rz_type_db_new() { */ RZ_API void rz_type_db_free(RzTypeDB *typedb) { rz_type_parser_free(typedb->parser); - ht_pp_free(typedb->callables); - ht_pp_free(typedb->types); - ht_pp_free(typedb->formats); + ht_sp_free(typedb->callables); + ht_sp_free(typedb->types); + ht_ss_free(typedb->formats); free((void *)typedb->target->default_type); free(typedb->target->os); free(typedb->target->cpu); @@ -98,10 +79,10 @@ RZ_API void rz_type_db_free(RzTypeDB *typedb) { * Destroys all loaded base types and callable types. */ RZ_API void rz_type_db_purge(RzTypeDB *typedb) { - ht_pp_free(typedb->callables); - typedb->callables = ht_pp_new(NULL, callables_ht_free, NULL); - ht_pp_free(typedb->types); - typedb->types = ht_pp_new(NULL, types_ht_free, NULL); + ht_sp_free(typedb->callables); + typedb->callables = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_type_callable_free); + ht_sp_free(typedb->types); + typedb->types = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_type_base_type_free); rz_type_parser_free(typedb->parser); typedb->parser = rz_type_parser_init(typedb->types, typedb->callables); } @@ -110,8 +91,8 @@ RZ_API void rz_type_db_purge(RzTypeDB *typedb) { * \brief Purges formats in the instance of the RzTypeDB */ RZ_API void rz_type_db_format_purge(RzTypeDB *typedb) { - ht_pp_free(typedb->formats); - typedb->formats = ht_pp_new(NULL, formats_ht_free, NULL); + ht_ss_free(typedb->formats); + typedb->formats = ht_ss_new(HT_STR_DUP, HT_STR_OWN); } static void set_default_type(RzTypeTarget *target, int bits) { @@ -841,7 +822,7 @@ struct PrettyHelperBufs { RzStrBuf *arraybuf; }; -static bool type_decl_as_pretty_string(const RzTypeDB *typedb, const RzType *type, HtPP *used_types, struct PrettyHelperBufs phbuf, bool *self_ref, char **self_ref_typename, bool zero_vla, bool print_anon, bool show_typedefs, bool allow_non_exist) { +static bool type_decl_as_pretty_string(const RzTypeDB *typedb, const RzType *type, HtSP *used_types, struct PrettyHelperBufs phbuf, bool *self_ref, char **self_ref_typename, bool zero_vla, bool print_anon, bool show_typedefs, bool allow_non_exist) { rz_return_val_if_fail(typedb && type && used_types && self_ref, false); bool is_anon = false; @@ -852,7 +833,7 @@ static bool type_decl_as_pretty_string(const RzTypeDB *typedb, const RzType *typ } is_anon = !strncmp(type->identifier.name, "anonymous ", strlen("anonymous ")); *self_ref = false; - ht_pp_find(used_types, type->identifier.name, self_ref); + ht_sp_find(used_types, type->identifier.name, self_ref); *self_ref = *self_ref && !is_anon; // no self_ref for anon types *self_ref_typename = *self_ref ? strdup(type->identifier.name) : NULL; @@ -937,7 +918,7 @@ static bool type_decl_as_pretty_string(const RzTypeDB *typedb, const RzType *typ return true; } -static char *type_as_pretty_string(const RzTypeDB *typedb, const RzType *type, const char *identifier, HtPP *used_types, unsigned int opts, int unfold_level, int indent_level) { +static char *type_as_pretty_string(const RzTypeDB *typedb, const RzType *type, const char *identifier, HtSP *used_types, unsigned int opts, int unfold_level, int indent_level) { rz_return_val_if_fail(typedb && type, NULL); if (unfold_level < 0) { // recursion base case @@ -990,7 +971,7 @@ static char *type_as_pretty_string(const RzTypeDB *typedb, const RzType *type, c unfold_level = 0; // no unfold unfold_anon = unfold_all = false; } else if (self_ref_typename) { - ht_pp_insert(used_types, self_ref_typename, NULL); // add the type to the ht + ht_sp_insert(used_types, self_ref_typename, NULL); // add the type to the ht } RzBaseType *btype = NULL; bool is_anon = false; @@ -1100,7 +1081,7 @@ static char *type_as_pretty_string(const RzTypeDB *typedb, const RzType *type, c rz_strbuf_append(buf, "\n"); } if (self_ref_typename) { - ht_pp_delete(used_types, self_ref_typename); + ht_sp_delete(used_types, self_ref_typename); free(self_ref_typename); } free(typename_str); @@ -1127,13 +1108,13 @@ RZ_API RZ_OWN char *rz_type_as_pretty_string(const RzTypeDB *typedb, RZ_NONNULL if (unfold_level < 0) { // any negative number means maximum unfolding unfold_level = INT32_MAX; } - HtPP *used_types = ht_pp_new0(); // use a hash table to keep track of unfolded types + HtSP *used_types = ht_sp_new(HT_STR_DUP, NULL, NULL); // use a hash table to keep track of unfolded types if (!used_types) { RZ_LOG_ERROR("Failed to create hashtable while pretty printing types") return NULL; } char *pretty_type = type_as_pretty_string(typedb, type, identifier, used_types, opts, unfold_level, 0); - ht_pp_free(used_types); + ht_sp_free(used_types); return pretty_type; } @@ -1304,10 +1285,12 @@ RZ_API bool rz_type_db_edit_base_type(RzTypeDB *typedb, RZ_NONNULL const char *n } // Remove the original type first // but do not free them - void *freefn = (void *)typedb->types->opt.freefn; - typedb->types->opt.freefn = types_ht_free_keep_val; - ht_pp_delete(typedb->types, t->name); - typedb->types->opt.freefn = freefn; + HtSPKv *kv = ht_sp_find_kv(typedb->types, t->name, NULL); + if (!kv || kv->value != t) { + return false; + } + kv->value = NULL; + ht_sp_delete(typedb->types, t->name); char *error_msg = NULL; int result = rz_type_parse_string_stateless(typedb->parser, typestr, &error_msg); if (result) { @@ -1317,7 +1300,7 @@ RZ_API bool rz_type_db_edit_base_type(RzTypeDB *typedb, RZ_NONNULL const char *n free(error_msg); // There is an error during the parsing thus we restore the old type // We insert the type back - ht_pp_insert(typedb->types, t->name, t); + ht_sp_insert(typedb->types, t->name, t); return false; } // Free now unnecessary old base type diff --git a/librz/type/typeclass.c b/librz/type/typeclass.c index cf79d1adffb..a37be2ac32c 100644 --- a/librz/type/typeclass.c +++ b/librz/type/typeclass.c @@ -296,7 +296,7 @@ struct list_typeclass { RzTypeTypeclass typeclass; }; -static bool base_type_typeclass_collect_cb(void *user, const void *k, const void *v) { +static bool base_type_typeclass_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { struct list_typeclass *l = user; RzBaseType *btype = (RzBaseType *)v; RzTypeTypeclass typeclass; @@ -316,7 +316,7 @@ struct list_typeclass_size { size_t size; }; -static bool base_type_typeclass_sized_collect_cb(void *user, const void *k, const void *v) { +static bool base_type_typeclass_sized_collect_cb(void *user, RZ_UNUSED const char *k, const void *v) { struct list_typeclass_size *l = user; RzBaseType *btype = (RzBaseType *)v; RzTypeTypeclass typeclass; @@ -340,7 +340,7 @@ RZ_API RZ_OWN RzList /**/ *rz_type_typeclass_get_all(const RzTypeD rz_return_val_if_fail(typeclass < RZ_TYPE_TYPECLASS_INVALID, NULL); RzList *types = rz_list_new(); struct list_typeclass lt = { typedb, types, typeclass }; - ht_pp_foreach(typedb->types, base_type_typeclass_collect_cb, <); + ht_sp_foreach(typedb->types, base_type_typeclass_collect_cb, <); return types; } @@ -356,7 +356,7 @@ RZ_API RZ_OWN RzList /**/ *rz_type_typeclass_get_all_sized(const R rz_return_val_if_fail(size && typeclass < RZ_TYPE_TYPECLASS_INVALID, NULL); RzList *types = rz_list_new(); struct list_typeclass_size lt = { typedb, types, typeclass, size }; - ht_pp_foreach(typedb->types, base_type_typeclass_sized_collect_cb, <); + ht_sp_foreach(typedb->types, base_type_typeclass_sized_collect_cb, <); return types; } diff --git a/librz/util/event.c b/librz/util/event.c index 2308033dfa4..4139f9740fd 100644 --- a/librz/util/event.c +++ b/librz/util/event.c @@ -10,10 +10,6 @@ typedef struct rz_event_callback_hook_t { int handle; } RzEventCallbackHook; -static void ht_callback_free(HtUPKv *kv) { - rz_vector_free((RzVector *)kv->value); -} - RZ_API RzEvent *rz_event_new(void *user) { RzEvent *ev = RZ_NEW0(RzEvent); if (!ev) { @@ -22,7 +18,7 @@ RZ_API RzEvent *rz_event_new(void *user) { ev->user = user; ev->next_handle = 0; - ev->callbacks = ht_up_new(NULL, ht_callback_free, NULL); + ev->callbacks = ht_up_new(NULL, (HtUPFreeValue)rz_vector_free); if (!ev->callbacks) { goto err; } diff --git a/librz/util/ht/ht_inc.c b/librz/util/ht/ht_inc.c index f6f6da95454..a7e2e835def 100644 --- a/librz/util/ht/ht_inc.c +++ b/librz/util/ht/ht_inc.c @@ -1,8 +1,11 @@ // SPDX-FileCopyrightText: 2016-2018 crowell // SPDX-FileCopyrightText: 2016-2018 pancake // SPDX-FileCopyrightText: 2016-2018 ret2libc +// SPDX-FileCopyrightText: 2024 pelijah // SPDX-License-Identifier: BSD-3-Clause +#include + #define LOAD_FACTOR 1 #define S_ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) @@ -19,33 +22,33 @@ static const ut32 ht_primes_sizes[] = { 4166287, 4999559, 5999471, 7199369 }; -static inline ut32 hashfn(HtName_(Ht) * ht, const KEY_TYPE k) { +static inline ut32 hashfn(HtName_(Ht) *ht, const KEY_TYPE k) { return ht->opt.hashfn ? ht->opt.hashfn(k) : KEY_TO_HASH(k); } -static inline ut32 bucketfn(HtName_(Ht) * ht, const KEY_TYPE k) { +static inline ut32 bucketfn(HtName_(Ht) *ht, const KEY_TYPE k) { return hashfn(ht, k) % ht->size; } -static inline KEY_TYPE dupkey(HtName_(Ht) * ht, const KEY_TYPE k) { +static inline KEY_TYPE dupkey(HtName_(Ht) *ht, const KEY_TYPE k) { return ht->opt.dupkey ? ht->opt.dupkey(k) : (KEY_TYPE)k; } -static inline VALUE_TYPE dupval(HtName_(Ht) * ht, const VALUE_TYPE v) { +static inline VALUE_TYPE dupval(HtName_(Ht) *ht, const VALUE_TYPE v) { return ht->opt.dupvalue ? ht->opt.dupvalue(v) : (VALUE_TYPE)v; } -static inline ut32 calcsize_key(HtName_(Ht) * ht, const KEY_TYPE k) { +static inline ut32 calcsize_key(HtName_(Ht) *ht, const KEY_TYPE k) { return ht->opt.calcsizeK ? ht->opt.calcsizeK(k) : 0; } -static inline ut32 calcsize_val(HtName_(Ht) * ht, const VALUE_TYPE v) { +static inline ut32 calcsize_val(HtName_(Ht) *ht, const VALUE_TYPE v) { return ht->opt.calcsizeV ? ht->opt.calcsizeV(v) : 0; } -static inline void freefn(HtName_(Ht) * ht, HT_(Kv) * kv) { - if (ht->opt.freefn) { - ht->opt.freefn(kv); +static inline void fini_kv_pair(HtName_(Ht) *ht, HT_(Kv) *kv) { + if (ht->opt.finiKV) { + ht->opt.finiKV(kv, ht->opt.finiKV_user); } } @@ -62,7 +65,7 @@ static inline ut32 compute_size(ut32 idx, ut32 sz) { return idx != UT32_MAX && idx < S_ARRAY_SIZE(ht_primes_sizes) ? ht_primes_sizes[idx] : (sz | 1); } -static inline bool is_kv_equal(HtName_(Ht) * ht, const KEY_TYPE key, const ut32 key_len, const HT_(Kv) * kv) { +static inline bool is_kv_equal(HtName_(Ht) *ht, const KEY_TYPE key, const ut32 key_len, const HT_(Kv) *kv) { if (key_len != kv->key_len) { return false; } @@ -74,11 +77,11 @@ static inline bool is_kv_equal(HtName_(Ht) * ht, const KEY_TYPE key, const ut32 return res; } -static inline HT_(Kv) * kv_at(HtName_(Ht) * ht, HT_(Bucket) * bt, ut32 i) { +static inline HT_(Kv) *kv_at(HtName_(Ht) *ht, HT_(Bucket) *bt, ut32 i) { return (HT_(Kv) *)((char *)bt->arr + i * ht->opt.elem_size); } -static inline HT_(Kv) * next_kv(HtName_(Ht) * ht, HT_(Kv) * kv) { +static inline HT_(Kv) *next_kv(HtName_(Ht) *ht, HT_(Kv) *kv) { return (HT_(Kv) *)((char *)kv + ht->opt.elem_size); } @@ -94,15 +97,8 @@ static inline HT_(Kv) * next_kv(HtName_(Ht) * ht, HT_(Kv) * kv) { // Create a new hashtable and return a pointer to it. // size - number of buckets in the hashtable -// hashfunction - the function that does the hashing, must not be null. -// comparator - the function to check if values are equal, if NULL, just checks -// == (for storing ints). -// keydup - function to duplicate to key (eg strdup), if NULL just does strup. -// valdup - same as keydup, but for values but if NULL just assign -// pair_free - function for freeing a keyvaluepair - if NULL just does free. -// calcsize - function to calculate the size of a value. if NULL, just stores 0. -static HtName_(Ht) * internal_ht_new(ut32 size, ut32 prime_idx, HT_(Options) * opt) { - HtName_(Ht) *ht = calloc(1, sizeof(*ht)); +static RZ_OWN HtName_(Ht) *internal_ht_new(ut32 size, ut32 prime_idx, HT_(Options) *opt) { + HtName_(Ht) *ht = RZ_NEW0(HtName_(Ht)); if (!ht) { return NULL; } @@ -123,11 +119,37 @@ static HtName_(Ht) * internal_ht_new(ut32 size, ut32 prime_idx, HT_(Options) * o return ht; } -RZ_API HtName_(Ht) * Ht_(new_opt)(HT_(Options) * opt) { +/** + * \brief Create a new hashtable with options \p opt. + * + * Options are copied to an inner field. + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new_opt)(RZ_NONNULL HT_(Options) *opt) { + rz_return_val_if_fail(opt, NULL); return internal_ht_new(ht_primes_sizes[0], 0, opt); } -RZ_API void Ht_(free)(HtName_(Ht) * ht) { +/** + * \brief Create a new hashtable with options \p opt and + * preallocated buckets for \p initial_size entries. + * + * Options are copied to an inner field. + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new_opt_size)(RZ_NONNULL HT_(Options) *opt, ut32 initial_size) { + rz_return_val_if_fail(opt, NULL); + ut32 idx = 0; + while (idx < S_ARRAY_SIZE(ht_primes_sizes) && + ht_primes_sizes[idx] * LOAD_FACTOR < initial_size) { + idx++; + } + if (idx == S_ARRAY_SIZE(ht_primes_sizes)) { + idx = UT32_MAX; + } + ut32 sz = compute_size(idx, (ut32)(initial_size * (2 - LOAD_FACTOR))); + return internal_ht_new(sz, idx, opt); +} + +RZ_API void Ht_(free)(RZ_NULLABLE HtName_(Ht) *ht) { if (!ht) { return; } @@ -135,12 +157,12 @@ RZ_API void Ht_(free)(HtName_(Ht) * ht) { ut32 i; for (i = 0; i < ht->size; i++) { HT_(Bucket) *bt = &ht->table[i]; - HT_(Kv) * kv; + HT_(Kv) *kv; ut32 j; - if (ht->opt.freefn) { + if (ht->opt.finiKV) { BUCKET_FOREACH(ht, bt, j, kv) { - ht->opt.freefn(kv); + ht->opt.finiKV(kv, ht->opt.finiKV_user); } } @@ -151,8 +173,8 @@ RZ_API void Ht_(free)(HtName_(Ht) * ht) { } // Increases the size of the hashtable by 2. -static void internal_ht_grow(HtName_(Ht) * ht) { - HtName_(Ht) * ht2; +static void internal_ht_grow(HtName_(Ht) *ht) { + HtName_(Ht) *ht2; HtName_(Ht) swap; ut32 idx = next_idx(ht->prime_idx); ut32 sz = compute_size(idx, ht->size * 2); @@ -167,7 +189,7 @@ static void internal_ht_grow(HtName_(Ht) * ht) { for (i = 0; i < ht->size; i++) { HT_(Bucket) *bt = &ht->table[i]; - HT_(Kv) * kv; + HT_(Kv) *kv; ut32 j; BUCKET_FOREACH(ht, bt, j, kv) { @@ -179,25 +201,25 @@ static void internal_ht_grow(HtName_(Ht) * ht) { *ht = *ht2; *ht2 = swap; - ht2->opt.freefn = NULL; + ht2->opt.finiKV = NULL; Ht_(free)(ht2); } -static void check_growing(HtName_(Ht) * ht) { +static void check_growing(HtName_(Ht) *ht) { if (ht->count >= LOAD_FACTOR * ht->size) { internal_ht_grow(ht); } } -static HT_(Kv) * reserve_kv(HtName_(Ht) * ht, const KEY_TYPE key, const int key_len, bool update) { +static HT_(Kv) *reserve_kv(HtName_(Ht) *ht, const KEY_TYPE key, const int key_len, bool update) { HT_(Bucket) *bt = &ht->table[bucketfn(ht, key)]; - HT_(Kv) * kvtmp; + HT_(Kv) *kvtmp; ut32 j; BUCKET_FOREACH(ht, bt, j, kvtmp) { if (is_kv_equal(ht, key, key_len, kvtmp)) { if (update) { - freefn(ht, kvtmp); + fini_kv_pair(ht, kvtmp); return kvtmp; } return NULL; @@ -215,7 +237,8 @@ static HT_(Kv) * reserve_kv(HtName_(Ht) * ht, const KEY_TYPE key, const int key_ return kv_at(ht, bt, bt->count - 1); } -RZ_API bool Ht_(insert_kv)(HtName_(Ht) * ht, HT_(Kv) * kv, bool update) { +RZ_API bool Ht_(insert_kv)(RZ_NONNULL HtName_(Ht) *ht, RZ_NONNULL HT_(Kv) *kv, bool update) { + rz_return_val_if_fail(ht && kv, false); HT_(Kv) *kv_dst = reserve_kv(ht, kv->key, kv->key_len, update); if (!kv_dst) { return false; @@ -226,7 +249,7 @@ RZ_API bool Ht_(insert_kv)(HtName_(Ht) * ht, HT_(Kv) * kv, bool update) { return true; } -static bool insert_update(HtName_(Ht) * ht, const KEY_TYPE key, VALUE_TYPE value, bool update) { +static bool insert_update(HtName_(Ht) *ht, const KEY_TYPE key, VALUE_TYPE value, bool update) { ut32 key_len = calcsize_key(ht, key); HT_(Kv) *kv_dst = reserve_kv(ht, key, key_len, update); if (!kv_dst) { @@ -241,20 +264,29 @@ static bool insert_update(HtName_(Ht) * ht, const KEY_TYPE key, VALUE_TYPE value return true; } -// Inserts the key value pair key, value into the hashtable. -// Doesn't allow for "update" of the value. -RZ_API bool Ht_(insert)(HtName_(Ht) * ht, const KEY_TYPE key, VALUE_TYPE value) { +/** + * Inserts the key value pair \p key, \p value into the hashtable \p ht. + * Doesn't allow for "update" of the value. + */ +RZ_API bool Ht_(insert)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, VALUE_TYPE value) { + rz_return_val_if_fail(ht, false); return insert_update(ht, key, value, false); } -// Inserts the key value pair key, value into the hashtable. -// Does allow for "update" of the value. -RZ_API bool Ht_(update)(HtName_(Ht) * ht, const KEY_TYPE key, VALUE_TYPE value) { +/** + * Inserts the key value pair \p key, \p value into the hashtable \p ht. + * Does allow for "update" of the value. + */ +RZ_API bool Ht_(update)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, VALUE_TYPE value) { + rz_return_val_if_fail(ht, false); return insert_update(ht, key, value, true); } -// Update the key of an element that has old_key as key and replace it with new_key -RZ_API bool Ht_(update_key)(HtName_(Ht) * ht, const KEY_TYPE old_key, const KEY_TYPE new_key) { +/** + * Update the key of an element that has \p old_key as key and replace it with \p new_key + */ +RZ_API bool Ht_(update_key)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE old_key, const KEY_TYPE new_key) { + rz_return_val_if_fail(ht, false); // First look for the value associated with old_key bool found; VALUE_TYPE value = Ht_(find)(ht, old_key, &found); @@ -271,7 +303,7 @@ RZ_API bool Ht_(update_key)(HtName_(Ht) * ht, const KEY_TYPE old_key, const KEY_ // Remove the old_key kv, paying attention to not double free the value HT_(Bucket) *bt = &ht->table[bucketfn(ht, old_key)]; const int old_key_len = calcsize_key(ht, old_key); - HT_(Kv) * kv; + HT_(Kv) *kv; ut32 j; BUCKET_FOREACH(ht, bt, j, kv) { @@ -284,7 +316,7 @@ RZ_API bool Ht_(update_key)(HtName_(Ht) * ht, const KEY_TYPE old_key, const KEY_ kv->value = HT_NULL_VALUE; kv->value_len = 0; } - freefn(ht, kv); + fini_kv_pair(ht, kv); void *src = next_kv(ht, kv); memmove(kv, src, (bt->count - j - 1) * ht->opt.elem_size); @@ -297,20 +329,20 @@ RZ_API bool Ht_(update_key)(HtName_(Ht) * ht, const KEY_TYPE old_key, const KEY_ return false; } -// Returns the corresponding SdbKv entry from the key. -// If `found` is not NULL, it will be set to true if the entry was found, false -// otherwise. -RZ_API HT_(Kv) * Ht_(find_kv)(HtName_(Ht) * ht, const KEY_TYPE key, bool *found) { +/** + * Returns the corresponding Kv entry from \p key. + * If \p found is not NULL, it will be set to true if the entry was found, + * false otherwise. + */ +RZ_API RZ_BORROW HT_(Kv) *Ht_(find_kv)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, RZ_NULLABLE bool *found) { if (found) { *found = false; } - if (!ht) { - return NULL; - } + rz_return_val_if_fail(ht, NULL); HT_(Bucket) *bt = &ht->table[bucketfn(ht, key)]; ut32 key_len = calcsize_key(ht, key); - HT_(Kv) * kv; + HT_(Kv) *kv; ut32 j; BUCKET_FOREACH(ht, bt, j, kv) { @@ -324,24 +356,29 @@ RZ_API HT_(Kv) * Ht_(find_kv)(HtName_(Ht) * ht, const KEY_TYPE key, bool *found) return NULL; } -// Looks up the corresponding value from the key. -// If `found` is not NULL, it will be set to true if the entry was found, false -// otherwise. -RZ_API VALUE_TYPE Ht_(find)(HtName_(Ht) * ht, const KEY_TYPE key, bool *found) { +/** + * Looks up the corresponding value from \p key. + * If \p found is not NULL, it will be set to true if the entry was found, + * false otherwise. + */ +RZ_API VALUE_TYPE Ht_(find)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key, RZ_NULLABLE bool *found) { HT_(Kv) *res = Ht_(find_kv)(ht, key, found); return res ? res->value : HT_NULL_VALUE; } -// Deletes a entry from the hash table from the key, if the pair exists. -RZ_API bool Ht_(delete)(HtName_(Ht) * ht, const KEY_TYPE key) { +/** + * Deletes an entry from the hash table \p ht with key \p key, if the pair exists. + */ +RZ_API bool Ht_(delete)(RZ_NONNULL HtName_(Ht) *ht, const KEY_TYPE key) { + rz_return_val_if_fail(ht, false); HT_(Bucket) *bt = &ht->table[bucketfn(ht, key)]; ut32 key_len = calcsize_key(ht, key); - HT_(Kv) * kv; + HT_(Kv) *kv; ut32 j; BUCKET_FOREACH(ht, bt, j, kv) { if (is_kv_equal(ht, key, key_len, kv)) { - freefn(ht, kv); + fini_kv_pair(ht, kv); void *src = next_kv(ht, kv); memmove(kv, src, (bt->count - j - 1) * ht->opt.elem_size); bt->count--; @@ -352,12 +389,17 @@ RZ_API bool Ht_(delete)(HtName_(Ht) * ht, const KEY_TYPE key) { return false; } -RZ_API void Ht_(foreach)(HtName_(Ht) * ht, HT_(ForeachCallback) cb, void *user) { +/** + * Apply \p cb for each KV pair in \p ht. + * If \p cb returns false, the iteration is stopped. + */ +RZ_API void Ht_(foreach)(RZ_NONNULL HtName_(Ht) *ht, RZ_NONNULL HT_(ForeachCallback) cb, RZ_NULLABLE void *user) { + rz_return_if_fail(ht && cb); ut32 i; for (i = 0; i < ht->size; ++i) { HT_(Bucket) *bt = &ht->table[i]; - HT_(Kv) * kv; + HT_(Kv) *kv; ut32 j, count; BUCKET_FOREACH_SAFE(ht, bt, j, count, kv) { diff --git a/librz/util/ht/ht_pp.c b/librz/util/ht/ht_pp.c index 9525aeeaa0d..e6681ae1dfa 100644 --- a/librz/util/ht/ht_pp.c +++ b/librz/util/ht/ht_pp.c @@ -6,47 +6,3 @@ #include "sdb.h" #include #include "ht_inc.c" - -static HtName_(Ht) * internal_ht_default_new(ut32 size, ut32 prime_idx, HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) calcsizeV) { - HT_(Options) - opt = { - .cmp = (HT_(ListComparator))strcmp, - .hashfn = (HT_(HashFunction))sdb_hash, - .dupkey = (HT_(DupKey))strdup, - .dupvalue = valdup, - .calcsizeK = (HT_(CalcSizeK))strlen, - .calcsizeV = calcsizeV, - .freefn = pair_free, - .elem_size = sizeof(HT_(Kv)), - }; - return internal_ht_new(size, prime_idx, &opt); -} - -// creates a default HtPP that has strings as keys -RZ_API HtName_(Ht) * Ht_(new)(HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) calcsizeV) { - return internal_ht_default_new(ht_primes_sizes[0], 0, valdup, pair_free, calcsizeV); -} - -static void free_kv_key(HT_(Kv) * kv) { - free(kv->key); -} - -// creates a default HtPP that has strings as keys but does not dup, nor free the values -RZ_API HtName_(Ht) * Ht_(new0)(void) { - return Ht_(new)(NULL, free_kv_key, NULL); -} - -RZ_API HtName_(Ht) * Ht_(new_size)(ut32 initial_size, HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) calcsizeV) { - ut32 i = 0; - - while (i < S_ARRAY_SIZE(ht_primes_sizes) && - ht_primes_sizes[i] * LOAD_FACTOR < initial_size) { - i++; - } - if (i == S_ARRAY_SIZE(ht_primes_sizes)) { - i = UT32_MAX; - } - - ut32 sz = compute_size(i, (ut32)(initial_size * (2 - LOAD_FACTOR))); - return internal_ht_default_new(sz, i, valdup, pair_free, calcsizeV); -} diff --git a/librz/util/ht/ht_pu.c b/librz/util/ht/ht_pu.c index 9e42e849b1d..81bcf991f49 100644 --- a/librz/util/ht/ht_pu.c +++ b/librz/util/ht/ht_pu.c @@ -6,23 +6,3 @@ #include "sdb.h" #include #include "ht_inc.c" - -static void free_kv_key(HT_(Kv) * kv) { - free(kv->key); -} - -// creates a default HtPU that has strings as keys -RZ_API HtName_(Ht) * Ht_(new0)(void) { - HT_(Options) - opt = { - .cmp = (HT_(ListComparator))strcmp, - .hashfn = (HT_(HashFunction))sdb_hash, - .dupkey = (HT_(DupKey))strdup, - .dupvalue = NULL, - .calcsizeK = (HT_(CalcSizeK))strlen, - .calcsizeV = NULL, - .freefn = free_kv_key, - .elem_size = sizeof(HT_(Kv)), - }; - return Ht_(new_opt)(&opt); -} diff --git a/librz/util/ht/ht_sp.c b/librz/util/ht/ht_sp.c new file mode 100644 index 00000000000..3cc505d0ff8 --- /dev/null +++ b/librz/util/ht/ht_sp.c @@ -0,0 +1,46 @@ +// SPDX-FileCopyrightText: 2024 pelijah +// SPDX-License-Identifier: BSD-3-Clause + +#include "sdb.h" +#include +#include "ht_inc.c" + +static void fini_kv(HT_(Kv) *kv, void *user) { + HT_(FreeValue) func = (HT_(FreeValue))user; + free(kv->key); + if (func) { + func(kv->value); + } +} + +static void fini_kv_val(HT_(Kv) *kv, void *user) { + HT_(FreeValue) func = (HT_(FreeValue))user; + if (func) { + func(kv->value); + } +} + +/** + * \brief Create a new hash table that has C-string as key and void* as value. + * \param key_opt Defines how key is stored + * \param dup_val Function to making copy of a value when inserting + * \param free_val Function to releasing a stored value + * + * Keys are compared using strcmp function. + * Size of keys is calculated using strlen function. + * Copies of keys are made using strdup function if appropriate option is set. + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(HtStrOption key_opt, RZ_NULLABLE HT_(DupValue) dup_val, RZ_NULLABLE HT_(FreeValue) free_val) { + HT_(Options) opt = { + .cmp = (HT_(Comparator))strcmp, + .hashfn = (HT_(HashFunction))sdb_hash, + .dupkey = key_opt == HT_STR_DUP ? (HT_(DupKey))strdup : NULL, + .dupvalue = dup_val, + .calcsizeK = (HT_(CalcSizeK))strlen, + .calcsizeV = NULL, + .finiKV = key_opt == HT_STR_CONST ? fini_kv_val : fini_kv, + .finiKV_user = (void *)free_val, + .elem_size = 0, + }; + return internal_ht_new(ht_primes_sizes[0], 0, &opt); +} diff --git a/librz/util/ht/ht_ss.c b/librz/util/ht/ht_ss.c new file mode 100644 index 00000000000..779b134734f --- /dev/null +++ b/librz/util/ht/ht_ss.c @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: 2024 pelijah +// SPDX-License-Identifier: BSD-3-Clause + +#include "sdb.h" +#include +#include "ht_inc.c" + +static void fini_kv(HT_(Kv) *kv, void *user) { + HT_(FreeValue) func = (HT_(FreeValue))user; + free(kv->key); + if (func) { + func(kv->value); + } +} + +static void fini_kv_val(HT_(Kv) *kv, void *user) { + HT_(FreeValue) func = (HT_(FreeValue))user; + if (func) { + func(kv->value); + } +} + +/** + * \brief Create a new hash table that has C-string as key and C-string as value. + * \param key_opt Defines how key is stored + * \param val_opt Defines how value is stored + * + * Keys are compared using strcmp function. + * Size of keys is calculated using strlen function. + * Copies of keys/values are made using strdup function if appropriate option is set. + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(HtStrOption key_opt, HtStrOption val_opt) { + HT_(Options) opt = { + .cmp = (HT_(Comparator))strcmp, + .hashfn = (HT_(HashFunction))sdb_hash, + .dupkey = key_opt == HT_STR_DUP ? (HT_(DupKey))strdup : NULL, + .dupvalue = val_opt == HT_STR_DUP ? (HT_(DupValue))strdup : NULL, + .calcsizeK = (HT_(CalcSizeK))strlen, + .calcsizeV = (HT_(CalcSizeV))strlen, + .finiKV = key_opt == HT_STR_CONST ? fini_kv_val : fini_kv, + .finiKV_user = val_opt == HT_STR_CONST ? NULL : (HT_(FreeValue))free, + .elem_size = 0, + }; + return internal_ht_new(ht_primes_sizes[0], 0, &opt); +} diff --git a/librz/util/ht/ht_su.c b/librz/util/ht/ht_su.c new file mode 100644 index 00000000000..4721914b916 --- /dev/null +++ b/librz/util/ht/ht_su.c @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: 2024 pelijah +// SPDX-License-Identifier: BSD-3-Clause + +#include "sdb.h" +#include +#include "ht_inc.c" + +static void fini_kv_key(HT_(Kv) *kv, RZ_UNUSED void *user) { + free(kv->key); +} + +/** + * \brief Create a new hash table that has C-string as key and ut64 as value. + * \param key_opt Defines how key is stored + * + * Keys are compared using strcmp function. + * Size of keys is calculated using strlen function. + * Copies of keys are made using strdup function if appropriate option is set. + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(HtStrOption key_opt) { + HT_(Options) opt = { + .cmp = (HT_(Comparator))strcmp, + .hashfn = (HT_(HashFunction))sdb_hash, + .dupkey = key_opt == HT_STR_DUP ? (HT_(DupKey))strdup : NULL, + .dupvalue = NULL, + .calcsizeK = (HT_(CalcSizeK))strlen, + .calcsizeV = NULL, + .finiKV = key_opt == HT_STR_CONST ? NULL : fini_kv_key, + .finiKV_user = NULL, + .elem_size = 0, + }; + return internal_ht_new(ht_primes_sizes[0], 0, &opt); +} diff --git a/librz/util/ht/ht_up.c b/librz/util/ht/ht_up.c index a1ea77e63f9..9f9e6d2d78b 100644 --- a/librz/util/ht/ht_up.c +++ b/librz/util/ht/ht_up.c @@ -1,46 +1,51 @@ // SPDX-FileCopyrightText: 2016-2018 crowell // SPDX-FileCopyrightText: 2016-2018 pancake // SPDX-FileCopyrightText: 2016-2018 ret2libc +// SPDX-FileCopyrightText: 2024 pelijah // SPDX-License-Identifier: BSD-3-Clause #include #include "ht_inc.c" -static HtName_(Ht) * internal_ht_default_new(ut32 size, ut32 prime_idx, HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) calcsizeV) { - HT_(Options) - opt = { - .cmp = NULL, - .hashfn = NULL, // TODO: use a better hash function for numbers - .dupkey = NULL, - .dupvalue = valdup, - .calcsizeK = NULL, - .calcsizeV = calcsizeV, - .freefn = pair_free, - .elem_size = sizeof(HT_(Kv)), - }; - return internal_ht_new(size, prime_idx, &opt); +static void fini_kv_val(HT_(Kv) *kv, void *user) { + HT_(FreeValue) func = (HT_(FreeValue))user; + if (func) { + func(kv->value); + } } -RZ_API HtName_(Ht) * Ht_(new)(HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) calcsizeV) { - return internal_ht_default_new(ht_primes_sizes[0], 0, valdup, pair_free, calcsizeV); +static void init_options(HT_(Options) *opt, HT_(DupValue) valdup, HT_(FreeValue) valfree) { + opt->cmp = NULL; + opt->hashfn = NULL; + opt->dupkey = NULL; + opt->dupvalue = valdup; + opt->calcsizeK = NULL; + opt->calcsizeV = NULL; + opt->finiKV = fini_kv_val; + opt->finiKV_user = (void *)valfree; + opt->elem_size = 0; } -// creates a default HtUP that does not dup, nor free the values -RZ_API HtName_(Ht) * Ht_(new0)(void) { - return Ht_(new)(NULL, NULL, NULL); +/** + * \brief Create a new hash table that has ut64 as key and void* as value. + * \param valdup Function to making copy of a value when inserting + * \param valfree Function to releasing a stored value + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(RZ_NULLABLE HT_(DupValue) valdup, RZ_NULLABLE HT_(FreeValue) valfree) { + HT_(Options) opt; + init_options(&opt, valdup, valfree); + return internal_ht_new(ht_primes_sizes[0], 0, &opt); } -RZ_API HtName_(Ht) * Ht_(new_size)(ut32 initial_size, HT_(DupValue) valdup, HT_(KvFreeFunc) pair_free, HT_(CalcSizeV) calcsizeV) { - ut32 i = 0; - - while (i < S_ARRAY_SIZE(ht_primes_sizes) && - ht_primes_sizes[i] * LOAD_FACTOR < initial_size) { - i++; - } - if (i == S_ARRAY_SIZE(ht_primes_sizes)) { - i = UT32_MAX; - } - - ut32 sz = compute_size(i, (ut32)(initial_size * (2 - LOAD_FACTOR))); - return internal_ht_default_new(sz, i, valdup, pair_free, calcsizeV); +/** + * \brief Create a new hash table that has ut64 as key and void* as value + * with preallocated buckets for \p initial_size entries. + * \param initial_size Initial size of the hash table + * \param valdup Function to making copy of a value when inserting + * \param valfree Function to releasing a stored value + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new_size)(ut32 initial_size, RZ_NULLABLE HT_(DupValue) valdup, RZ_NULLABLE HT_(FreeValue) valfree) { + HT_(Options) opt; + init_options(&opt, valdup, valfree); + return Ht_(new_opt_size)(&opt, initial_size); } diff --git a/librz/util/ht/ht_uu.c b/librz/util/ht/ht_uu.c index 8b42d6593cc..8a67e94009c 100644 --- a/librz/util/ht/ht_uu.c +++ b/librz/util/ht/ht_uu.c @@ -7,16 +7,10 @@ #include "ht_inc.c" -RZ_API HtName_(Ht) * Ht_(new0)(void) { - HT_(Options) - opt = { - .cmp = NULL, - .hashfn = NULL, - .dupkey = NULL, - .dupvalue = NULL, - .calcsizeK = NULL, - .calcsizeV = NULL, - .freefn = NULL - }; +/** + * \brief Create a new hash table that has ut64 as key and ut64 as value. + */ +RZ_API RZ_OWN HtName_(Ht) *Ht_(new)(void) { + HT_(Options) opt = { 0 }; return Ht_(new_opt)(&opt); } diff --git a/librz/util/lib.c b/librz/util/lib.c index 28cfe197b59..1f82607a950 100644 --- a/librz/util/lib.c +++ b/librz/util/lib.c @@ -30,7 +30,7 @@ RZ_API RzLib *rz_lib_new(RZ_NULLABLE const char *symname, RZ_NULLABLE const char lib->plugins = rz_list_new(); lib->symname = strdup(symname ? symname : RZ_LIB_SYMNAME); lib->symnamefunc = strdup(symnamefunc ? symnamefunc : RZ_LIB_SYMFUNC); - lib->opened_dirs = ht_pu_new0(); + lib->opened_dirs = ht_su_new(HT_STR_DUP); return lib; } @@ -48,7 +48,7 @@ RZ_API void rz_lib_free(RzLib *lib) { rz_list_free(lib->plugins); free(lib->symname); free(lib->symnamefunc); - ht_pu_free(lib->opened_dirs); + ht_su_free(lib->opened_dirs); free(lib); } @@ -245,7 +245,7 @@ RZ_API bool rz_lib_open(RzLib *lib, RZ_NONNULL const char *file) { RZ_API bool rz_lib_opendir(RzLib *lib, const char *path, bool force) { rz_return_val_if_fail(lib && path, false); - if (!force && ht_pu_find(lib->opened_dirs, path, NULL)) { + if (!force && ht_su_find(lib->opened_dirs, path, NULL)) { return false; } #if WANT_DYLINK @@ -320,7 +320,7 @@ RZ_API bool rz_lib_opendir(RzLib *lib, const char *path, bool force) { closedir(dh); #endif #endif - ht_pu_insert(lib->opened_dirs, path, 1); + ht_su_insert(lib->opened_dirs, path, 1); return true; } diff --git a/librz/util/meson.build b/librz/util/meson.build index 72148f646e2..8e9ac6ba510 100644 --- a/librz/util/meson.build +++ b/librz/util/meson.build @@ -86,6 +86,9 @@ rz_util_common_sources = [ 'ht/ht_pp.c', 'ht/ht_up.c', 'ht/ht_pu.c', + 'ht/ht_sp.c', + 'ht/ht_ss.c', + 'ht/ht_su.c', 'set.c', ] rz_util_sources = rz_util_common_sources diff --git a/librz/util/sdb/src/sdb.c b/librz/util/sdb/src/sdb.c index d44bb2b8e59..6744adde48c 100644 --- a/librz/util/sdb/src/sdb.c +++ b/librz/util/sdb/src/sdb.c @@ -10,7 +10,7 @@ #include "sdb.h" #include "sdb_private.h" -static inline SdbKv *next_kv(HtPP *ht, SdbKv *kv) { +static inline SdbKv *next_kv(HtSS *ht, SdbKv *kv) { return (SdbKv *)((char *)kv + ht->opt.elem_size); } @@ -751,7 +751,7 @@ RZ_API bool sdb_foreach(Sdb *s, SdbForeachCallback cb, void *user) { ut32 i; for (i = 0; i < s->ht->size; ++i) { - HtPPBucket *bt = &s->ht->table[i]; + HtSSBucket *bt = &s->ht->table[i]; SdbKv *kv; ut32 j, count; @@ -798,7 +798,7 @@ RZ_API bool sdb_sync(Sdb *s) { /* append new keyvalues */ for (i = 0; i < s->ht->size; ++i) { - HtPPBucket *bt = &s->ht->table[i]; + HtSSBucket *bt = &s->ht->table[i]; SdbKv *kv; ut32 j, count; diff --git a/librz/util/sdb/src/sdb.h b/librz/util/sdb/src/sdb.h index 87369b9ed71..ae60f3da235 100644 --- a/librz/util/sdb/src/sdb.h +++ b/librz/util/sdb/src/sdb.h @@ -70,7 +70,7 @@ typedef struct sdb_t { int lock; struct cdb db; struct cdb_make m; - HtPP *ht; + HtSS *ht; ut32 eod; ut32 pos; int fdump; diff --git a/librz/util/sdb/src/sdbht.c b/librz/util/sdb/src/sdbht.c index d187173ec40..3f32fa77dfe 100644 --- a/librz/util/sdb/src/sdbht.c +++ b/librz/util/sdb/src/sdbht.c @@ -3,20 +3,15 @@ #include "sdbht.h" -void sdbkv_fini(SdbKv *kv) { - free(kv->base.key); - free(kv->base.value); -} - -RZ_API HtPP *sdb_ht_new(void) { - HtPP *ht = ht_pp_new((HtPPDupValue)strdup, (HtPPKvFreeFunc)sdbkv_fini, (HtPPCalcSizeV)strlen); +RZ_API HtSS *sdb_ht_new(void) { + HtSS *ht = ht_ss_new(HT_STR_DUP, HT_STR_DUP); if (ht) { ht->opt.elem_size = sizeof(SdbKv); } return ht; } -static bool sdb_ht_internal_insert(HtPP *ht, const char *key, const char *value, bool update) { +static bool sdb_ht_internal_insert(HtSS *ht, const char *key, const char *value, bool update) { if (!ht || !key || !value) { return false; } @@ -32,7 +27,7 @@ static bool sdb_ht_internal_insert(HtPP *ht, const char *key, const char *value, kvp.base.key_len = strlen(kvp.base.key); kvp.base.value_len = strlen(kvp.base.value); kvp.expire = 0; - return ht_pp_insert_kv(ht, (HtPPKv *)&kvp, update); + return ht_ss_insert_kv(ht, (HtSSKv *)&kvp, update); err: free(kvp.base.key); @@ -40,30 +35,30 @@ static bool sdb_ht_internal_insert(HtPP *ht, const char *key, const char *value, return false; } -RZ_API bool sdb_ht_insert(HtPP *ht, const char *key, const char *value) { +RZ_API bool sdb_ht_insert(HtSS *ht, const char *key, const char *value) { return sdb_ht_internal_insert(ht, key, value, false); } -RZ_API bool sdb_ht_insert_kvp(HtPP *ht, SdbKv *kvp, bool update) { - return ht_pp_insert_kv(ht, (HtPPKv *)kvp, update); +RZ_API bool sdb_ht_insert_kvp(HtSS *ht, SdbKv *kvp, bool update) { + return ht_ss_insert_kv(ht, (HtSSKv *)kvp, update); } -RZ_API bool sdb_ht_update(HtPP *ht, const char *key, const char *value) { +RZ_API bool sdb_ht_update(HtSS *ht, const char *key, const char *value) { return sdb_ht_internal_insert(ht, key, value, true); } -RZ_API SdbKv *sdb_ht_find_kvp(HtPP *ht, const char *key, bool *found) { - return (SdbKv *)ht_pp_find_kv(ht, key, found); +RZ_API SdbKv *sdb_ht_find_kvp(HtSS *ht, const char *key, bool *found) { + return (SdbKv *)ht_ss_find_kv(ht, key, found); } -RZ_API char *sdb_ht_find(HtPP *ht, const char *key, bool *found) { - return (char *)ht_pp_find(ht, key, found); +RZ_API char *sdb_ht_find(HtSS *ht, const char *key, bool *found) { + return (char *)ht_ss_find(ht, key, found); } -RZ_API void sdb_ht_free(HtPP *ht) { - ht_pp_free(ht); +RZ_API void sdb_ht_free(HtSS *ht) { + ht_ss_free(ht); } -RZ_API bool sdb_ht_delete(HtPP *ht, const char *key) { - return ht_pp_delete(ht, key); +RZ_API bool sdb_ht_delete(HtSS *ht, const char *key) { + return ht_ss_delete(ht, key); } diff --git a/librz/util/sdb/src/sdbht.h b/librz/util/sdb/src/sdbht.h index f408a40f92a..47d8c8a8836 100644 --- a/librz/util/sdb/src/sdbht.h +++ b/librz/util/sdb/src/sdbht.h @@ -4,7 +4,7 @@ #ifndef __SDB_HT_H #define __SDB_HT_H -#include +#include #ifdef __cplusplus extern "C" { @@ -12,8 +12,8 @@ extern "C" { /** keyvalue pair **/ typedef struct sdb_kv { - // sub of HtPPKv so we can cast safely - HtPPKv base; + // sub of HtSSKv so we can cast safely + HtSSKv base; ut32 cas; ut64 expire; } SdbKv; @@ -40,21 +40,21 @@ extern RZ_API void sdbkv_free(SdbKv *kv); extern RZ_API ut32 sdb_hash(const char *key); -RZ_API HtPP *sdb_ht_new(void); +RZ_API HtSS *sdb_ht_new(void); // Destroy a hashtable and all of its entries. -RZ_API void sdb_ht_free(HtPP *ht); +RZ_API void sdb_ht_free(HtSS *ht); // Insert a new Key-Value pair into the hashtable. If the key already exists, returns false. -RZ_API bool sdb_ht_insert(HtPP *ht, const char *key, const char *value); +RZ_API bool sdb_ht_insert(HtSS *ht, const char *key, const char *value); // Insert a new Key-Value pair into the hashtable, or updates the value if the key already exists. -RZ_API bool sdb_ht_insert_kvp(HtPP *ht, SdbKv *kvp, bool update); +RZ_API bool sdb_ht_insert_kvp(HtSS *ht, SdbKv *kvp, bool update); // Insert a new Key-Value pair into the hashtable, or updates the value if the key already exists. -RZ_API bool sdb_ht_update(HtPP *ht, const char *key, const char *value); +RZ_API bool sdb_ht_update(HtSS *ht, const char *key, const char *value); // Delete a key from the hashtable. -RZ_API bool sdb_ht_delete(HtPP *ht, const char *key); +RZ_API bool sdb_ht_delete(HtSS *ht, const char *key); // Find the value corresponding to the matching key. -RZ_API char *sdb_ht_find(HtPP *ht, const char *key, bool *found); +RZ_API char *sdb_ht_find(HtSS *ht, const char *key, bool *found); // Find the KeyValuePair corresponding to the matching key. -RZ_API SdbKv *sdb_ht_find_kvp(HtPP *ht, const char *key, bool *found); +RZ_API SdbKv *sdb_ht_find_kvp(HtSS *ht, const char *key, bool *found); #ifdef __cplusplus } diff --git a/librz/util/set.c b/librz/util/set.c index 991cf45cee0..1581152594c 100644 --- a/librz/util/set.c +++ b/librz/util/set.c @@ -1,48 +1,77 @@ // SPDX-FileCopyrightText: 2019 pancake +// SPDX-FileCopyrightText: 2024 pelijah // SPDX-License-Identifier: MIT #include +#include -// p - -RZ_API SetP *set_p_new(void) { - return ht_pp_new0(); +/** + * \brief Create a new hash set with C-string as elements. + * \param opt Defines how elements are stored + */ +RZ_API RZ_OWN SetS *set_s_new(HtStrOption opt) { + return ht_sp_new(opt, NULL, NULL); } -RZ_API void set_p_add(SetP *s, const void *u) { - ht_pp_insert(s, u, (void *)1); +/** + * \brief Add element \p str to hash set \p set. + */ +RZ_API void set_s_add(RZ_NONNULL SetS *set, const char *str) { + rz_return_if_fail(set); + ht_sp_insert(set, str, (void *)1); } -RZ_API bool set_p_contains(SetP *s, const void *u) { - return ht_pp_find(s, u, NULL) != NULL; +/** + * \brief Check if hash set \p set contains element \p str. + */ +RZ_API bool set_s_contains(RZ_NONNULL SetS *set, const char *str) { + rz_return_val_if_fail(set, false); + return ht_sp_find(set, str, NULL) != NULL; } -RZ_API void set_p_delete(SetP *s, const void *u) { - ht_pp_delete(s, u); +/** + * \brief Add element \p str from hash set \p set. + */ +RZ_API void set_s_delete(RZ_NONNULL SetS *set, const char *str) { + rz_return_if_fail(set); + ht_sp_delete(set, str); } -RZ_API void set_p_free(SetP *p) { - ht_pp_free((HtPP *)p); +RZ_API void set_s_free(RZ_NULLABLE SetS *set) { + ht_sp_free((HtSP *)set); } -// u - -RZ_API SetU *set_u_new(void) { - return (SetU *)ht_up_new0(); +/** + * \brief Create a new hash set with ut64 as elements. + */ +RZ_API RZ_OWN SetU *set_u_new(void) { + return (SetU *)ht_up_new(NULL, NULL); } -RZ_API void set_u_add(SetU *s, ut64 u) { - ht_up_insert(s, u, (void *)1); +/** + * \brief Add element \p u to hash set \p set. + */ +RZ_API void set_u_add(RZ_NONNULL SetU *set, ut64 u) { + rz_return_if_fail(set); + ht_up_insert(set, u, (void *)1); } -RZ_API bool set_u_contains(SetU *s, ut64 u) { - return ht_up_find(s, u, NULL) != NULL; +/** + * \brief Check if hash set \p set contains element \p u. + */ +RZ_API bool set_u_contains(RZ_NONNULL SetU *set, ut64 u) { + rz_return_val_if_fail(set, false); + return ht_up_find(set, u, NULL) != NULL; } -RZ_API void set_u_delete(SetU *s, ut64 u) { - ht_up_delete(s, u); +/** + * \brief Delete element \p u from hash set \p set. + */ +RZ_API void set_u_delete(RZ_NONNULL SetU *set, ut64 u) { + rz_return_if_fail(set); + ht_up_delete(set, u); } -RZ_API void set_u_free(SetU *s) { - ht_up_free(s); +RZ_API void set_u_free(RZ_NULLABLE SetU *set) { + ht_up_free((HtUP *)set); } diff --git a/librz/util/str_constpool.c b/librz/util/str_constpool.c index d60ec306a08..859a6e2c651 100644 --- a/librz/util/str_constpool.c +++ b/librz/util/str_constpool.c @@ -3,29 +3,25 @@ #include "rz_util/rz_str_constpool.h" -static void kv_fini(HtPPKv *kv) { - free(kv->key); -} - RZ_API bool rz_str_constpool_init(RzStrConstPool *pool) { - pool->ht = ht_pp_new(NULL, kv_fini, NULL); + pool->ht = ht_sp_new(HT_STR_DUP, NULL, NULL); return pool->ht != NULL; } RZ_API void rz_str_constpool_fini(RzStrConstPool *pool) { - ht_pp_free(pool->ht); + ht_sp_free(pool->ht); } RZ_API const char *rz_str_constpool_get(RzStrConstPool *pool, const char *str) { if (!str) { return NULL; } - HtPPKv *kv = ht_pp_find_kv(pool->ht, str, NULL); + HtSPKv *kv = ht_sp_find_kv(pool->ht, str, NULL); if (kv) { return kv->key; } - ht_pp_insert(pool->ht, str, NULL); - kv = ht_pp_find_kv(pool->ht, str, NULL); + ht_sp_insert(pool->ht, str, NULL); + kv = ht_sp_find_kv(pool->ht, str, NULL); if (kv) { return kv->key; } diff --git a/librz/util/sys.c b/librz/util/sys.c index e0159c395bb..c693b6eb26e 100644 --- a/librz/util/sys.c +++ b/librz/util/sys.c @@ -1572,7 +1572,7 @@ static bool is_child = false; RZ_DEFINE_CONSTRUCTOR(sys_pipe_constructor) static void sys_pipe_constructor(void) { sys_pipe_mutex = rz_th_lock_new(false); - fd2close = ht_uu_new0(); + fd2close = ht_uu_new(); } #ifdef RZ_DEFINE_DESTRUCTOR_NEEDS_PRAGMA diff --git a/librz/util/thread_hash_table.c b/librz/util/thread_hash_table.c index 4faba42b155..21ae9320ba0 100644 --- a/librz/util/thread_hash_table.c +++ b/librz/util/thread_hash_table.c @@ -23,33 +23,19 @@ free(ht); \ } -#define th_ht_new0_decl(name) \ - RZ_API th_ht_type(name) * rz_th_##name##_new0(void) { \ +#define th_ht_new_decl(name, type) \ + RZ_API th_ht_type(name) * rz_th_##name##_new(type *table) { \ + rz_return_val_if_fail(table, NULL); \ th_ht_type(name) *ht = RZ_NEW0(th_ht_type(name)); \ if (!ht) { \ return NULL; \ } \ - ht->table = name##_new0(); \ ht->lock = rz_th_lock_new(true); \ - if (!ht->table || !ht->lock) { \ - th_ht_free(name, ht); \ - return NULL; \ - } \ - return ht; \ - } - -#define th_ht_new_opt_decl(name, type) \ - RZ_API th_ht_type(name) * rz_th_##name##_new_opt(type##Options *opt) { \ - th_ht_type(name) *ht = RZ_NEW0(th_ht_type(name)); \ - if (!ht) { \ - return NULL; \ - } \ - ht->table = name##_new_opt(opt); \ - ht->lock = rz_th_lock_new(true); \ - if (!ht->table || !ht->lock) { \ - th_ht_free(name, ht); \ + if (!ht->lock) { \ + free(ht); \ return NULL; \ } \ + ht->table = table; \ return ht; \ } @@ -101,8 +87,7 @@ #define th_ht_define(name, type, ktype, vtype) \ th_ht_struct(name, type); \ th_ht_free_decl(name); \ - th_ht_new0_decl(name); \ - th_ht_new_opt_decl(name, type); \ + th_ht_new_decl(name, type); \ th_ht_kv_op_decl(name, insert, const ktype, vtype); \ th_ht_kv_op_decl(name, update, const ktype, vtype); \ th_ht_delete_decl(name, ktype); \ @@ -114,3 +99,6 @@ th_ht_define(ht_pp, HtPP, void *, void *); th_ht_define(ht_up, HtUP, ut64, void *); th_ht_define(ht_uu, HtUU, ut64, ut64); th_ht_define(ht_pu, HtPU, void *, ut64); +th_ht_define(ht_sp, HtSP, char *, void *); +th_ht_define(ht_ss, HtSS, char *, char *); +th_ht_define(ht_su, HtSU, char *, ut64); diff --git a/test/unit/test_analysis_function.c b/test/unit/test_analysis_function.c index 2a33ad996ab..f2745d22b9c 100644 --- a/test/unit/test_analysis_function.c +++ b/test/unit/test_analysis_function.c @@ -44,7 +44,7 @@ bool ht_up_count(void *user, const ut64 k, const void *v) { return true; } -bool ht_pp_count(void *user, const void *k, const void *v) { +bool ht_sp_count(void *user, const char *k, const void *v) { size_t *count = user; (*count)++; return true; @@ -59,7 +59,7 @@ static bool function_check_invariants(RzAnalysis *analysis) { RzAnalysisFunction *fcn; rz_list_foreach (analysis->fcns, it, fcn) { mu_assert_ptreq(ht_up_find(analysis->ht_addr_fun, fcn->addr, NULL), fcn, "function in addr ht"); - mu_assert_ptreq(ht_pp_find(analysis->ht_name_fun, fcn->name, NULL), fcn, "function in name ht"); + mu_assert_ptreq(ht_sp_find(analysis->ht_name_fun, fcn->name, NULL), fcn, "function in name ht"); } size_t addr_count = 0; @@ -67,7 +67,7 @@ static bool function_check_invariants(RzAnalysis *analysis) { mu_assert_eq(addr_count, rz_list_length(analysis->fcns), "function addr ht count"); size_t name_count = 0; - ht_pp_foreach(analysis->ht_name_fun, ht_pp_count, &name_count); + ht_sp_foreach(analysis->ht_name_fun, ht_sp_count, &name_count); mu_assert_eq(name_count, rz_list_length(analysis->fcns), "function name ht count"); return true; diff --git a/test/unit/test_il_validate.c b/test/unit/test_il_validate.c index d0b455952f3..b82bde812b4 100644 --- a/test/unit/test_il_validate.c +++ b/test/unit/test_il_validate.c @@ -996,17 +996,17 @@ static bool test_il_validate_effect_repeat() { // types remembered from the loop op = rz_il_op_new_repeat(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0))); - HtPP *local_var_sorts; + HtSP *local_var_sorts; val = rz_il_validate_effect(op, ctx, &local_var_sorts, &t, &report); mu_assert_true(val, "valid"); mu_assert_eq(t, RZ_IL_TYPE_EFFECT_DATA, "effect type"); mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 1, "local var sorts count"); - RzILSortPure *sort = ht_pp_find(local_var_sorts, "x", NULL); + RzILSortPure *sort = ht_sp_find(local_var_sorts, "x", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); @@ -1020,13 +1020,13 @@ static bool test_il_validate_effect_repeat() { mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 2, "local var sorts count"); - sort = ht_pp_find(local_var_sorts, "x", NULL); + sort = ht_sp_find(local_var_sorts, "x", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort"); - sort = ht_pp_find(local_var_sorts, "y", NULL); + sort = ht_sp_find(local_var_sorts, "y", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); @@ -1040,13 +1040,13 @@ static bool test_il_validate_effect_repeat() { mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 2, "local var sorts count"); - sort = ht_pp_find(local_var_sorts, "x", NULL); + sort = ht_sp_find(local_var_sorts, "x", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort"); - sort = ht_pp_find(local_var_sorts, "y", NULL); + sort = ht_sp_find(local_var_sorts, "y", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); @@ -1139,19 +1139,19 @@ static bool test_il_validate_effect_branch() { op = rz_il_op_new_branch(rz_il_op_new_b0(), rz_il_op_new_set("x", true, rz_il_op_new_bitv_from_ut64(14, 0)), rz_il_op_new_set("y", true, rz_il_op_new_b0())); - HtPP *local_var_sorts; + HtSP *local_var_sorts; val = rz_il_validate_effect(op, ctx, &local_var_sorts, &t, &report); mu_assert_true(val, "valid"); mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 2, "local var sorts count"); - RzILSortPure *sort = ht_pp_find(local_var_sorts, "x", NULL); + RzILSortPure *sort = ht_sp_find(local_var_sorts, "x", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort"); - sort = ht_pp_find(local_var_sorts, "y", NULL); + sort = ht_sp_find(local_var_sorts, "y", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); @@ -1166,10 +1166,10 @@ static bool test_il_validate_effect_branch() { mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 1, "local var sorts count"); - sort = ht_pp_find(local_var_sorts, "y", NULL); + sort = ht_sp_find(local_var_sorts, "y", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); @@ -1183,13 +1183,13 @@ static bool test_il_validate_effect_branch() { mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 2, "local var sorts count"); - sort = ht_pp_find(local_var_sorts, "x", NULL); + sort = ht_sp_find(local_var_sorts, "x", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort"); - sort = ht_pp_find(local_var_sorts, "y", NULL); + sort = ht_sp_find(local_var_sorts, "y", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); @@ -1202,13 +1202,13 @@ static bool test_il_validate_effect_branch() { mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 2, "local var sorts count"); - sort = ht_pp_find(local_var_sorts, "x", NULL); + sort = ht_sp_find(local_var_sorts, "x", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort"); - sort = ht_pp_find(local_var_sorts, "y", NULL); + sort = ht_sp_find(local_var_sorts, "y", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); @@ -1224,13 +1224,13 @@ static bool test_il_validate_effect_branch() { mu_assert_null(report, "no report"); mu_assert_notnull(local_var_sorts, "local var sorts"); mu_assert_eq(local_var_sorts->count, 2, "local var sorts count"); - sort = ht_pp_find(local_var_sorts, "x", NULL); + sort = ht_sp_find(local_var_sorts, "x", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bv(14)), "local var sort"); - sort = ht_pp_find(local_var_sorts, "y", NULL); + sort = ht_sp_find(local_var_sorts, "y", NULL); mu_assert_notnull(sort, "local var sort"); mu_assert_true(rz_il_sort_pure_eq(*sort, rz_il_sort_pure_bool()), "local var sort"); - ht_pp_free(local_var_sorts); + ht_sp_free(local_var_sorts); local_var_sorts = NULL; rz_il_op_effect_free(op); diff --git a/test/unit/test_sdb_hash.c b/test/unit/test_sdb_hash.c index 79d80b90d49..747461fe6a8 100644 --- a/test/unit/test_sdb_hash.c +++ b/test/unit/test_sdb_hash.c @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include typedef struct _test_struct { char *name; @@ -14,7 +17,7 @@ typedef struct _test_struct { } Person; bool test_ht_insert_lookup(void) { - HtPP *ht = sdb_ht_new(); + HtSS *ht = sdb_ht_new(); sdb_ht_insert(ht, "AAAA", "vAAAA"); sdb_ht_insert(ht, "BBBB", "vBBBB"); sdb_ht_insert(ht, "CCCC", "vCCCC"); @@ -28,7 +31,7 @@ bool test_ht_insert_lookup(void) { } bool test_ht_update_lookup(void) { - HtPP *ht = sdb_ht_new(); + HtSS *ht = sdb_ht_new(); sdb_ht_insert(ht, "AAAA", "vAAAA"); sdb_ht_insert(ht, "BBBB", "vBBBB"); @@ -45,7 +48,7 @@ bool test_ht_update_lookup(void) { } bool test_ht_delete(void) { - HtPP *ht = sdb_ht_new(); + HtSS *ht = sdb_ht_new(); mu_assert("nothing should be deleted", !sdb_ht_delete(ht, "non existing")); sdb_ht_insert(ht, "AAAA", "vAAAA"); @@ -57,7 +60,7 @@ bool test_ht_delete(void) { } bool test_ht_insert_kvp(void) { - HtPP *ht = sdb_ht_new(); + HtSS *ht = sdb_ht_new(); SdbKv *kv = sdbkv_new("AAAA", "vAAAA"); mu_assert("AAAA shouldn't exist", !sdb_ht_find_kvp(ht, "AAAA", NULL)); sdb_ht_insert_kvp(ht, kv, false); @@ -76,31 +79,31 @@ bool test_ht_insert_kvp(void) { mu_end; } -ut32 create_collision(const void *key) { +ut32 create_collision(RZ_UNUSED const char *key) { return 10; } bool test_ht_insert_collision(void) { - HtPP *ht = sdb_ht_new(); + HtSS *ht = sdb_ht_new(); ht->opt.hashfn = create_collision; - ht_pp_insert(ht, "AAAA", "vAAAA"); + ht_ss_insert(ht, "AAAA", "vAAAA"); mu_assert_streq(sdb_ht_find(ht, "AAAA", NULL), "vAAAA", "AAAA should be there"); - ht_pp_insert(ht, "BBBB", "vBBBB"); + ht_ss_insert(ht, "BBBB", "vBBBB"); mu_assert_streq(sdb_ht_find(ht, "AAAA", NULL), "vAAAA", "AAAA should still be there"); mu_assert_streq(sdb_ht_find(ht, "BBBB", NULL), "vBBBB", "BBBB should be there"); - ht_pp_insert(ht, "CCCC", "vBBBB"); + ht_ss_insert(ht, "CCCC", "vBBBB"); mu_assert_streq(sdb_ht_find(ht, "CCCC", NULL), "vBBBB", "CCCC should be there"); sdb_ht_free(ht); mu_end; } -ut32 key2hash(const void *key) { +ut32 key2hash(const char *key) { return atoi(key); } bool test_ht_grow(void) { - HtPP *ht = sdb_ht_new(); + HtSS *ht = sdb_ht_new(); char str[15], vstr[15]; char buf[100]; int i; @@ -127,7 +130,7 @@ bool test_ht_grow(void) { } bool test_ht_kvp(void) { - HtPP *ht = sdb_ht_new(); + HtSS *ht = sdb_ht_new(); SdbKv *kvp = sdbkv_new("AAAA", "vAAAA"); mu_assert_eq(kvp->base.key_len, 4, "key_len should be 4"); @@ -155,9 +158,10 @@ Person *duplicate_person(Person *p) { return c; } -void free_kv(HtPPKv *kv) { - free(kv->key); - Person *p = kv->value; +void free_person(Person *p) { + if (!p) { + return; + } free(p->name); free(p); } @@ -183,117 +187,110 @@ bool test_ht_general(void) { person2->name = strdup("pancake"); person2->age = 9000; - HtPP *ht = ht_pp_new((HtPPDupValue)duplicate_person, free_kv, (HtPPCalcSizeV)calcSizePerson); + HtSP *ht = ht_sp_new(HT_STR_DUP, (HtSPDupValue)duplicate_person, (HtSPFreeValue)free_person); if (!ht) { mu_cleanup_fail(err_free_persons, "ht alloc"); } - ht_pp_insert(ht, "radare", (void *)person1); - ht_pp_insert(ht, "pancake", (void *)person2); - p = ht_pp_find(ht, "radare", &found); + ht_sp_insert(ht, "radare", (void *)person1); + ht_sp_insert(ht, "pancake", (void *)person2); + p = ht_sp_find(ht, "radare", &found); mu_assert("radare not found", found); mu_assert_streq(p->name, "radare", "wrong person"); mu_assert_eq(p->age, 10, "wrong radare age"); - p = ht_pp_find(ht, "pancake", &found); + p = ht_sp_find(ht, "pancake", &found); mu_assert("radare not found", found); mu_assert_streq(p->name, "pancake", "wrong person"); mu_assert_eq(p->age, 9000, "wrong pancake age"); - (void)ht_pp_find(ht, "not", &found); + (void)ht_sp_find(ht, "not", &found); mu_assert("found but it should not exists", !found); - ht_pp_delete(ht, "pancake"); - p = ht_pp_find(ht, "pancake", &found); + ht_sp_delete(ht, "pancake"); + p = ht_sp_find(ht, "pancake", &found); mu_assert("pancake was deleted", !found); - ht_pp_insert(ht, "pancake", (void *)person2); - ht_pp_delete(ht, "radare"); - ht_pp_update(ht, "pancake", (void *)person1); - p = ht_pp_find(ht, "pancake", &found); + ht_sp_insert(ht, "pancake", (void *)person2); + ht_sp_delete(ht, "radare"); + ht_sp_update(ht, "pancake", (void *)person1); + p = ht_sp_find(ht, "pancake", &found); mu_assert("pancake was updated", found); mu_assert_streq(p->name, "radare", "wrong person"); mu_assert_eq(p->age, 10, "wrong age"); - ht_pp_free(ht); + ht_sp_free(ht); err_free_persons: - free(person2->name); - free(person2); + free_person(person2); err_free_person1: - free(person1->name); - free(person1); + free_person(person1); err_malloc: mu_cleanup_end; } -static void free_key_value(HtPPKv *kv) { - free(kv->key); - free(kv->value); -} - -bool should_not_be_caled(void *user, const char *k, void *v) { +bool should_not_be_caled(void *user, const char *k, const void *v) { mu_fail("this function should not be called"); return false; } bool test_empty_ht(void) { - HtPP *ht = ht_pp_new0(); - ht_pp_foreach(ht, (HtPPForeachCallback)should_not_be_caled, NULL); - void *r = ht_pp_find(ht, "key1", NULL); + HtSP *ht = ht_sp_new(HT_STR_DUP, NULL, NULL); + ht_sp_foreach(ht, should_not_be_caled, NULL); + void *r = ht_sp_find(ht, "key1", NULL); mu_assert_null(r, "key1 should not be present"); - ht_pp_free(ht); + ht_sp_free(ht); mu_end; } bool test_insert(void) { - HtPP *ht = ht_pp_new0(); + HtSS *ht = ht_ss_new(HT_STR_CONST, HT_STR_CONST); void *r; bool res; bool found; - res = ht_pp_insert(ht, "key1", "value1"); + res = ht_ss_insert(ht, "key1", "value1"); mu_assert("key1 should be a new element", res); - r = ht_pp_find(ht, "key1", &found); + r = ht_ss_find(ht, "key1", &found); mu_assert("found should be true", found); mu_assert_streq(r, "value1", "value1 should be retrieved"); - res = ht_pp_insert(ht, "key1", "value2"); + res = ht_ss_insert(ht, "key1", "value2"); mu_assert("key1 should be an already existing element", !res); - r = ht_pp_find(ht, "key1", &found); + r = ht_ss_find(ht, "key1", &found); mu_assert_streq(r, "value1", "value1 should be retrieved"); mu_assert("found should be true", found); - r = ht_pp_find(ht, "key2", &found); + r = ht_ss_find(ht, "key2", &found); mu_assert_null(r, "key2 should not be present"); mu_assert("found for key2 should be false", !found); - ht_pp_free(ht); + ht_ss_free(ht); mu_end; } bool test_update(void) { - HtPP *ht = ht_pp_new0(); + HtSS *ht = ht_ss_new(HT_STR_DUP, HT_STR_DUP); bool found; - ht_pp_insert(ht, "key1", "value1"); - ht_pp_update(ht, "key1", "value2"); - void *r = ht_pp_find(ht, "key1", &found); + ht_ss_insert(ht, "key1", "value1"); + ht_ss_update(ht, "key1", "value2"); + void *r = ht_ss_find(ht, "key1", &found); mu_assert_streq(r, "value2", "value2 should be retrieved"); mu_assert("found should be true", found); - ht_pp_free(ht); + ht_ss_free(ht); mu_end; } bool test_delete(void) { - HtPP *ht = ht_pp_new0(); + HtSS *ht = ht_ss_new(HT_STR_DUP, HT_STR_DUP); bool found; - ht_pp_insert(ht, "key1", "value1"); - ht_pp_delete(ht, "key1"); - void *r = ht_pp_find(ht, "key1", &found); + ht_ss_insert(ht, "key1", "value1"); + ht_ss_delete(ht, "key1"); + void *r = ht_ss_find(ht, "key1", &found); mu_assert_null(r, "key1 should not be found"); mu_assert("found should be false", !found); - ht_pp_free(ht); + ht_ss_free(ht); mu_end; } @@ -304,18 +301,18 @@ static bool grow_1_foreach(void *user, const char *k, int v) { } bool test_grow_1(void) { - HtPP *ht = ht_pp_new0(); + HtSP *ht = ht_sp_new(HT_STR_DUP, NULL, NULL); int i; for (i = 0; i < 3; ++i) { grow_1_found[i] = false; } - ht_pp_insert(ht, "key0", (void *)0); - ht_pp_insert(ht, "key1", (void *)1); - ht_pp_insert(ht, "key2", (void *)2); + ht_sp_insert(ht, "key0", (void *)0); + ht_sp_insert(ht, "key1", (void *)1); + ht_sp_insert(ht, "key2", (void *)2); - ht_pp_foreach(ht, (HtPPForeachCallback)grow_1_foreach, NULL); + ht_sp_foreach(ht, (HtSPForeachCallback)grow_1_foreach, NULL); for (i = 0; i < 3; ++i) { if (!grow_1_found[i]) { fprintf(stderr, "i = %d\n", i); @@ -323,12 +320,12 @@ bool test_grow_1(void) { } } - ht_pp_free(ht); + ht_sp_free(ht); mu_end; } bool test_grow_2(void) { - HtPP *ht = ht_pp_new((HtPPDupValue)strdup, (HtPPKvFreeFunc)free_key_value, NULL); + HtSS *ht = ht_ss_new(HT_STR_DUP, HT_STR_DUP); char *r; bool found; int i; @@ -337,27 +334,27 @@ bool test_grow_2(void) { char buf[20], buf2[20]; snprintf(buf, 20, "key%d", i); snprintf(buf2, 20, "value%d", i); - ht_pp_insert(ht, buf, buf2); + ht_ss_insert(ht, buf, buf2); } - r = ht_pp_find(ht, "key1", &found); + r = ht_ss_find(ht, "key1", &found); mu_assert_streq(r, "value1", "value1 should be retrieved"); mu_assert("found should be true", found); - r = ht_pp_find(ht, "key2000", &found); + r = ht_ss_find(ht, "key2000", &found); mu_assert_streq(r, "value2000", "value2000 should be retrieved"); mu_assert("found should be true", found); - r = ht_pp_find(ht, "key4000", &found); + r = ht_ss_find(ht, "key4000", &found); mu_assert_null(r, "key4000 should not be there"); mu_assert("found should be false", !found); - ht_pp_free(ht); + ht_ss_free(ht); mu_end; } bool test_grow_3(void) { - HtPP *ht = ht_pp_new((HtPPDupValue)strdup, (HtPPKvFreeFunc)free_key_value, NULL); + HtSS *ht = ht_ss_new(HT_STR_DUP, HT_STR_DUP); char *r; bool found; int i; @@ -366,47 +363,47 @@ bool test_grow_3(void) { char buf[20], buf2[20]; snprintf(buf, 20, "key%d", i); snprintf(buf2, 20, "value%d", i); - ht_pp_insert(ht, buf, buf2); + ht_ss_insert(ht, buf, buf2); } for (i = 0; i < 3000; i += 3) { char buf[20]; snprintf(buf, 20, "key%d", i); - ht_pp_delete(ht, buf); + ht_ss_delete(ht, buf); } - r = ht_pp_find(ht, "key1", &found); + r = ht_ss_find(ht, "key1", &found); mu_assert_streq(r, "value1", "value1 should be retrieved"); mu_assert("found should be true", found); - r = ht_pp_find(ht, "key2000", &found); + r = ht_ss_find(ht, "key2000", &found); mu_assert_streq(r, "value2000", "value2000 should be retrieved"); mu_assert("found should be true", found); - r = ht_pp_find(ht, "key4000", &found); + r = ht_ss_find(ht, "key4000", &found); mu_assert_null(r, "key4000 should not be there"); mu_assert("found should be false", !found); - r = ht_pp_find(ht, "key0", &found); + r = ht_ss_find(ht, "key0", &found); mu_assert_null(r, "key0 should not be there"); mu_assert("found should be false", !found); for (i = 1; i < 3000; i += 3) { char buf[20]; snprintf(buf, 20, "key%d", i); - ht_pp_delete(ht, buf); + ht_ss_delete(ht, buf); } - r = ht_pp_find(ht, "key1", &found); + r = ht_ss_find(ht, "key1", &found); mu_assert_null(r, "key1 should not be there"); mu_assert("found should be false", !found); - ht_pp_free(ht); + ht_ss_free(ht); mu_end; } bool test_grow_4(void) { - HtPP *ht = ht_pp_new(NULL, (HtPPKvFreeFunc)free_key_value, NULL); + HtSS *ht = ht_ss_new(HT_STR_DUP, HT_STR_OWN); char *r; bool found; int i; @@ -416,42 +413,42 @@ bool test_grow_4(void) { snprintf(buf, 20, "key%d", i); buf2 = malloc(20); snprintf(buf2, 20, "value%d", i); - ht_pp_insert(ht, buf, buf2); + ht_ss_insert(ht, buf, buf2); } - r = ht_pp_find(ht, "key1", &found); + r = ht_ss_find(ht, "key1", &found); mu_assert_streq(r, "value1", "value1 should be retrieved"); mu_assert("found should be true", found); - r = ht_pp_find(ht, "key2000", &found); + r = ht_ss_find(ht, "key2000", &found); mu_assert_streq(r, "value2000", "value2000 should be retrieved"); mu_assert("found should be true", found); for (i = 0; i < 3000; i += 3) { char buf[20]; snprintf(buf, 20, "key%d", i); - ht_pp_delete(ht, buf); + ht_ss_delete(ht, buf); } - r = ht_pp_find(ht, "key2000", &found); + r = ht_ss_find(ht, "key2000", &found); mu_assert_streq(r, "value2000", "value2000 should be retrieved"); mu_assert("found should be true", found); - r = ht_pp_find(ht, "key0", &found); + r = ht_ss_find(ht, "key0", &found); mu_assert_null(r, "key0 should not be there"); mu_assert("found should be false", !found); for (i = 1; i < 3000; i += 3) { char buf[20]; snprintf(buf, 20, "key%d", i); - ht_pp_delete(ht, buf); + ht_ss_delete(ht, buf); } - r = ht_pp_find(ht, "key1", &found); + r = ht_ss_find(ht, "key1", &found); mu_assert_null(r, "key1 should not be there"); mu_assert("found should be false", !found); - ht_pp_free(ht); + ht_ss_free(ht); mu_end; } @@ -462,12 +459,8 @@ bool foreach_delete_cb(void *user, const ut64 key, const void *v) { return true; } -static void free_up_value(HtUPKv *kv) { - free(kv->value); -} - bool test_foreach_delete(void) { - HtUP *ht = ht_up_new((HtUPDupValue)strdup, free_up_value, NULL); + HtUP *ht = ht_up_new((HtUPDupValue)strdup, free); // create a collision ht_up_insert(ht, 0, "value1"); @@ -484,7 +477,7 @@ bool test_foreach_delete(void) { bool test_update_key(void) { bool res; - HtUP *ht = ht_up_new((HtUPDupValue)strdup, free_up_value, NULL); + HtUP *ht = ht_up_new((HtUPDupValue)strdup, free); // create a collision ht_up_insert(ht, 0, "value1"); @@ -508,31 +501,31 @@ bool test_update_key(void) { bool test_ht_pu_ops(void) { bool res; ut64 val; - HtPU *ht = ht_pu_new0(); + HtSU *ht = ht_su_new(HT_STR_DUP); - ht_pu_insert(ht, "key1", 0xcafebabe); - val = ht_pu_find(ht, "key1", &res); + ht_su_insert(ht, "key1", 0xcafebabe); + val = ht_su_find(ht, "key1", &res); mu_assert_eq(val, 0xcafebabe, "0xcafebabe should be retrieved"); mu_assert("found should be true", res); - res = ht_pu_insert(ht, "key1", 0xdeadbeefdeadbeef); + res = ht_su_insert(ht, "key1", 0xdeadbeefdeadbeef); mu_assert("key1 should be an already existing element", !res); - val = ht_pu_find(ht, "key1", &res); + val = ht_su_find(ht, "key1", &res); mu_assert_eq(val, 0xcafebabe, "0xcafebabe should still be retrieved"); - res = ht_pu_update(ht, "key1", 0xdeadbeefdeadbeef); + res = ht_su_update(ht, "key1", 0xdeadbeefdeadbeef); mu_assert("key1 should be updated", res); - val = ht_pu_find(ht, "key1", &res); + val = ht_su_find(ht, "key1", &res); mu_assert_eq(val, 0xdeadbeefdeadbeef, "0xdeadbeefdeadbeef should be retrieved"); mu_assert("found should be true", res); - res = ht_pu_delete(ht, "key1"); + res = ht_su_delete(ht, "key1"); mu_assert("key1 should be deleted", res); - val = ht_pu_find(ht, "key1", &res); + val = ht_su_find(ht, "key1", &res); mu_assert_eq(val, 0, "0 should be retrieved"); mu_assert("found should be false", !res); - ht_pu_free(ht); + ht_su_free(ht); mu_end; } diff --git a/test/unit/test_threads.c b/test/unit/test_threads.c index 17bdb26c3ff..47ba3472c0c 100644 --- a/test/unit/test_threads.c +++ b/test/unit/test_threads.c @@ -85,39 +85,40 @@ bool test_thread_ht(void) { bool v_boolean = false; const char *element = NULL; - RzThreadHtPP *ht = rz_th_ht_pp_new0(); - mu_assert_notnull(ht, "rz_th_ht_pp_new0() null check"); + HtSS *tab = ht_ss_new(HT_STR_DUP, HT_STR_DUP); + RzThreadHtSS *ht = rz_th_ht_ss_new(tab); + mu_assert_notnull(ht, "rz_th_ht_ss_new() null check"); v_boolean = true; - element = (const char *)rz_th_ht_pp_find(ht, "not found", &v_boolean); + element = rz_th_ht_ss_find(ht, "not found", &v_boolean); mu_assert_false(v_boolean, "the search must say not found"); mu_assert_null(element, "the search must return NULL"); - v_boolean = rz_th_ht_pp_insert(ht, "foo", "bar"); + v_boolean = rz_th_ht_ss_insert(ht, "foo", "bar"); mu_assert_true(v_boolean, "the insert must succeed"); v_boolean = false; - element = (const char *)rz_th_ht_pp_find(ht, "foo", &v_boolean); + element = rz_th_ht_ss_find(ht, "foo", &v_boolean); mu_assert_true(v_boolean, "the search must say found"); mu_assert_notnull(element, "the search must NOT return NULL"); mu_assert_streq(element, "bar", "expecting to find 'bar' when searching for 'foo'"); - element = (const char *)rz_th_ht_pp_find(ht, "foo", NULL); + element = rz_th_ht_ss_find(ht, "foo", NULL); mu_assert_notnull(element, "the search must NOT return NULL"); mu_assert_streq(element, "bar", "expecting to find 'bar' when searching for 'foo'"); - v_boolean = rz_th_ht_pp_delete(ht, "not found"); + v_boolean = rz_th_ht_ss_delete(ht, "not found"); mu_assert_false(v_boolean, "the delete must fail"); - v_boolean = rz_th_ht_pp_delete(ht, "foo"); + v_boolean = rz_th_ht_ss_delete(ht, "foo"); mu_assert_true(v_boolean, "the delete must succeed"); v_boolean = true; - element = (const char *)rz_th_ht_pp_find(ht, "foo", &v_boolean); + element = rz_th_ht_ss_find(ht, "foo", &v_boolean); mu_assert_false(v_boolean, "the search must say not found"); mu_assert_null(element, "the search must return NULL"); - rz_th_ht_pp_free(ht); + rz_th_ht_ss_free(ht); mu_end; }