diff --git a/librz/asm/asm.c b/librz/asm/asm.c index 9f5c1db9fd7..ea920817d1e 100644 --- a/librz/asm/asm.c +++ b/librz/asm/asm.c @@ -1439,7 +1439,7 @@ static bool overlaps_with_token(RZ_BORROW RzVector /**/ *toks, * \return 1 If a.start > b.start * \return 0 If a.start == b.start */ -static int cmp_tokens(const RzAsmToken *a, const RzAsmToken *b) { +static int cmp_tokens(const RzAsmToken *a, const RzAsmToken *b, void *user) { rz_return_val_if_fail(a && b, 0); if (a->start < b->start) { return -1; @@ -1591,7 +1591,7 @@ RZ_API RZ_OWN RzAsmTokenString *rz_asm_tokenize_asm_regex(RZ_BORROW RzStrBuf *as } } - rz_vector_sort(toks->tokens, (RzVectorComparator)cmp_tokens, false); + rz_vector_sort(toks->tokens, (RzVectorComparator)cmp_tokens, false, NULL); check_token_coverage(toks); return toks; diff --git a/librz/bin/bfile_string.c b/librz/bin/bfile_string.c index 932a764ccd4..e1b27cf99dd 100644 --- a/librz/bin/bfile_string.c +++ b/librz/bin/bfile_string.c @@ -234,7 +234,7 @@ static bool create_string_search_thread(RzThreadPool *pool, size_t min_length, R return true; } -static int string_compare_sort(const RzBinString *a, const RzBinString *b) { +static int string_compare_sort(const RzBinString *a, const RzBinString *b, void *user) { if (b->paddr > a->paddr) { return -1; } else if (b->paddr < a->paddr) { @@ -493,7 +493,7 @@ RZ_API RZ_OWN RzPVector /**/ *rz_bin_file_strings(RZ_NONNULL RzBi if (!raw_strings) { scan_cfstring_table(bf, strings_db, results, max_interval); } - rz_pvector_sort(results, (RzPVectorComparator)string_compare_sort); + rz_pvector_sort(results, (RzPVectorComparator)string_compare_sort, NULL); { void **it; diff --git a/librz/bin/bobj.c b/librz/bin/bobj.c index 91c6ce2204d..479f85e4a9f 100644 --- a/librz/bin/bobj.c +++ b/librz/bin/bobj.c @@ -73,7 +73,7 @@ RZ_API ut64 rz_bin_reloc_size(RzBinReloc *reloc) { } \ } while (0); -static int reloc_cmp(const void *a, const void *b) { +static int reloc_cmp(const void *a, const void *b, void *user) { const RzBinReloc *ar = a; const RzBinReloc *br = b; CMP_CHECK(vaddr); @@ -83,7 +83,7 @@ static int reloc_cmp(const void *a, const void *b) { return 0; } -static int reloc_target_cmp(const void *a, const void *b) { +static int reloc_target_cmp(const void *a, const void *b, void *user) { const RzBinReloc *ar = a; const RzBinReloc *br = b; CMP_CHECK(target_vaddr); @@ -117,11 +117,11 @@ RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*v.free = NULL; // ownership of relocs transferred rz_pvector_free(relocs); - rz_pvector_sort(&sorter, reloc_cmp); + rz_pvector_sort(&sorter, reloc_cmp, NULL); ret->relocs_count = rz_pvector_len(&sorter); ret->relocs = (RzBinReloc **)rz_pvector_flush(&sorter); rz_pvector_fini(&sorter); - rz_pvector_sort(&target_sorter, reloc_target_cmp); + rz_pvector_sort(&target_sorter, reloc_target_cmp, NULL); ret->target_relocs_count = rz_pvector_len(&target_sorter); ret->target_relocs = (RzBinReloc **)rz_pvector_flush(&target_sorter); rz_pvector_fini(&target_sorter); @@ -273,6 +273,10 @@ RZ_IPI int rz_bin_compare_class_field(RzBinClassField *a, RzBinClassField *b) { return 0; } +static int bin_compare_class(RzBinClass *a, RzBinClass *b, void *user) { + return rz_bin_compare_class(a, b); +} + /** * \brief Tries to add a new class unless its name is found and returns it. * @@ -303,7 +307,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)rz_bin_compare_class); + rz_pvector_sort(o->classes, (RzPVectorComparator)bin_compare_class, NULL); ht_pp_insert(o->name_to_class_object, name, oclass); return oclass; } diff --git a/librz/bin/dbginfo.c b/librz/bin/dbginfo.c index 41591e5867a..fb4080f67ab 100644 --- a/librz/bin/dbginfo.c +++ b/librz/bin/dbginfo.c @@ -36,7 +36,7 @@ RZ_API void rz_bin_source_line_info_builder_push_sample(RzBinSourceLineInfoBuild sample->file = file ? rz_str_constpool_get(&builder->filename_pool, file) : NULL; } -static int line_sample_cmp(const void *a, const void *b) { +static int line_sample_cmp(const void *a, const void *b, void *user) { const RzBinSourceLineSample *sa = a; const RzBinSourceLineSample *sb = b; // first, sort by addr @@ -106,7 +106,7 @@ RZ_API RzBinSourceLineInfo *rz_bin_source_line_info_builder_build_and_fini(RzBin for (size_t i = 0; i < initial_samples_count; i++) { rz_pvector_push(&sorter, &initial_samples[i]); } - rz_pvector_sort(&sorter, line_sample_cmp); + rz_pvector_sort(&sorter, line_sample_cmp, NULL); r->samples_count = 0; for (size_t i = 0; i < initial_samples_count; i++) { diff --git a/librz/bin/format/dex/dex.c b/librz/bin/format/dex/dex.c index 47dc5401396..3906f31910b 100644 --- a/librz/bin/format/dex/dex.c +++ b/librz/bin/format/dex/dex.c @@ -1508,7 +1508,7 @@ RZ_API RZ_OWN RzPVector /**/ *rz_bin_dex_imports(RZ_NONNULL RzBin return imports; } -static int compare_strings(const void *a, const void *b) { +static int compare_strings(const void *a, const void *b, void *user) { return strcmp((const char *)a, (const char *)b); } @@ -1574,7 +1574,7 @@ RZ_API RZ_OWN RzPVector /**/ *rz_bin_dex_libraries(RZ_NONNULL RzBinDex * object = p; } - if (rz_pvector_find(libraries, object, compare_strings)) { + if (rz_pvector_find(libraries, object, compare_strings, NULL)) { free(object); continue; } diff --git a/librz/bin/format/java/class_bin.c b/librz/bin/format/java/class_bin.c index f30e3ec256d..d9b2440aab6 100644 --- a/librz/bin/format/java/class_bin.c +++ b/librz/bin/format/java/class_bin.c @@ -1884,7 +1884,7 @@ RZ_API RZ_OWN RzList /**/ *rz_bin_java_class_as_sections(RZ_NONN return sections; } -static int compare_strings(const void *a, const void *b) { +static int compare_strings(const void *a, const void *b, void *user) { return strcmp((const char *)a, (const char *)b); } @@ -1930,7 +1930,7 @@ RZ_API RZ_OWN RzPVector /**/ *rz_bin_java_class_as_libraries(RZ_NONNULL // arg0 is name_index tmp = java_class_constant_pool_stringify_at(bin, arg0); } - if (tmp && !rz_pvector_find(vec, tmp, compare_strings)) { + if (tmp && !rz_pvector_find(vec, tmp, compare_strings, NULL)) { rz_pvector_push(vec, tmp); } else { free(tmp); diff --git a/librz/bin/format/ne/ne.c b/librz/bin/format/ne/ne.c index db800851c2d..5d6714dfc65 100644 --- a/librz/bin/format/ne/ne.c +++ b/librz/bin/format/ne/ne.c @@ -105,7 +105,7 @@ RzList /**/ *rz_bin_ne_get_segments(rz_bin_ne_obj_t *bin) { return segments; } -static int __find_symbol_by_paddr(const void *paddr, const void *sym) { +static int __find_symbol_by_paddr(const void *paddr, const void *sym, void *user) { return (int)!(*(ut64 *)paddr == ((RzBinSymbol *)sym)->paddr); } @@ -184,7 +184,7 @@ RzPVector /**/ *rz_bin_ne_get_symbols(rz_bin_ne_obj_t *bin) { RzBinAddr *en; int i = 1; rz_list_foreach (entries, it, en) { - if (!rz_pvector_find(symbols, &en->paddr, __find_symbol_by_paddr)) { + if (!rz_pvector_find(symbols, &en->paddr, __find_symbol_by_paddr, NULL)) { sym = RZ_NEW0(RzBinSymbol); if (!sym) { break; diff --git a/librz/cons/pal.c b/librz/cons/pal.c index 01795eba38a..956a9e2cfa8 100644 --- a/librz/cons/pal.c +++ b/librz/cons/pal.c @@ -126,6 +126,10 @@ static inline ut8 rgbnum(const char ch1, const char ch2) { return r << 4 | r2; } +static int compare_strings(const char *s1, const char *s2, void *user) { + return strcmp(s1, s2); +} + static void __cons_pal_update_event(RzConsContext *ctx) { RzPVector sorter; rz_pvector_init(&sorter, NULL); @@ -139,7 +143,7 @@ static void __cons_pal_update_event(RzConsContext *ctx) { char *rgb = rz_str_newf("rgb:%02x%02x%02x", rcolor->r, rcolor->g, rcolor->b); rz_pvector_push(&sorter, rgb); } - rz_pvector_sort(&sorter, (RzPVectorComparator)strcmp); + rz_pvector_sort(&sorter, (RzPVectorComparator)compare_strings, NULL); rz_cons_rainbow_free(ctx); rz_cons_rainbow_new(ctx, rz_pvector_len(&sorter)); int n = 0; diff --git a/librz/core/cmd/cmd_analysis.c b/librz/core/cmd/cmd_analysis.c index 3356bf404cf..2bf918c952a 100644 --- a/librz/core/cmd/cmd_analysis.c +++ b/librz/core/cmd/cmd_analysis.c @@ -2776,7 +2776,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_display_handler(RzCore *core, int a return RZ_CMD_STATUS_OK; } -static int delta_cmp(const void *a, const void *b) { +static int delta_cmp(const void *a, const void *b, void *user) { const RzAnalysisVar *va = a; const RzAnalysisVar *vb = b; if (va->storage.type != vb->storage.type) { @@ -2797,7 +2797,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_vars_stackframe_handler(RzCore *core, in if (!vars) { return RZ_CMD_STATUS_ERROR; } - rz_pvector_sort(vars, delta_cmp); + rz_pvector_sort(vars, delta_cmp, NULL); void **it; rz_pvector_foreach (vars, it) { RzAnalysisVar *p = *it; diff --git a/librz/core/cmd/cmd_api.c b/librz/core/cmd/cmd_api.c index 796b875cc53..f29de025f74 100644 --- a/librz/core/cmd/cmd_api.c +++ b/librz/core/cmd/cmd_api.c @@ -94,7 +94,7 @@ RZ_LIB_VERSION(rz_cmd); static void fill_details(RzCmd *cmd, RzCmdDesc *cd, RzStrBuf *sb, bool use_color); -static int cd_sort(const void *a, const void *b) { +static int cd_sort(const void *a, const void *b, void *user) { RzCmdDesc *ca = (RzCmdDesc *)a; RzCmdDesc *cb = (RzCmdDesc *)b; return rz_str_casecmp(ca->name, cb->name); @@ -120,7 +120,7 @@ static bool cmd_desc_set_parent(RzCmd *cmd, RzCmdDesc *cd, RzCmdDesc *parent) { cd->parent = parent; rz_pvector_push(&parent->children, cd); if (!cmd->batch && parent->help->sort_subcommands) { - rz_pvector_sort(&parent->children, cd_sort); + rz_pvector_sort(&parent->children, cd_sort, NULL); } parent->n_children++; } @@ -271,7 +271,7 @@ static void sort_groups(RzCmdDesc *group) { void **it_cd; if (group->help->sort_subcommands) { - rz_pvector_sort(&group->children, cd_sort); + rz_pvector_sort(&group->children, cd_sort, NULL); } rz_cmd_desc_children_foreach(group, it_cd) { RzCmdDesc *cd = *(RzCmdDesc **)it_cd; diff --git a/librz/core/cmd/cmd_info.c b/librz/core/cmd/cmd_info.c index 1bd912ddad0..429ceba4ea2 100644 --- a/librz/core/cmd/cmd_info.c +++ b/librz/core/cmd/cmd_info.c @@ -65,6 +65,10 @@ typedef enum { PRINT_SOURCE_INFO_FILES } PrintSourceInfoType; +static int compare_string(const char *s1, const char *s2, void *user) { + return strcmp(s1, s2); +} + static bool print_source_info(RzCore *core, PrintSourceInfoType type, RzCmdStateOutput *state) { RzBinFile *binfile = core->bin->cur; if (!binfile || !binfile->o) { @@ -94,7 +98,7 @@ static bool print_source_info(RzCore *core, PrintSourceInfoType type, RzCmdState RzPVector sorter; rz_pvector_init(&sorter, free); ht_pp_foreach(files, source_file_collect_cb, &sorter); - rz_pvector_sort(&sorter, (RzPVectorComparator)strcmp); + rz_pvector_sort(&sorter, (RzPVectorComparator)compare_string, NULL); ht_pp_free(files); // print them! if (state->mode == RZ_OUTPUT_MODE_JSON) { diff --git a/librz/include/rz_vector.h b/librz/include/rz_vector.h index 26c88c1c5dd..f6abce1e34a 100644 --- a/librz/include/rz_vector.h +++ b/librz/include/rz_vector.h @@ -38,8 +38,8 @@ extern "C" { */ // RzPVectorComparator should return negative, 0, positive to indicate "value < vec_data", "value == vec_data", "value > vec_data". -typedef int (*RzPVectorComparator)(const void *value, const void *vec_data); -typedef int (*RzVectorComparator)(const void *a, const void *b); +typedef int (*RzPVectorComparator)(const void *value, const void *vec_data, void *user); +typedef int (*RzVectorComparator)(const void *a, const void *b, void *user); typedef void (*RzVectorFree)(void *e, void *user); typedef void (*RzPVectorFree)(void *e); @@ -176,7 +176,7 @@ RZ_API void *rz_vector_shrink(RzVector *vec); RZ_API void *rz_vector_flush(RzVector *vec); // sort vector -RZ_API void rz_vector_sort(RzVector *vec, RzVectorComparator cmp, bool reverse); +RZ_API void rz_vector_sort(RzVector *vec, RzVectorComparator cmp, bool reverse, void *user); /* * example: @@ -310,7 +310,7 @@ static inline void *rz_pvector_tail(RzPVector *vec) { RZ_API void **rz_pvector_contains(RzPVector *vec, const void *x); // find the element in the vec based on cmparator -RZ_API RZ_BORROW void **rz_pvector_find(RZ_NONNULL const RzPVector *vec, RZ_NONNULL const void *element, RZ_NONNULL RzPVectorComparator cmp); +RZ_API RZ_BORROW void **rz_pvector_find(RZ_NONNULL const RzPVector *vec, RZ_NONNULL const void *element, RZ_NONNULL RzPVectorComparator cmp, void *user); // removes and returns the pointer at the given index. Does not call free. RZ_API void *rz_pvector_remove_at(RzPVector *vec, size_t index); @@ -345,7 +345,7 @@ static inline void **rz_pvector_push_front(RzPVector *vec, void *x) { } // sort vec using quick sort. -RZ_API void rz_pvector_sort(RzPVector *vec, RzPVectorComparator cmp); +RZ_API void rz_pvector_sort(RzPVector *vec, RzPVectorComparator cmp, void *user); static inline void **rz_pvector_reserve(RzPVector *vec, size_t capacity) { return (void **)rz_vector_reserve(&vec->v, capacity); diff --git a/librz/main/rz-diff.c b/librz/main/rz-diff.c index d7d7a713611..121fe9171bf 100644 --- a/librz/main/rz-diff.c +++ b/librz/main/rz-diff.c @@ -742,6 +742,10 @@ static int import_compare(const RzBinImport *a, const RzBinImport *b) { return 0; } +static int import_compare_vec(const RzBinImport *a, const RzBinImport *b, void *user) { + return import_compare(a, b); +} + static RzDiff *rz_diff_imports_new(DiffFile *dfile_a, DiffFile *dfile_b) { RzPVector *vec_a = NULL; RzPVector *vec_b = NULL; @@ -756,8 +760,8 @@ static RzDiff *rz_diff_imports_new(DiffFile *dfile_a, DiffFile *dfile_b) { rz_diff_error_ret(NULL, "cannot get imports from '%s'\n", dfile_b->dio->filename); } - rz_pvector_sort(vec_a, (RzPVectorComparator)import_compare); - rz_pvector_sort(vec_b, (RzPVectorComparator)import_compare); + rz_pvector_sort(vec_a, (RzPVectorComparator)import_compare_vec, NULL); + rz_pvector_sort(vec_b, (RzPVectorComparator)import_compare_vec, NULL); RzDiffMethods methods = { .elem_at = (RzDiffMethodElemAt)rz_diff_pvector_elem_at, @@ -811,6 +815,10 @@ static int symbol_compare(const RzBinSymbol *a, const RzBinSymbol *b) { return 0; } +static int symbol_compare_vec(const RzBinSymbol *a, const RzBinSymbol *b, void *user) { + return symbol_compare(a, b); +} + static void symbol_stringify(const RzBinSymbol *elem, RzStrBuf *sb) { rz_strbuf_setf(sb, "%s %s %s\n", elem->libname, elem->classname, elem->name); } @@ -829,8 +837,8 @@ static RzDiff *rz_diff_symbols_new(DiffFile *dfile_a, DiffFile *dfile_b, bool co rz_diff_error_ret(NULL, "cannot get symbols from '%s'\n", dfile_b->dio->filename); } - rz_pvector_sort(vec_a, (RzPVectorComparator)symbol_compare); - rz_pvector_sort(vec_b, (RzPVectorComparator)symbol_compare); + rz_pvector_sort(vec_a, (RzPVectorComparator)symbol_compare_vec, NULL); + rz_pvector_sort(vec_b, (RzPVectorComparator)symbol_compare_vec, NULL); RzDiffMethods methods = { .elem_at = (RzDiffMethodElemAt)rz_diff_pvector_elem_at, @@ -890,6 +898,10 @@ static void string_stringify(const RzBinString *elem, RzStrBuf *sb) { rz_strbuf_setf(sb, "%s\n", elem->string); } +static int string_compare_vec(const RzBinString *a, const RzBinString *b, void *user) { + return string_compare(a, b); +} + static RzDiff *rz_diff_strings_new(DiffFile *dfile_a, DiffFile *dfile_b, bool compare_addr) { RzPVector *vec_a = NULL; RzPVector *vec_b = NULL; @@ -904,8 +916,8 @@ static RzDiff *rz_diff_strings_new(DiffFile *dfile_a, DiffFile *dfile_b, bool co rz_diff_error_ret(NULL, "cannot get strings from '%s'\n", dfile_b->dio->filename); } - rz_pvector_sort(vec_a, (RzPVectorComparator)string_compare); - rz_pvector_sort(vec_b, (RzPVectorComparator)string_compare); + rz_pvector_sort(vec_a, (RzPVectorComparator)string_compare_vec, NULL); + rz_pvector_sort(vec_b, (RzPVectorComparator)string_compare_vec, NULL); RzDiffMethods methods = { .elem_at = (RzDiffMethodElemAt)rz_diff_pvector_elem_at, @@ -952,6 +964,10 @@ static int class_compare(const RzBinClass *a, const RzBinClass *b) { return 0; } +static int class_compare_vec(const RzBinClass *a, const RzBinClass *b, void *user) { + return class_compare(a, b); +} + static void class_stringify(const RzBinClass *elem, RzStrBuf *sb) { rz_strbuf_setf(sb, "%s %s\n", SAFE_STR(elem->super), elem->name); } @@ -970,8 +986,8 @@ static RzDiff *rz_diff_classes_new(DiffFile *dfile_a, DiffFile *dfile_b, bool co rz_diff_error_ret(NULL, "cannot get classes from '%s'\n", dfile_b->dio->filename); } - rz_pvector_sort(vec_a, (RzPVectorComparator)class_compare); - rz_pvector_sort(vec_b, (RzPVectorComparator)class_compare); + rz_pvector_sort(vec_a, (RzPVectorComparator)class_compare_vec, NULL); + rz_pvector_sort(vec_b, (RzPVectorComparator)class_compare_vec, NULL); RzDiffMethods methods = { .elem_at = (RzDiffMethodElemAt)rz_diff_pvector_elem_at, @@ -1077,6 +1093,10 @@ static int libs_compare(const char *a, const char *b) { return 0; } +static int libs_compare_vec(const char *a, const char *b, void *user) { + return libs_compare(a, b); +} + static void libs_stringify(const char *elem, RzStrBuf *sb) { rz_strbuf_setf(sb, "%s\n", SAFE_STR(elem)); } @@ -1095,8 +1115,8 @@ static RzDiff *rz_diff_libraries_new(DiffFile *dfile_a, DiffFile *dfile_b) { rz_diff_error_ret(NULL, "cannot get libraries from '%s'\n", dfile_b->dio->filename); } - rz_pvector_sort(vec_a, (RzPVectorComparator)libs_compare); - rz_pvector_sort(vec_b, (RzPVectorComparator)libs_compare); + rz_pvector_sort(vec_a, (RzPVectorComparator)libs_compare_vec, NULL); + rz_pvector_sort(vec_b, (RzPVectorComparator)libs_compare_vec, NULL); RzDiffMethods methods = { .elem_at = (RzDiffMethodElemAt)rz_diff_pvector_elem_at, @@ -1269,6 +1289,14 @@ static int field_compare(const RzBinField *a, const RzBinField *b) { return 0; } +static int field_compare_addr_vec(const RzBinField *a, const RzBinField *b, void *user) { + return field_compare_addr(a, b); +} + +static int field_compare_vec(const RzBinField *a, const RzBinField *b, void *user) { + return field_compare(a, b); +} + static void field_stringify(const RzBinField *elem, RzStrBuf *sb) { rz_strbuf_setf(sb, "%s %s\n", SAFE_STR(elem->type), elem->name); } @@ -1287,8 +1315,8 @@ static RzDiff *rz_diff_fields_new(DiffFile *dfile_a, DiffFile *dfile_b, bool com rz_diff_error_ret(NULL, "cannot get fields from '%s'\n", dfile_b->dio->filename); } - rz_pvector_sort(vec_a, (RzPVectorComparator)(compare_addr ? field_compare_addr : field_compare)); - rz_pvector_sort(vec_b, (RzPVectorComparator)(compare_addr ? field_compare_addr : field_compare)); + rz_pvector_sort(vec_a, (RzPVectorComparator)(compare_addr ? field_compare_addr_vec : field_compare_vec), NULL); + rz_pvector_sort(vec_b, (RzPVectorComparator)(compare_addr ? field_compare_addr_vec : field_compare_vec), NULL); RzDiffMethods methods = { .elem_at = (RzDiffMethodElemAt)rz_diff_pvector_elem_at, diff --git a/librz/util/table.c b/librz/util/table.c index c73b2ce6266..68bd6c8c1c1 100644 --- a/librz/util/table.c +++ b/librz/util/table.c @@ -4,9 +4,10 @@ #include #include "rz_cons.h" -// cant do that without globals because RzList doesnt have void *user :( -static int Gnth = 0; -static RzListComparator Gcmp = NULL; +typedef struct row_info { + int nth; + RzListComparator cmp; +} row_info_t; static int sortString(const void *a, const void *b) { return strcmp(a, b); @@ -790,44 +791,45 @@ RZ_API void rz_table_filter(RzTable *t, int nth, int op, const char *un) { } } -static int cmp(const void *_a, const void *_b) { +static int cmp(const void *_a, const void *_b, void *user) { + row_info_t *info = (row_info_t *)user; RzTableRow *a = (RzTableRow *)_a; RzTableRow *b = (RzTableRow *)_b; - const char *wa = rz_pvector_at(a->items, Gnth); - const char *wb = rz_pvector_at(b->items, Gnth); - int res = Gcmp(wa, wb); - return res; + const char *wa = rz_pvector_at(a->items, info->nth); + const char *wb = rz_pvector_at(b->items, info->nth); + return info->cmp(wa, wb); } RZ_API void rz_table_sort(RzTable *t, int nth, bool dec) { RzTableColumn *col = rz_vector_index_ptr(t->cols, nth); - if (col) { - Gnth = nth; - if (col->type && col->type->cmp) { - Gcmp = col->type->cmp; - rz_vector_sort(t->rows, cmp, dec); - } - Gnth = 0; - Gcmp = NULL; + if (!(col && col->type && col->type->cmp)) { + return; } + + row_info_t info = { 0 }; + info.nth = nth; + info.cmp = col->type->cmp; + rz_vector_sort(t->rows, cmp, dec, &info); } -static int cmplen(const void *_a, const void *_b) { +static int cmplen(const void *_a, const void *_b, void *user) { + row_info_t *info = (row_info_t *)user; RzTableRow *a = (RzTableRow *)_a; RzTableRow *b = (RzTableRow *)_b; - const char *wa = rz_pvector_at(a->items, Gnth); - const char *wb = rz_pvector_at(b->items, Gnth); - int res = strlen(wa) - strlen(wb); - return res; + const char *wa = rz_pvector_at(a->items, info->nth); + const char *wb = rz_pvector_at(b->items, info->nth); + return strlen(wa) - strlen(wb); } RZ_API void rz_table_sortlen(RzTable *t, int nth, bool dec) { RzTableColumn *col = rz_vector_index_ptr(t->cols, nth); - if (col) { - Gnth = nth; - rz_vector_sort(t->rows, cmplen, dec); - Gnth = 0; + if (!col) { + return; } + + row_info_t info = { 0 }; + info.nth = nth; + rz_vector_sort(t->rows, cmplen, dec, &info); } static int rz_rows_cmp(RzPVector /**/ *lhs, RzPVector /**/ *rhs, RzVector /**/ *cols, int nth) { diff --git a/librz/util/vector.c b/librz/util/vector.c index 9aaa1b42726..f5bd39aa223 100644 --- a/librz/util/vector.c +++ b/librz/util/vector.c @@ -310,7 +310,7 @@ RZ_API void *rz_vector_flush(RzVector *vec) { // CLRS Quicksort. It is slow, but simple. #define VEC_INDEX(a, i) (char *)a + elem_size *(i) -static void vector_quick_sort(void *a, size_t elem_size, size_t len, RzPVectorComparator cmp, bool reverse) { +static void vector_quick_sort(void *a, size_t elem_size, size_t len, RzVectorComparator cmp, bool reverse, void *user) { rz_return_if_fail(a); if (len <= 1) { return; @@ -330,8 +330,8 @@ static void vector_quick_sort(void *a, size_t elem_size, size_t len, RzPVectorCo memcpy(pivot, VEC_INDEX(a, i), elem_size); memcpy(VEC_INDEX(a, i), VEC_INDEX(a, len - 1), elem_size); for (i = 0; i < len - 1; i++) { - if ((cmp(VEC_INDEX(a, i), pivot) < 0 && !reverse) || - (cmp(VEC_INDEX(a, i), pivot) > 0 && reverse)) { + if ((cmp(VEC_INDEX(a, i), pivot, user) < 0 && !reverse) || + (cmp(VEC_INDEX(a, i), pivot, user) > 0 && reverse)) { memcpy(t, VEC_INDEX(a, i), elem_size); memcpy(VEC_INDEX(a, i), VEC_INDEX(a, j), elem_size); memcpy(VEC_INDEX(a, j), t, elem_size); @@ -342,8 +342,8 @@ static void vector_quick_sort(void *a, size_t elem_size, size_t len, RzPVectorCo memcpy(VEC_INDEX(a, j), pivot, elem_size); RZ_FREE(t); RZ_FREE(pivot); - vector_quick_sort(a, elem_size, j, cmp, reverse); - vector_quick_sort(VEC_INDEX(a, j + 1), elem_size, len - j - 1, cmp, reverse); + vector_quick_sort(a, elem_size, j, cmp, reverse, user); + vector_quick_sort(VEC_INDEX(a, j + 1), elem_size, len - j - 1, cmp, reverse, user); } #undef VEC_INDEX @@ -353,10 +353,11 @@ static void vector_quick_sort(void *a, size_t elem_size, size_t len, RzPVectorCo * \param vec pointer to RzVector * \param cmp function used for comparing elements while sorting * \param reverse sort order, ascending order when reverse = False + * \param user user pointer to extra data. */ -RZ_API void rz_vector_sort(RzVector *vec, RzVectorComparator cmp, bool reverse) { +RZ_API void rz_vector_sort(RzVector *vec, RzVectorComparator cmp, bool reverse, void *user) { rz_return_if_fail(vec && cmp); - vector_quick_sort(vec->a, vec->elem_size, vec->len, cmp, reverse); + vector_quick_sort(vec->a, vec->elem_size, vec->len, cmp, reverse, user); } // pvector @@ -431,12 +432,12 @@ RZ_API void **rz_pvector_contains(RzPVector *vec, const void *x) { * \param cmp the comparator function * \return the iter of the element if found, NULL otherwise */ -RZ_API RZ_BORROW void **rz_pvector_find(RZ_NONNULL const RzPVector *vec, RZ_NONNULL const void *value, RZ_NONNULL RzPVectorComparator cmp) { +RZ_API RZ_BORROW void **rz_pvector_find(RZ_NONNULL const RzPVector *vec, RZ_NONNULL const void *value, RZ_NONNULL RzPVectorComparator cmp, void *user) { rz_return_val_if_fail(vec, NULL); void **iter; rz_pvector_foreach (vec, iter) { - if (!cmp(value, *iter)) { + if (!cmp(value, *iter, user)) { return iter; } } @@ -475,7 +476,7 @@ RZ_API void *rz_pvector_pop_front(RzPVector *vec) { } // CLRS Quicksort. It is slow, but simple. -static void quick_sort(void **a, size_t n, RzPVectorComparator cmp) { +static void quick_sort(void **a, size_t n, RzPVectorComparator cmp, void *user) { if (n <= 1) { return; } @@ -483,7 +484,7 @@ static void quick_sort(void **a, size_t n, RzPVectorComparator cmp) { void *t, *pivot = a[i]; a[i] = a[n - 1]; for (i = 0; i < n - 1; i++) { - if (cmp(a[i], pivot) < 0) { + if (cmp(a[i], pivot, user) < 0) { t = a[i]; a[i] = a[j]; a[j] = t; @@ -492,11 +493,11 @@ static void quick_sort(void **a, size_t n, RzPVectorComparator cmp) { } a[n - 1] = a[j]; a[j] = pivot; - quick_sort(a, j, cmp); - quick_sort(a + j + 1, n - j - 1, cmp); + quick_sort(a, j, cmp, user); + quick_sort(a + j + 1, n - j - 1, cmp, user); } -RZ_API void rz_pvector_sort(RzPVector *vec, RzPVectorComparator cmp) { +RZ_API void rz_pvector_sort(RzPVector *vec, RzPVectorComparator cmp, void *user) { rz_return_if_fail(vec && cmp); - quick_sort(vec->v.a, vec->v.len, cmp); + quick_sort(vec->v.a, vec->v.len, cmp, user); } diff --git a/test/unit/test_vector.c b/test/unit/test_vector.c index f0461fe33a3..b0a1851a20c 100644 --- a/test/unit/test_vector.c +++ b/test/unit/test_vector.c @@ -220,6 +220,12 @@ static bool test_vector_clone(void) { mu_end; } +static int compare_string(const char *a, const char *b, void *user) { + int *num = user; + *num = 44; + return strcmp(a, b); +} + static bool test_vector_sort(void) { RzVector *v = rz_vector_new(sizeof("aaa"), NULL, NULL); rz_vector_push(v, "abb"); @@ -228,14 +234,18 @@ static bool test_vector_sort(void) { rz_vector_push(v, "ccc"); // do inc sort - rz_vector_sort(v, (RzVectorComparator)strcmp, false); + int num = 88; + rz_vector_sort(v, (RzVectorComparator)compare_string, false, &num); + mu_assert_eq(num, 44, "check user pointer"); mu_assert_streq(rz_vector_index_ptr(v, 0), "abb", "sorted strings"); mu_assert_streq(rz_vector_index_ptr(v, 1), "abb", "sorted strings"); mu_assert_streq(rz_vector_index_ptr(v, 2), "caa", "sorted strings"); mu_assert_streq(rz_vector_index_ptr(v, 3), "ccc", "sorted strings"); // do dec sort - rz_vector_sort(v, (RzVectorComparator)strcmp, true); + num = 55; + rz_vector_sort(v, (RzVectorComparator)compare_string, true, &num); + mu_assert_eq(num, 44, "check user pointer"); mu_assert_streq(rz_vector_index_ptr(v, 0), "ccc", "sorted strings"); mu_assert_streq(rz_vector_index_ptr(v, 1), "caa", "sorted strings"); mu_assert_streq(rz_vector_index_ptr(v, 2), "abb", "sorted strings"); @@ -893,7 +903,9 @@ static bool test_pvector_set(void) { mu_end; } -static int compare_int(const void *a, const void *b) { +static int compare_int(const void *a, const void *b, void *user) { + int *num = user; + *num = 44; return *(ut32 *)a - *(ut32 *)b; } @@ -901,9 +913,11 @@ static bool test_pvector_find(void) { RzPVector v; init_test_pvector(&v, 5, 0); void *e = ((void **)v.v.a)[3]; + int num = 77; ut32 e_val = 3; - void **p = rz_pvector_find(&v, &e_val, compare_int); + void **p = rz_pvector_find(&v, &e_val, compare_int, &num); mu_assert_eq(*p, e, "find"); + mu_assert_eq(num, 44, "ensure user is passed"); mu_end; } @@ -1199,6 +1213,7 @@ static bool test_pvector_push_front(void) { } static bool test_pvector_sort(void) { + int num = 66; RzPVector v; rz_pvector_init(&v, free); rz_pvector_push(&v, strdup("Charmander")); @@ -1206,9 +1221,10 @@ static bool test_pvector_sort(void) { rz_pvector_push(&v, strdup("Bulbasaur")); rz_pvector_push(&v, strdup("Meowth")); rz_pvector_push(&v, strdup("Caterpie")); - rz_pvector_sort(&v, (RzPVectorComparator)strcmp); + rz_pvector_sort(&v, (RzPVectorComparator)compare_string, &num); mu_assert_eq(v.v.len, 5UL, "sort len"); + mu_assert_eq(num, 44, "sort user pointer check"); mu_assert_streq((const char *)((void **)v.v.a)[0], "Bulbasaur", "sorted strings"); mu_assert_streq((const char *)((void **)v.v.a)[1], "Caterpie", "sorted strings"); mu_assert_streq((const char *)((void **)v.v.a)[2], "Charmander", "sorted strings");