From 73d4b0b8bbf17fc0429c74c5870c1deea4d4ed5f Mon Sep 17 00:00:00 2001 From: pelijah Date: Thu, 4 Apr 2024 22:59:42 +0300 Subject: [PATCH] Add ht_pp_new_s2p() and ht_pp_new_s2s() --- binrz/rz-test/rz-test.c | 7 +-- librz/arch/analysis.c | 9 +--- librz/arch/asm.c | 11 +---- librz/arch/block.c | 2 +- librz/arch/class.c | 2 +- librz/arch/dwarf_process.c | 12 +---- librz/arch/esil/esil.c | 7 +-- librz/arch/esil/esil_interrupt.c | 2 +- librz/arch/esil/esil_trace.c | 2 +- librz/arch/fcn.c | 2 +- librz/arch/function.c | 11 ++--- librz/arch/hint.c | 2 +- librz/arch/il/analysis_il_trace.c | 2 +- librz/arch/platform_profile.c | 2 +- librz/arch/rtti_msvc.c | 2 +- librz/arch/serialize_analysis.c | 2 +- librz/arch/xrefs.c | 4 +- librz/bin/bobj_process_class.c | 6 +-- librz/bin/bobj_process_section.c | 2 +- librz/bin/bobj_process_symbol.c | 2 +- librz/bin/dwarf/abbrev.c | 2 +- librz/bin/dwarf/macro.h | 2 +- librz/bin/format/elf/elf_symbols.c | 2 +- librz/bin/format/mach0/mach0.c | 2 +- librz/config/config.c | 2 +- librz/config/serialize_config.c | 2 +- librz/cons/canvas.c | 2 +- librz/cons/hud.c | 7 +-- librz/core/agraph.c | 4 +- librz/core/analysis_objc.c | 2 +- librz/core/analysis_tp.c | 5 +- librz/core/cbin.c | 7 +-- librz/core/cmd/cmd_api.c | 9 +--- librz/core/cmd/cmd_info.c | 2 +- librz/core/disasm.c | 10 +--- librz/core/tui/panels.c | 7 +-- librz/debug/debug.c | 2 +- librz/debug/dsession.c | 2 +- librz/debug/trace.c | 4 +- librz/diff/diff.c | 19 ++++--- librz/flag/flag.c | 9 +--- librz/il/definitions/variable.c | 14 +----- librz/il/il_validate.c | 15 ++---- librz/include/rz_util/ht_inc.h | 17 ++++++- librz/include/rz_util/ht_pp.h | 6 +-- librz/include/rz_util/rz_serialize.h | 2 +- librz/io/p_cache.c | 2 +- librz/main/rz-asm.c | 6 +-- librz/reg/profile.c | 2 +- librz/sign/sigdb.c | 2 +- librz/syscall/syscall.c | 2 +- librz/type/function.c | 6 +-- librz/type/parser/c_cpp_parser.c | 6 +-- librz/type/serialize_functions.c | 2 +- librz/type/type.c | 42 +++++----------- librz/util/event.c | 2 +- librz/util/ht/ht_inc.c | 17 ++++++- librz/util/ht/ht_pp.c | 74 +++++++++++++++------------- librz/util/ht/ht_pu.c | 2 +- librz/util/ht/ht_uu.c | 11 +---- librz/util/sdb/src/sdbht.c | 7 +-- librz/util/set.c | 2 +- librz/util/str_constpool.c | 6 +-- test/unit/test_sdb_hash.c | 38 ++++++-------- 64 files changed, 190 insertions(+), 287 deletions(-) diff --git a/binrz/rz-test/rz-test.c b/binrz/rz-test/rz-test.c index ca3ba88c38e..a682036e8b0 100644 --- a/binrz/rz-test/rz-test.c +++ b/binrz/rz-test/rz-test.c @@ -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,7 +512,7 @@ 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_pp_new_s2p(HT_STR_DUP, NULL, &free); if (state.path_left) { void **it; rz_pvector_foreach (&state.queue, it) { diff --git a/librz/arch/analysis.c b/librz/arch/analysis.c index 68e9e9ce083..b66733553bc 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) { @@ -87,7 +82,7 @@ RZ_API RzAnalysis *rz_analysis_new(void) { } analysis->bb_tree = NULL; analysis->ht_addr_fun = ht_up_new0(); - analysis->ht_name_fun = ht_pp_new0(); + analysis->ht_name_fun = ht_pp_new_s2p(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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_analysis_var_global_free); analysis->global_var_tree = NULL; analysis->il_vm = NULL; analysis->hash = rz_hash_new(); diff --git a/librz/arch/asm.c b/librz/arch/asm.c index 3774e67030b..c1486316cee 100644 --- a/librz/arch/asm.c +++ b/librz/arch/asm.c @@ -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; @@ -863,7 +854,7 @@ RZ_API RzAsmCode *rz_asm_massemble(RzAsm *a, const char *assembly) { return NULL; } ht_pp_free(a->flags); - if (!(a->flags = ht_pp_new(__dup_val, __flag_free_kv, NULL))) { + if (!(a->flags = ht_pp_new_s2s(HT_STR_DUP, HT_STR_DUP))) { free(tokens); return NULL; } diff --git a/librz/arch/block.c b/librz/arch/block.c index 200d5ed55b1..e4458a6758a 100644 --- a/librz/arch/block.c +++ b/librz/arch/block.c @@ -721,7 +721,7 @@ typedef struct { bool reachable; } NoreturnSuccessor; -static void noreturn_successor_free(HtUPKv *kv) { +static void noreturn_successor_free(HtUPKv *kv, RZ_UNUSED void *user) { NoreturnSuccessor *succ = kv->value; rz_analysis_block_unref(succ->block); free(succ); diff --git a/librz/arch/class.c b/librz/arch/class.c index 82e7d9ea836..70c9d2b125c 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(); + HtPP /**/ *hashmap = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); if (!hashmap) { rz_graph_free(class_graph); ls_free(classes); diff --git a/librz/arch/dwarf_process.c b/librz/arch/dwarf_process.c index fbe9e5c91f0..03ecafe2b74 100644 --- a/librz/arch/dwarf_process.c +++ b/librz/arch/dwarf_process.c @@ -9,7 +9,7 @@ #include #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) { \ if (!kv) \ return; \ f(kv->value); \ @@ -2077,14 +2077,6 @@ 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 @@ -2100,7 +2092,7 @@ RZ_API RzAnalysisDebugInfo *rz_analysis_debug_info_new() { 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->base_types_by_name = ht_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_pvector_free); debug_info->visited = set_u_new(); return debug_info; } diff --git a/librz/arch/esil/esil.c b/librz/arch/esil/esil.c index beaefd6519b..f2608573913 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_pp_new_s2p(HT_STR_DUP, NULL, free); esil->iotrap = iotrap; esil->in_cmd_step = false; rz_analysis_esil_sources_init(esil); diff --git a/librz/arch/esil/esil_interrupt.c b/librz/arch/esil/esil_interrupt.c index c30235135f9..e50bea2dd0f 100644 --- a/librz/arch/esil/esil_interrupt.c +++ b/librz/arch/esil/esil_interrupt.c @@ -5,7 +5,7 @@ #include #include -static void interrupt_free(HtUPKv *kv) { +static void interrupt_free(HtUPKv *kv, RZ_UNUSED void *user) { RzAnalysisEsilInterrupt *i = (RzAnalysisEsilInterrupt *)kv->value; rz_analysis_esil_interrupt_free(i->esil, i); } diff --git a/librz/arch/esil/esil_trace.c b/librz/arch/esil/esil_trace.c index 76e353222c2..62db20e4262 100644 --- a/librz/arch/esil/esil_trace.c +++ b/librz/arch/esil/esil_trace.c @@ -20,7 +20,7 @@ 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) { +static void htup_vector_free(HtUPKv *kv, RZ_UNUSED void *user) { rz_vector_free(kv->value); } diff --git a/librz/arch/fcn.c b/librz/arch/fcn.c index d7a9444f9a8..fa53bb8a9ce 100644 --- a/librz/arch/fcn.c +++ b/librz/arch/fcn.c @@ -2265,7 +2265,7 @@ 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) { +static void free_ht_up(HtUPKv *kv, RZ_UNUSED void *user) { ht_up_free((HtUP *)kv->value); } diff --git a/librz/arch/function.c b/librz/arch/function.c index 3ce5b63098b..fa3061b604c 100644 --- a/librz/arch/function.c +++ b/librz/arch/function.c @@ -80,16 +80,11 @@ static bool function_already_defined_at(RzAnalysis *analysis, const char *name, return false; } -static void inst_vars_kv_free(HtUPKv *kv) { +static void inst_vars_kv_free(HtUPKv *kv, RZ_UNUSED void *user) { 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); +static void labels_kv_free(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); } @@ -110,7 +105,7 @@ RZ_API RzAnalysisFunction *rz_analysis_function_new(RzAnalysis *analysis) { 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->label_addrs = ht_pp_new_s2p(HT_STR_DUP, NULL, free); return fcn; } diff --git a/librz/arch/hint.c b/librz/arch/hint.c index 100489793ff..e5fbad5f645 100644 --- a/librz/arch/hint.c +++ b/librz/arch/hint.c @@ -54,7 +54,7 @@ static void addr_hint_record_fini(void *element, void *user) { } } -static void addr_hint_record_ht_free(HtUPKv *kv) { +static void addr_hint_record_ht_free(HtUPKv *kv, RZ_UNUSED void *user) { rz_vector_free(kv->value); } diff --git a/librz/arch/il/analysis_il_trace.c b/librz/arch/il/analysis_il_trace.c index 3e8993eca5e..98ab37c51e2 100644 --- a/librz/arch/il/analysis_il_trace.c +++ b/librz/arch/il/analysis_il_trace.c @@ -11,7 +11,7 @@ * 4. reg.write name & data **/ -static void htup_vector_free(HtUPKv *kv) { +static void htup_vector_free(HtUPKv *kv, RZ_UNUSED void *user) { rz_vector_free(kv->value); } diff --git a/librz/arch/platform_profile.c b/librz/arch/platform_profile.c index a6f7315524f..c552d4c8205 100644 --- a/librz/arch/platform_profile.c +++ b/librz/arch/platform_profile.c @@ -19,7 +19,7 @@ RZ_API void rz_platform_profile_free(RzPlatformProfile *p) { free(p); } -static void free_mmio_kv(HtUPKv *kv) { +static void free_mmio_kv(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); } diff --git a/librz/arch/rtti_msvc.c b/librz/arch/rtti_msvc.c index cbd2367ffb4..f1baab56b77 100644 --- a/librz/arch/rtti_msvc.c +++ b/librz/arch/rtti_msvc.c @@ -961,7 +961,7 @@ static const char *recovery_apply_type_descriptor(RRTTIMSVCAnalContext *context, return name; } -void str_value_free(HtUPKv *kv) { +void str_value_free(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); } diff --git a/librz/arch/serialize_analysis.c b/librz/arch/serialize_analysis.c index 921aa44d403..aae315746f6 100644 --- a/librz/arch/serialize_analysis.c +++ b/librz/arch/serialize_analysis.c @@ -1759,7 +1759,7 @@ typedef struct { bool bits_set; } HintsAtAddr; -static void hints_at_addr_kv_free(HtUPKv *kv) { +static void hints_at_addr_kv_free(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); } diff --git a/librz/arch/xrefs.c b/librz/arch/xrefs.c index 4f38bd2ac20..68a73afc15d 100644 --- a/librz/arch/xrefs.c +++ b/librz/arch/xrefs.c @@ -38,11 +38,11 @@ RZ_API RZ_OWN RzList /**/ *rz_analysis_xref_list_new() { return rz_list_newf((RzListFree)free); } -static void xrefs_ht_free(HtUPKv *kv) { +static void xrefs_ht_free(HtUPKv *kv, RZ_UNUSED void *user) { ht_up_free(kv->value); } -static void xrefs_ref_free(HtUPKv *kv) { +static void xrefs_ref_free(HtUPKv *kv, RZ_UNUSED void *user) { rz_analysis_xref_free(kv->value); } diff --git a/librz/bin/bobj_process_class.c b/librz/bin/bobj_process_class.c index 85046964fb4..2113b00e5d5 100644 --- a/librz/bin/bobj_process_class.c +++ b/librz/bin/bobj_process_class.c @@ -85,9 +85,9 @@ RZ_IPI void rz_bin_set_and_process_classes(RzBinFile *bf, RzBinObject *o) { ht_pp_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->name_to_class_object = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); + o->glue_to_class_method = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); + o->glue_to_class_field = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); o->vaddr_to_class_method = ht_up_new0(); void **it; diff --git a/librz/bin/bobj_process_section.c b/librz/bin/bobj_process_section.c index 99b2e90ed55..8812b4c4d4a 100644 --- a/librz/bin/bobj_process_section.c +++ b/librz/bin/bobj_process_section.c @@ -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; + HtPP *filter_db = bin->filter ? ht_pp_new_s2p(HT_STR_DUP, NULL, NULL) : NULL; void **it; RzBinSection *element; diff --git a/librz/bin/bobj_process_symbol.c b/librz/bin/bobj_process_symbol.c index 619a16d86f5..9e725ea424b 100644 --- a/librz/bin/bobj_process_symbol.c +++ b/librz/bin/bobj_process_symbol.c @@ -95,7 +95,7 @@ RZ_IPI void rz_bin_process_symbols(RzBinFile *bf, RzBinObject *o, const RzDemang } ht_pp_free(o->import_name_symbols); - o->import_name_symbols = ht_pp_new0(); + o->import_name_symbols = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); RzBinProcessLanguage language_cb = rz_bin_process_language_symbol(o); diff --git a/librz/bin/dwarf/abbrev.c b/librz/bin/dwarf/abbrev.c index e94e4497642..2169725eef2 100644 --- a/librz/bin/dwarf/abbrev.c +++ b/librz/bin/dwarf/abbrev.c @@ -35,7 +35,7 @@ static void RzBinDwarfAbbrevTable_free(RzBinDwarfAbbrevTable *table) { free(table); } -static void htup_RzBinDwarfAbbrevTable_free(HtUPKv *kv) { +static void htup_RzBinDwarfAbbrevTable_free(HtUPKv *kv, RZ_UNUSED void *user) { if (!kv) { return; } 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/format/elf/elf_symbols.c b/librz/bin/format/elf/elf_symbols.c index 493498d6749..463c1576278 100644 --- a/librz/bin/format/elf/elf_symbols.c +++ b/librz/bin/format/elf/elf_symbols.c @@ -401,7 +401,7 @@ static bool get_gnu_debugdata_elf_symbols(ELFOBJ *bin, RzVector /*symbols; } - HtPP *hash = ht_pp_new0(); + HtPP *hash = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); if (!hash) { return NULL; } diff --git a/librz/config/config.c b/librz/config/config.c index 8f6e4382d79..c8953624b60 100644 --- a/librz/config/config.c +++ b/librz/config/config.c @@ -492,7 +492,7 @@ RZ_API RzConfig *rz_config_new(void *user) { if (!cfg) { return NULL; } - cfg->ht = ht_pp_new0(); + cfg->ht = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); cfg->nodes = rz_list_newf((RzListFree)rz_config_node_free); if (!cfg->nodes) { RZ_FREE(cfg); diff --git a/librz/config/serialize_config.c b/librz/config/serialize_config.c index f423f83d749..2f9a2744d00 100644 --- a/librz/config/serialize_config.c +++ b/librz/config/serialize_config.c @@ -49,7 +49,7 @@ 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_pp_new_s2p(HT_STR_DUP, NULL, NULL); if (!ctx.exclude) { return false; } diff --git a/librz/cons/canvas.c b/librz/cons/canvas.c index 49e66b464ea..82b5ead0a78 100644 --- a/librz/cons/canvas.c +++ b/librz/cons/canvas.c @@ -29,7 +29,7 @@ static int __getAnsiPiece(const char *p, char *chr) { return p - q; } -static void attribute_free_kv(HtUPKv *kv) { +static void attribute_free_kv(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); } diff --git a/librz/cons/hud.c b/librz/cons/hud.c index d3f6a7da2c3..6382c5391b2 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); + HtPP *ht = ht_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_list_free); RzLineHud *hud = (RzLineHud *)RZ_NEW(RzLineHud); hud->activate = 0; hud->vi = 0; diff --git a/librz/core/agraph.c b/librz/core/agraph.c index 1b645244803..df417650867 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 free_vertical_nodes_kv(HtPPKv *kv, RZ_UNUSED void *user) { rz_list_free(kv->value); } @@ -3572,7 +3572,7 @@ 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) { +static void free_nodes_kv(HtPPKv *kv, RZ_UNUSED void *user) { RzANode *n = (RzANode *)kv->value; if (!n->is_dummy) { agraph_node_free(n); diff --git a/librz/core/analysis_objc.c b/librz/core/analysis_objc.c index 94505a402e0..6a4968a3a55 100644 --- a/librz/core/analysis_objc.c +++ b/librz/core/analysis_objc.c @@ -45,7 +45,7 @@ static void array_add(RzCoreObjc *o, ut64 va, ut64 xrefs_to) { rz_vector_push(vec, &xrefs_to); } -static void kv_array_free(HtUPKv *kv) { +static void kv_array_free(HtUPKv *kv, RZ_UNUSED void *user) { rz_vector_free(kv->value); } diff --git a/librz/core/analysis_tp.c b/librz/core/analysis_tp.c index 5a17d88c3ce..2f377891792 100644 --- a/librz/core/analysis_tp.c +++ b/librz/core/analysis_tp.c @@ -530,7 +530,7 @@ 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) { +void free_op_cache_kv(HtUPKv *kv, RZ_UNUSED void *user) { rz_analysis_op_free(kv->value); } @@ -842,8 +842,7 @@ RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, H 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; + dtrace->ht = ht_pp_new_opt_size(&opt, fcn->ninstr); // Create a new context to store the return type propagation state struct ReturnTypeAnalysisCtx retctx = { diff --git a/librz/core/cbin.c b/librz/core/cbin.c index 5a97ff580e1..08111de0430 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 * @@ -1683,7 +1678,7 @@ static void digests_ht_free(HtPPKv *kv) { * */ RZ_API RZ_OWN HtPP *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); + HtPP *r = ht_pp_new_s2s(HT_STR_DUP, HT_STR_OWN); if (!r) { return NULL; } diff --git a/librz/core/cmd/cmd_api.c b/librz/core/cmd/cmd_api.c index 1f07cb105f5..4debf6a2c6e 100644 --- a/librz/core/cmd/cmd_api.c +++ b/librz/core/cmd/cmd_api.c @@ -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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)macro_free); + cmd->ht_cmds = ht_pp_new_s2p(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; diff --git a/librz/core/cmd/cmd_info.c b/librz/core/cmd/cmd_info.c index e53fb280a14..7e1ebb2ab11 100644 --- a/librz/core/cmd/cmd_info.c +++ b/librz/core/cmd/cmd_info.c @@ -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(); + HtPP *files = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); if (!files) { return false; } diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 4064cffd1e0..fdd514f7659 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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)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; diff --git a/librz/core/tui/panels.c b/librz/core/tui/panels.c index 22362ba6d3a..11de3e5c527 100644 --- a/librz/core/tui/panels.c +++ b/librz/core/tui/panels.c @@ -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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)__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..1b61ebc2cc6 100644 --- a/librz/debug/debug.c +++ b/librz/debug/debug.c @@ -366,7 +366,7 @@ static const char *rz_debug_str_callback(RzNum *userptr, ut64 off, int *ok) { return NULL; } -void free_tracenodes_kv(HtUPKv *kv) { +void free_tracenodes_kv(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); } diff --git a/librz/debug/dsession.c b/librz/debug/dsession.c index 8bf2f707467..53b5c2cbde9 100644 --- a/librz/debug/dsession.c +++ b/librz/debug/dsession.c @@ -26,7 +26,7 @@ static void rz_debug_checkpoint_fini(void *element, void *user) { rz_list_free(checkpoint->snaps); } -static void htup_vector_free(HtUPKv *kv) { +static void htup_vector_free(HtUPKv *kv, RZ_UNUSED void *user) { rz_vector_free(kv->value); } diff --git a/librz/debug/trace.c b/librz/debug/trace.c index 0836eb1871d..b32cf4aef13 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_pp_new_s2p(HT_STR_DUP, NULL, NULL); if (!t->ht) { rz_debug_trace_free(t); return NULL; @@ -301,7 +301,7 @@ 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(); + t->ht = ht_pp_new_s2p(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..c0f3263adac 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 free_hits(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, + .freefn = free_hits, + .freefn_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); diff --git a/librz/flag/flag.c b/librz/flag/flag.c index 35ee385c090..fcffa13575d 100644 --- a/librz/flag/flag.c +++ b/librz/flag/flag.c @@ -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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_flag_item_free); f->by_off = rz_skiplist_new(flag_skiplist_free, flag_skiplist_cmp); rz_list_free(f->zones); new_spaces(f); @@ -791,7 +786,7 @@ RZ_API bool rz_flag_unset_name(RzFlag *f, const char *name) { 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); + f->ht_name = ht_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)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..cb3713208b7 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,11 +50,11 @@ 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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_il_variable_free); if (!vs->vars) { return false; } - vs->contents = ht_pp_new(NULL, val_ht_free, NULL); + vs->contents = ht_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_il_value_free); if (!vs->contents) { ht_pp_free(vs->vars); vs->vars = NULL; diff --git a/librz/il/il_validate.c b/librz/il/il_validate.c index f191a0dabfa..beef5fd5f93 100644 --- a/librz/il/il_validate.c +++ b/librz/il/il_validate.c @@ -16,15 +16,6 @@ struct rz_il_validate_global_context_t { 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,7 +27,7 @@ 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_pp_new_s2p(HT_STR_DUP, NULL, free); if (!ctx->global_vars) { free(ctx); return NULL; @@ -121,11 +112,11 @@ typedef struct { 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_pp_new_s2p(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_pp_new_s2p(HT_STR_DUP, NULL, NULL); if (!ctx->local_vars_available) { ht_pp_free(ctx->local_vars_known); ctx->local_vars_known = NULL; diff --git a/librz/include/rz_util/ht_inc.h b/librz/include/rz_util/ht_inc.h index 53d5f4aff01..a877b66815b 100644 --- a/librz/include/rz_util/ht_inc.h +++ b/librz/include/rz_util/ht_inc.h @@ -39,7 +39,7 @@ #define VALUE_TYPE ut64 #define KEY_TO_HASH(x) ((ut32)(x)) #define HT_NULL_VALUE 0 -#else +#elif HT_TYPE == 4 #define HtName_(name) name##PU #define Ht_(name) ht_pu_##name #define HT_(name) HtPU##name @@ -49,6 +49,15 @@ #define HT_NULL_VALUE 0 #endif +#ifndef HT_STR_PROP_DEF +#define HT_STR_PROP_DEF +typedef enum { + HT_STR_DUP = 0, + HT_STR_OWN, + HT_STR_CONST +} HtStrOption; +#endif + #include "ls.h" #include @@ -61,9 +70,10 @@ typedef struct Ht_(kv) { } HT_(Kv); -typedef void (*HT_(KvFreeFunc))(HT_(Kv) *); +typedef void (*HT_(KvFreeFunc))(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); @@ -92,6 +102,7 @@ typedef struct Ht_(options_t) { calcsizeV; // Function to determine the value's size HT_(KvFreeFunc) freefn; // Function to free the keyvalue store + void *freefn_user; // User data which is passed into freefn size_t elem_size; // Size of each HtKv element (useful for subclassing like SdbKv) } HT_(Options); @@ -109,6 +120,8 @@ HtName_(Ht); // Create a new Ht with the provided Options RZ_API HtName_(Ht) * Ht_(new_opt)(HT_(Options) * opt); +// Create a new Ht with the provided Options and initial size +RZ_API HtName_(Ht) * Ht_(new_opt_size)(HT_(Options) * opt, ut32 initial_size); // Destroy a hashtable and all of its entries. RZ_API void Ht_(free)(HtName_(Ht) * ht); // Insert a new Key-Value pair into the hashtable. If the key already exists, returns false. diff --git a/librz/include/rz_util/ht_pp.h b/librz/include/rz_util/ht_pp.h index baf566884f0..ccb9ad361b3 100644 --- a/librz/include/rz_util/ht_pp.h +++ b/librz/include/rz_util/ht_pp.h @@ -17,9 +17,9 @@ extern "C" { #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); +RZ_DEPRECATE RZ_API HtName_(Ht) * Ht_(new0)(void); +RZ_API RZ_OWN HtName_(Ht) * Ht_(new_s2s)(HtStrOption key_opt, HtStrOption val_opt); +RZ_API RZ_OWN HtName_(Ht) * Ht_(new_s2p)(HtStrOption key_opt, HT_(DupValue) dupval, HT_(FreeValue) free_val); #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..bce87bd8184 100644 --- a/librz/include/rz_util/rz_serialize.h +++ b/librz/include/rz_util/rz_serialize.h @@ -46,7 +46,7 @@ static inline void rz_serialize_result_info_free(RzSerializeResultInfo *info) { typedef HtPP RzKeyParser; static inline RzKeyParser *rz_key_parser_new(void) { - return ht_pp_new0(); + return ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); } static inline void rz_key_parser_free(RzKeyParser *parser) { diff --git a/librz/io/p_cache.c b/librz/io/p_cache.c index b6439647c5f..925dfa2ecda 100644 --- a/librz/io/p_cache.c +++ b/librz/io/p_cache.c @@ -72,7 +72,7 @@ const ut64 cleanup_masks[] = { 0x7fffffffffffffff }; -static void pcache_kv_free(HtUPKv *kv) { +static void pcache_kv_free(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); } diff --git a/librz/main/rz-asm.c b/librz/main/rz-asm.c index e81e639a624..e7b8b059805 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_pp_foreach(as->a->flags, (HtPPForeachCallback)print_label, NULL); } return ret; } diff --git a/librz/reg/profile.c b/librz/reg/profile.c index 71c622b79e1..02f683c4168 100644 --- a/librz/reg/profile.c +++ b/librz/reg/profile.c @@ -353,7 +353,7 @@ 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_pp_new_s2p(HT_STR_DUP, NULL, NULL); } // Dynamically update the list of supported bit sizes diff --git a/librz/sign/sigdb.c b/librz/sign/sigdb.c index 518f48c13ca..e47c720c7da 100644 --- a/librz/sign/sigdb.c +++ b/librz/sign/sigdb.c @@ -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_freekv(HtPUKv *kv, RZ_UNUSED void *user) { if (!kv) { return; } diff --git a/librz/syscall/syscall.c b/librz/syscall/syscall.c index e689278a32b..fb4035285d6 100644 --- a/librz/syscall/syscall.c +++ b/librz/syscall/syscall.c @@ -30,7 +30,7 @@ RZ_API RZ_OWN RzSysregItem *rz_sysreg_item_new(RZ_NULLABLE const char *name) { return sysregitem; } -static void free_port_kv(HtUPKv *kv) { +static void free_port_kv(HtUPKv *kv, RZ_UNUSED void *user) { rz_sysreg_item_free(kv->value); } diff --git a/librz/type/function.c b/librz/type/function.c index e4b1701944a..8a26b037bfc 100644 --- a/librz/type/function.c +++ b/librz/type/function.c @@ -197,16 +197,12 @@ RZ_API bool rz_type_func_delete(RzTypeDB *typedb, RZ_NONNULL const char *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); + typedb->callables = ht_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_type_callable_free); } /** diff --git a/librz/type/parser/c_cpp_parser.c b/librz/type/parser/c_cpp_parser.c index d3d0e9e5cac..a44e41fc667 100644 --- a/librz/type/parser/c_cpp_parser.c +++ b/librz/type/parser/c_cpp_parser.c @@ -33,17 +33,17 @@ TSLanguage *tree_sitter_c(); CParserState *c_parser_state_new(HtPP *base_types, HtPP *callable_types) { CParserState *state = RZ_NEW0(CParserState); if (!base_types) { - state->types = ht_pp_new0(); + state->types = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); } else { state->types = base_types; } if (!callable_types) { - state->callables = ht_pp_new0(); + state->callables = ht_pp_new_s2p(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_pp_new_s2p(HT_STR_DUP, NULL, NULL); // Initializing error/warning/debug messages buffers state->errors = rz_strbuf_new(""); state->warnings = rz_strbuf_new(""); diff --git a/librz/type/serialize_functions.c b/librz/type/serialize_functions.c index 511afabc387..fd3582fbf57 100644 --- a/librz/type/serialize_functions.c +++ b/librz/type/serialize_functions.c @@ -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 + HtPP *type_str_cache = ht_pp_new_s2p(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; } diff --git a/librz/type/type.c b/librz/type/type.c index 51496c6e35c..a41b4be1915 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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)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_pp_new_s2s(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_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_type_callable_free); if (!typedb->callables) { goto rz_type_db_new_fail; } @@ -99,9 +80,9 @@ RZ_API void rz_type_db_free(RzTypeDB *typedb) { */ RZ_API void rz_type_db_purge(RzTypeDB *typedb) { ht_pp_free(typedb->callables); - typedb->callables = ht_pp_new(NULL, callables_ht_free, NULL); + typedb->callables = ht_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_type_callable_free); ht_pp_free(typedb->types); - typedb->types = ht_pp_new(NULL, types_ht_free, NULL); + typedb->types = ht_pp_new_s2p(HT_STR_DUP, NULL, (HtPPFreeValue)rz_type_base_type_free); rz_type_parser_free(typedb->parser); typedb->parser = rz_type_parser_init(typedb->types, typedb->callables); } @@ -111,7 +92,7 @@ RZ_API void rz_type_db_purge(RzTypeDB *typedb) { */ 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); + typedb->formats = ht_pp_new_s2s(HT_STR_DUP, HT_STR_OWN); } static void set_default_type(RzTypeTarget *target, int bits) { @@ -1127,7 +1108,7 @@ 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 + HtPP *used_types = ht_pp_new_s2p(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; @@ -1304,10 +1285,11 @@ 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; + HtPPKv *kv = ht_pp_find_kv(typedb->types, t->name, NULL); + if (!kv || kv->value != t) { + return false; + } + kv->value = NULL; char *error_msg = NULL; int result = rz_type_parse_string_stateless(typedb->parser, typestr, &error_msg); if (result) { diff --git a/librz/util/event.c b/librz/util/event.c index 2308033dfa4..b071d65be59 100644 --- a/librz/util/event.c +++ b/librz/util/event.c @@ -10,7 +10,7 @@ typedef struct rz_event_callback_hook_t { int handle; } RzEventCallbackHook; -static void ht_callback_free(HtUPKv *kv) { +static void ht_callback_free(HtUPKv *kv, RZ_UNUSED void *user) { rz_vector_free((RzVector *)kv->value); } diff --git a/librz/util/ht/ht_inc.c b/librz/util/ht/ht_inc.c index f6f6da95454..fff16680f4e 100644 --- a/librz/util/ht/ht_inc.c +++ b/librz/util/ht/ht_inc.c @@ -45,7 +45,7 @@ static inline ut32 calcsize_val(HtName_(Ht) * ht, const VALUE_TYPE v) { static inline void freefn(HtName_(Ht) * ht, HT_(Kv) * kv) { if (ht->opt.freefn) { - ht->opt.freefn(kv); + ht->opt.freefn(kv, ht->opt.freefn_user); } } @@ -127,6 +127,19 @@ RZ_API HtName_(Ht) * Ht_(new_opt)(HT_(Options) * opt) { return internal_ht_new(ht_primes_sizes[0], 0, opt); } +RZ_API RZ_OWN HtName_(Ht) * Ht_(new_opt_size)(HT_(Options) * opt, ut32 initial_size) { + 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)(HtName_(Ht) * ht) { if (!ht) { return; @@ -140,7 +153,7 @@ RZ_API void Ht_(free)(HtName_(Ht) * ht) { if (ht->opt.freefn) { BUCKET_FOREACH(ht, bt, j, kv) { - ht->opt.freefn(kv); + ht->opt.freefn(kv, ht->opt.freefn_user); } } diff --git a/librz/util/ht/ht_pp.c b/librz/util/ht/ht_pp.c index 9525aeeaa0d..2497980b8a4 100644 --- a/librz/util/ht/ht_pp.c +++ b/librz/util/ht/ht_pp.c @@ -7,46 +7,52 @@ #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); +// 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_s2p)(HT_STR_DUP, NULL, NULL); } -static void free_kv_key(HT_(Kv) * kv) { +static void s2p_free_kv(HT_(Kv) *kv, void *user) { + HT_(FreeValue) func = (HT_(FreeValue))user; free(kv->key); + if (func) { + func(kv->value); + } } -// 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); +static void s2p_free_kv_val(HT_(Kv) *kv, void *user) { + HT_(FreeValue) func = (HT_(FreeValue))user; + if (func) { + func(kv->value); + } } -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; - } +RZ_API RZ_OWN HtName_(Ht) * Ht_(new_s2p)(HtStrOption key_opt, HT_(DupValue) dupval, HT_(FreeValue) free_val) { + HT_(Options) opts = { + .cmp = (HT_(ListComparator))strcmp, + .hashfn = (HT_(HashFunction))sdb_hash, + .dupkey = key_opt == HT_STR_DUP ? (HT_(DupKey))strdup : NULL, + .dupvalue = dupval, + .calcsizeK = (HT_(CalcSizeK))strlen, + .calcsizeV = NULL, + .freefn = key_opt == HT_STR_CONST ? s2p_free_kv_val : s2p_free_kv, + .freefn_user = (void *)free_val, + .elem_size = 0, + }; + return internal_ht_new(ht_primes_sizes[0], 0, &opts); +} - ut32 sz = compute_size(i, (ut32)(initial_size * (2 - LOAD_FACTOR))); - return internal_ht_default_new(sz, i, valdup, pair_free, calcsizeV); +RZ_API RZ_OWN HtName_(Ht) * Ht_(new_s2s)(HtStrOption key_opt, HtStrOption val_opt) { + HT_(Options) opts = { + .cmp = (HT_(ListComparator))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, + .freefn = key_opt == HT_STR_CONST ? s2p_free_kv_val : s2p_free_kv, + .freefn_user = val_opt == HT_STR_CONST ? NULL : (HT_(FreeValue))free, + .elem_size = 0, + }; + return internal_ht_new(ht_primes_sizes[0], 0, &opts); } diff --git a/librz/util/ht/ht_pu.c b/librz/util/ht/ht_pu.c index 9e42e849b1d..7d4a5f67926 100644 --- a/librz/util/ht/ht_pu.c +++ b/librz/util/ht/ht_pu.c @@ -7,7 +7,7 @@ #include #include "ht_inc.c" -static void free_kv_key(HT_(Kv) * kv) { +static void free_kv_key(HT_(Kv) * kv, RZ_UNUSED void *user) { free(kv->key); } diff --git a/librz/util/ht/ht_uu.c b/librz/util/ht/ht_uu.c index 8b42d6593cc..aa398cc3509 100644 --- a/librz/util/ht/ht_uu.c +++ b/librz/util/ht/ht_uu.c @@ -8,15 +8,6 @@ #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 - }; + HT_(Options) opt = { 0 }; return Ht_(new_opt)(&opt); } diff --git a/librz/util/sdb/src/sdbht.c b/librz/util/sdb/src/sdbht.c index d187173ec40..076abda70b3 100644 --- a/librz/util/sdb/src/sdbht.c +++ b/librz/util/sdb/src/sdbht.c @@ -3,13 +3,8 @@ #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); + HtPP *ht = ht_pp_new_s2s(HT_STR_DUP, HT_STR_DUP); if (ht) { ht->opt.elem_size = sizeof(SdbKv); } diff --git a/librz/util/set.c b/librz/util/set.c index 991cf45cee0..fce4baf78c1 100644 --- a/librz/util/set.c +++ b/librz/util/set.c @@ -6,7 +6,7 @@ // p RZ_API SetP *set_p_new(void) { - return ht_pp_new0(); + return ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); } RZ_API void set_p_add(SetP *s, const void *u) { diff --git a/librz/util/str_constpool.c b/librz/util/str_constpool.c index d60ec306a08..47732da1a78 100644 --- a/librz/util/str_constpool.c +++ b/librz/util/str_constpool.c @@ -3,12 +3,8 @@ #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_pp_new_s2p(HT_STR_DUP, NULL, NULL); return pool->ht != NULL; } diff --git a/test/unit/test_sdb_hash.c b/test/unit/test_sdb_hash.c index 79d80b90d49..07fa9575b89 100644 --- a/test/unit/test_sdb_hash.c +++ b/test/unit/test_sdb_hash.c @@ -155,9 +155,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,7 +184,7 @@ bool test_ht_general(void) { person2->name = strdup("pancake"); person2->age = 9000; - HtPP *ht = ht_pp_new((HtPPDupValue)duplicate_person, free_kv, (HtPPCalcSizeV)calcSizePerson); + HtPP *ht = ht_pp_new_s2p(HT_STR_DUP, (HtPPDupValue)duplicate_person, (HtPPFreeValue)free_person); if (!ht) { mu_cleanup_fail(err_free_persons, "ht alloc"); } @@ -217,27 +218,20 @@ bool test_ht_general(void) { ht_pp_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) { mu_fail("this function should not be called"); return false; } bool test_empty_ht(void) { - HtPP *ht = ht_pp_new0(); + HtPP *ht = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); ht_pp_foreach(ht, (HtPPForeachCallback)should_not_be_caled, NULL); void *r = ht_pp_find(ht, "key1", NULL); mu_assert_null(r, "key1 should not be present"); @@ -246,7 +240,7 @@ bool test_empty_ht(void) { } bool test_insert(void) { - HtPP *ht = ht_pp_new0(); + HtPP *ht = ht_pp_new_s2p(HT_STR_CONST, NULL, NULL); void *r; bool res; bool found; @@ -272,7 +266,7 @@ bool test_insert(void) { } bool test_update(void) { - HtPP *ht = ht_pp_new0(); + HtPP *ht = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); bool found; ht_pp_insert(ht, "key1", "value1"); @@ -285,7 +279,7 @@ bool test_update(void) { } bool test_delete(void) { - HtPP *ht = ht_pp_new0(); + HtPP *ht = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); bool found; ht_pp_insert(ht, "key1", "value1"); @@ -304,7 +298,7 @@ static bool grow_1_foreach(void *user, const char *k, int v) { } bool test_grow_1(void) { - HtPP *ht = ht_pp_new0(); + HtPP *ht = ht_pp_new_s2p(HT_STR_DUP, NULL, NULL); int i; for (i = 0; i < 3; ++i) { @@ -328,7 +322,7 @@ bool test_grow_1(void) { } bool test_grow_2(void) { - HtPP *ht = ht_pp_new((HtPPDupValue)strdup, (HtPPKvFreeFunc)free_key_value, NULL); + HtPP *ht = ht_pp_new_s2s(HT_STR_DUP, HT_STR_DUP); char *r; bool found; int i; @@ -357,7 +351,7 @@ bool test_grow_2(void) { } bool test_grow_3(void) { - HtPP *ht = ht_pp_new((HtPPDupValue)strdup, (HtPPKvFreeFunc)free_key_value, NULL); + HtPP *ht = ht_pp_new_s2s(HT_STR_DUP, HT_STR_DUP); char *r; bool found; int i; @@ -406,7 +400,7 @@ bool test_grow_3(void) { } bool test_grow_4(void) { - HtPP *ht = ht_pp_new(NULL, (HtPPKvFreeFunc)free_key_value, NULL); + HtPP *ht = ht_pp_new_s2s(HT_STR_DUP, HT_STR_OWN); char *r; bool found; int i; @@ -462,7 +456,7 @@ bool foreach_delete_cb(void *user, const ut64 key, const void *v) { return true; } -static void free_up_value(HtUPKv *kv) { +static void free_up_value(HtUPKv *kv, RZ_UNUSED void *user) { free(kv->value); }