Implement colors for tables and move RzListInfo out of table.c (#5729)
This commit is contained in:
parent
f935f96323
commit
ea21a4a7b4
34 changed files with 1160 additions and 750 deletions
|
|
@ -304,7 +304,7 @@ RZ_API ut64 rz_core_analysis_address(RzCore *core, ut64 addr) {
|
|||
}
|
||||
|
||||
RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn) {
|
||||
RzList *flist = rz_list_newf((RzListFree)rz_listinfo_free);
|
||||
RzList *flist = rz_list_newf((RzListFree)rz_debug_listinfo_free);
|
||||
if (!flist) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -314,14 +314,14 @@ RZ_IPI void rz_core_analysis_bbs_asciiart(RzCore *core, RzAnalysisFunction *fcn)
|
|||
rz_pvector_foreach (fcn->bbs, iter) {
|
||||
b = (RzAnalysisBlock *)*iter;
|
||||
RzInterval inter = (RzInterval){ b->addr, b->size };
|
||||
RzListInfo *info = rz_listinfo_new(NULL, inter, inter, -1, NULL);
|
||||
RzDbgListInfo *info = rz_debug_listinfo_new(NULL, inter, inter, -1, NULL);
|
||||
if (!info) {
|
||||
break;
|
||||
}
|
||||
rz_list_append(flist, info);
|
||||
}
|
||||
RzTable *table = rz_core_table(core);
|
||||
rz_table_visual_list(table, flist, core->offset, core->blocksize,
|
||||
rz_core_debug_listinfo_to_table(table, flist, core->offset, core->blocksize,
|
||||
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
|
||||
rz_cons_printf("\n%s\n", rz_table_tostring(table));
|
||||
rz_table_free(table);
|
||||
|
|
|
|||
|
|
@ -41,8 +41,7 @@
|
|||
static RZ_NULLABLE RZ_BORROW const RzPVector /*<RzBinString *>*/ *core_bin_strings(RzCore *r, RzBinFile *file);
|
||||
|
||||
static void table_add_row_bool(RzTable *t, const char *key, bool val) {
|
||||
RzTableColumnType *typeString = rz_table_type("bool");
|
||||
const char *b = val || typeString ? rz_str_bool(val) : "";
|
||||
const char *b = rz_str_bool(val);
|
||||
rz_table_add_rowf(t, "ss", key, b);
|
||||
}
|
||||
|
||||
|
|
@ -319,9 +318,9 @@ static bool add_footer(RzCmdStateOutput *main_state, RzCmdStateOutput *state) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode default_mode, const char *header) {
|
||||
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode default_mode, const char *header, RzCore *core) {
|
||||
RzCmdStateOutput *state = RZ_NEW(RzCmdStateOutput);
|
||||
rz_cmd_state_output_init(state, main_state->mode == RZ_OUTPUT_MODE_STANDARD ? default_mode : main_state->mode);
|
||||
rz_cmd_state_output_init(state, main_state->mode == RZ_OUTPUT_MODE_STANDARD ? default_mode : main_state->mode, core);
|
||||
if (state->mode == RZ_OUTPUT_MODE_TABLE || state->mode == RZ_OUTPUT_MODE_STANDARD) {
|
||||
rz_cons_printf("[%c%s]\n", toupper(header[0]), header + 1);
|
||||
} else if (state->mode == RZ_OUTPUT_MODE_JSON || state->mode == RZ_OUTPUT_MODE_LONG_JSON) {
|
||||
|
|
@ -354,7 +353,7 @@ RZ_API bool rz_core_bin_print(RzCore *core, RZ_NONNULL RzBinFile *bf, ut32 mask,
|
|||
|
||||
#define wrap_mode(header, default_mode, method) \
|
||||
do { \
|
||||
RzCmdStateOutput *st = add_header(state, default_mode, header); \
|
||||
RzCmdStateOutput *st = add_header(state, default_mode, header, core); \
|
||||
res &= (method); \
|
||||
add_footer(state, st); \
|
||||
} while (0)
|
||||
|
|
@ -447,7 +446,7 @@ RZ_API bool rz_core_bin_print(RzCore *core, RZ_NONNULL RzBinFile *bf, ut32 mask,
|
|||
}
|
||||
if (mask & RZ_CORE_BIN_ACC_PDB) {
|
||||
if (state->mode & (RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON)) {
|
||||
RzCmdStateOutput *st = add_header(state, RZ_OUTPUT_MODE_STANDARD, "pdb");
|
||||
RzCmdStateOutput *st = add_header(state, RZ_OUTPUT_MODE_STANDARD, "pdb", core);
|
||||
RzPdb *pdb = rz_core_pdb_load_info(core, core->bin->file);
|
||||
if (!pdb) {
|
||||
rz_cmd_state_output_free(st);
|
||||
|
|
@ -3122,7 +3121,7 @@ RZ_API bool rz_core_file_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFil
|
|||
pj_end(state->d.pj);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_TABLE: {
|
||||
rz_table_hide_header(state->d.t);
|
||||
rz_table_show_header(state->d.t, false);
|
||||
if (desc) {
|
||||
rz_table_add_rowf(state->d.t, "sd", "fd", desc->fd);
|
||||
}
|
||||
|
|
@ -3168,6 +3167,44 @@ static const char *str2na(const char *s) {
|
|||
return RZ_STR_ISEMPTY(s) ? "N/A" : s;
|
||||
}
|
||||
|
||||
static bool core_bin_info_is_number(const char *value) {
|
||||
if (RZ_STR_ISEMPTY(value)) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; value[i]; ++i) {
|
||||
if (!IS_DIGIT(value[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *core_bin_info_color_selector(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user) {
|
||||
if (!column || !value) {
|
||||
return NULL;
|
||||
}
|
||||
const RzCore *core = (const RzCore *)user;
|
||||
const RzConsContext *ctx = core->cons->context;
|
||||
|
||||
if (RZ_STR_EQ(value, "N/A")) {
|
||||
return ctx->pal.invalid;
|
||||
} else if (value[0] == '0' && value[1] == 'x') {
|
||||
return ctx->pal.offset;
|
||||
} else if (core_bin_info_is_number(value)) {
|
||||
return ctx->pal.num;
|
||||
} else if (rz_str_is_true(value)) {
|
||||
return ctx->pal.graph_true;
|
||||
} else if (rz_str_is_false(value)) {
|
||||
return ctx->pal.graph_false;
|
||||
} else if (RZ_STR_EQ(value, "BE")) {
|
||||
return ctx->pal.ai_seq;
|
||||
} else if (RZ_STR_EQ(value, "LE")) {
|
||||
return ctx->pal.ai_write;
|
||||
}
|
||||
|
||||
return column_n ? ctx->pal.diff_match : ctx->pal.label;
|
||||
}
|
||||
|
||||
RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile *bf, RZ_NONNULL RzCmdStateOutput *state) {
|
||||
rz_return_val_if_fail(core && state, false);
|
||||
|
||||
|
|
@ -3183,6 +3220,11 @@ RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile
|
|||
bool havecode;
|
||||
int bits;
|
||||
|
||||
rz_cmd_state_output_set_columnsf(state, "ss", "field", "value");
|
||||
if (core->cons->context->color_mode != COLOR_MODE_DISABLED) {
|
||||
rz_cmd_state_output_set_color_selector(state, core_bin_info_color_selector, core);
|
||||
}
|
||||
|
||||
havecode = is_executable(obj) || rz_pvector_len(obj->entries) > 0;
|
||||
compiled = rz_core_bin_get_compile_time(bf);
|
||||
bits = (plugin && !strcmp(plugin->name, "any")) ? rz_config_get_i(core->config, "asm.bits") : info->bits;
|
||||
|
|
@ -3353,8 +3395,7 @@ RZ_API bool rz_core_bin_info_print(RZ_NONNULL RzCore *core, RZ_NONNULL RzBinFile
|
|||
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_TABLE:
|
||||
rz_table_set_columnsf(t, "ss", "field", "value");
|
||||
rz_table_hide_header(t);
|
||||
rz_table_show_header(t, false);
|
||||
|
||||
rz_table_add_rowf(t, "ss", "arch", str2na(info->arch));
|
||||
rz_table_add_rowf(t, "ss", "cpu", str2na(info->cpu));
|
||||
|
|
|
|||
|
|
@ -416,7 +416,7 @@ static bool cb_asmcpu(void *user, void *data) {
|
|||
update_asmcpu_options(core, node);
|
||||
/* print verbose help instead of plain option listing */
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core);
|
||||
rz_core_asm_cpu_plugin_print(core, &state, rz_config_get(core->config, "asm.arch"));
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
@ -508,7 +508,7 @@ static bool cb_asmarch(void *user, void *data) {
|
|||
if (strlen(node->value) > 1 && node->value[1] == '?') {
|
||||
/* print more verbose help instead of plain option values */
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core);
|
||||
rz_core_asm_plugins_print(core, &state, NULL);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
@ -1563,9 +1563,9 @@ static bool cb_dbg_args(void *user, void *data) {
|
|||
static bool cb_dbgbackend(void *user, void *data) {
|
||||
RzCore *core = (RzCore *)user;
|
||||
RzConfigNode *node = (RzConfigNode *)data;
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
|
||||
if (!strcmp(node->value, "?")) {
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, core);
|
||||
rz_core_debug_plugins_print(core, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
|
|||
|
|
@ -763,8 +763,17 @@ RZ_API void rz_debug_traces_ascii(RzDebug *dbg, ut64 offset) {
|
|||
rz_return_if_fail(dbg);
|
||||
RzList *info_list = rz_debug_traces_info(dbg, offset);
|
||||
RzTable *table = rz_table_new();
|
||||
table->cons = rz_cons_singleton();
|
||||
rz_table_visual_list(table, info_list, offset, 1,
|
||||
|
||||
RzCons *cons = rz_cons_singleton();
|
||||
if (cons) {
|
||||
if (cons->use_utf8_curvy) {
|
||||
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
|
||||
} else if (cons->use_utf8) {
|
||||
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
rz_core_debug_listinfo_to_table(table, info_list, offset, 1,
|
||||
rz_cons_get_size(NULL), dbg->iob.io->va);
|
||||
char *s = rz_table_tostring(table);
|
||||
rz_cons_printf("\n%s\n", s);
|
||||
|
|
@ -1320,3 +1329,98 @@ RZ_IPI void rz_core_debug_signal_print(RzDebug *dbg, RzCmdStateOutput *state) {
|
|||
}
|
||||
rz_cmd_state_output_array_end(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Populates a RzTable with a given RzList of RzDbgListInfo
|
||||
*
|
||||
* \param table The table to fill
|
||||
* \param list The list to use for filling
|
||||
* \param[in] seek The seek is used as selector to show the current seek
|
||||
* \param[in] len The length of the current selected section
|
||||
* \param[in] width The width max width for printing
|
||||
* \param[in] va When true, seek is a virtual address.
|
||||
*/
|
||||
RZ_IPI void rz_core_debug_listinfo_to_table(RZ_NONNULL RzTable *table, RZ_NULLABLE RzList /*<RzDbgListInfo *>*/ *list, ut64 seek, ut64 len, int width, bool va) {
|
||||
rz_return_if_fail(table);
|
||||
|
||||
ut64 mul, min = -1, max = -1;
|
||||
RzListIter *iter;
|
||||
RzDbgListInfo *info;
|
||||
table->showHeader = false;
|
||||
const char *h_line = table->char_mode != RZ_TABLE_CHAR_MODE_ASCII ? RUNE_LONG_LINE_HORIZ : "-";
|
||||
const char *block = table->char_mode != RZ_TABLE_CHAR_MODE_ASCII ? UTF_BLOCK : "#";
|
||||
int j, i;
|
||||
width -= 80;
|
||||
if (width < 1) {
|
||||
width = 30;
|
||||
}
|
||||
|
||||
rz_table_set_columnsf(table, "sxsxsss", "No.", "start", "blocks", "end", "perms", "extra", "name");
|
||||
rz_list_foreach (list, iter, info) {
|
||||
if (min == -1 || info->pitv.addr < min) {
|
||||
min = info->pitv.addr;
|
||||
}
|
||||
if (max == -1 || info->pitv.addr + info->pitv.size > max) {
|
||||
max = info->pitv.addr + info->pitv.size;
|
||||
}
|
||||
}
|
||||
mul = (max - min) / width;
|
||||
if (min != -1 && mul > 0) {
|
||||
i = 0;
|
||||
rz_list_foreach (list, iter, info) {
|
||||
RzStrBuf *buf = rz_strbuf_new("");
|
||||
for (j = 0; j < width; j++) {
|
||||
ut64 pos = min + j * mul;
|
||||
ut64 npos = min + (j + 1) * mul;
|
||||
const char *arg = (info->pitv.addr < npos && (info->pitv.addr + info->pitv.size) > pos)
|
||||
? block
|
||||
: h_line;
|
||||
rz_strbuf_append(buf, arg);
|
||||
}
|
||||
char *b = rz_strbuf_drain(buf);
|
||||
char no[64];
|
||||
if (va) {
|
||||
rz_table_add_rowf(table, "sxsxsss",
|
||||
rz_strf(no, "%d%c", i, rz_itv_contain(info->vitv, seek) ? '*' : ' '),
|
||||
info->vitv.addr,
|
||||
b,
|
||||
rz_itv_end(info->vitv),
|
||||
(info->perm != -1) ? rz_str_rwx_i(info->perm) : "",
|
||||
(info->extra) ? info->extra : "",
|
||||
(info->name) ? info->name : "");
|
||||
} else {
|
||||
rz_table_add_rowf(table, "sxsxsss",
|
||||
rz_strf(no, "%d%c", i, rz_itv_contain(info->pitv, seek) ? '*' : ' '),
|
||||
info->pitv.addr,
|
||||
b,
|
||||
rz_itv_end(info->pitv),
|
||||
(info->perm != -1) ? rz_str_rwx_i(info->perm) : "",
|
||||
(info->extra) ? info->extra : "",
|
||||
(info->name) ? info->name : "");
|
||||
}
|
||||
free(b);
|
||||
i++;
|
||||
}
|
||||
RzStrBuf *buf = rz_strbuf_new("");
|
||||
/* current seek */
|
||||
if (i > 0 && len != 0) {
|
||||
if (seek == UT64_MAX) {
|
||||
seek = 0;
|
||||
}
|
||||
for (j = 0; j < width; j++) {
|
||||
rz_strbuf_append(buf, ((j * mul) + min >= seek && (j * mul) + min <= seek + len) ? "^" : h_line);
|
||||
}
|
||||
char *s = rz_strbuf_drain(buf);
|
||||
char *seekstart = rz_str_newf("0x%08" PFMT64x, seek);
|
||||
char *seekend = rz_str_newf("0x%08" PFMT64x, seek + len);
|
||||
|
||||
rz_table_add_rowf(table, "sssssss", "=>", seekstart, s, seekend, "", "", "");
|
||||
|
||||
free(seekend);
|
||||
free(seekstart);
|
||||
free(s);
|
||||
} else {
|
||||
rz_strbuf_free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3203,27 +3203,25 @@ static int RzAnalysisRef_cmp(const RzAnalysisXRef *xref1, const RzAnalysisXRef *
|
|||
}
|
||||
|
||||
static void function_list_print_to_table(RzCore *core, RzList /*<RzAnalysisFunction *>*/ *list, RzTable *t, bool verbose) {
|
||||
RzTableColumnType *typeString = rz_table_type("string");
|
||||
RzTableColumnType *typeNumber = rz_table_type("number");
|
||||
rz_table_add_column(t, typeNumber, "addr", 0);
|
||||
rz_table_add_column(t, typeString, "name", 0);
|
||||
rz_table_add_column(t, typeNumber, "size", 0);
|
||||
rz_table_add_column(t, typeNumber, "xrefsTo", 0);
|
||||
rz_table_add_column(t, typeNumber, "xrefsFrom", 0);
|
||||
rz_table_add_column(t, typeNumber, "calls", 0);
|
||||
rz_table_add_column(t, typeNumber, "nbbs", 0);
|
||||
rz_table_add_column(t, typeNumber, "edges", 0);
|
||||
rz_table_add_column(t, typeNumber, "cc", 0);
|
||||
rz_table_add_column(t, typeNumber, "cost", 0);
|
||||
rz_table_add_column(t, rz_table_type("boolean"), "noreturn", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "size");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "xrefsTo");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "xrefsFrom");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "calls");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "nbbs");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "edges");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "cc");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "cost");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_BOOL, "noreturn");
|
||||
if (verbose) {
|
||||
rz_table_add_column(t, typeNumber, "min bound", 0);
|
||||
rz_table_add_column(t, typeNumber, "range", 0);
|
||||
rz_table_add_column(t, typeNumber, "max bound", 0);
|
||||
rz_table_add_column(t, typeNumber, "locals", 0);
|
||||
rz_table_add_column(t, typeNumber, "args", 0);
|
||||
rz_table_add_column(t, typeNumber, "frame", 0);
|
||||
rz_table_add_column(t, typeNumber, "loops", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "min bound");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "range");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "max bound");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "locals");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "args");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "frame");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "loops");
|
||||
}
|
||||
|
||||
RzListIter *iter;
|
||||
|
|
@ -3444,7 +3442,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_list_handler(RzCore *core, int argc, con
|
|||
break;
|
||||
case RZ_OUTPUT_MODE_LONG:
|
||||
rz_cmd_state_output_fini(state);
|
||||
if (rz_cmd_state_output_init(state, RZ_OUTPUT_MODE_TABLE)) {
|
||||
if (rz_cmd_state_output_init(state, RZ_OUTPUT_MODE_TABLE, core)) {
|
||||
function_list_print_to_table(core, list, state->d.t, true);
|
||||
} else {
|
||||
res = RZ_CMD_STATUS_ERROR;
|
||||
|
|
@ -3583,7 +3581,7 @@ RZ_IPI RzCmdStatus rz_analysis_function_list_ascii_handler(RzCore *core, int arg
|
|||
if (!fcns) {
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
RzList *flist = rz_list_newf((RzListFree)rz_listinfo_free);
|
||||
RzList *flist = rz_list_newf((RzListFree)rz_debug_listinfo_free);
|
||||
if (!flist) {
|
||||
rz_list_free(fcns);
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
|
|
@ -3593,14 +3591,14 @@ RZ_IPI RzCmdStatus rz_analysis_function_list_ascii_handler(RzCore *core, int arg
|
|||
RzAnalysisFunction *fcn;
|
||||
rz_list_foreach (fcns, iter, fcn) {
|
||||
RzInterval inter = { rz_analysis_function_min_addr(fcn), rz_analysis_function_linear_size(fcn) };
|
||||
RzListInfo *info = rz_listinfo_new(fcn->name, inter, inter, -1, rz_strf(temp, "%d", fcn->bits));
|
||||
RzDbgListInfo *info = rz_debug_listinfo_new(fcn->name, inter, inter, -1, rz_strf(temp, "%d", fcn->bits));
|
||||
if (!info) {
|
||||
break;
|
||||
}
|
||||
rz_list_append(flist, info);
|
||||
}
|
||||
RzTable *table = rz_core_table(core);
|
||||
rz_table_visual_list(table, flist, core->offset, core->blocksize,
|
||||
rz_core_debug_listinfo_to_table(table, flist, core->offset, core->blocksize,
|
||||
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
|
||||
char *tablestr = rz_table_tostring(table);
|
||||
rz_cons_printf("\n%s\n", tablestr);
|
||||
|
|
@ -3852,11 +3850,9 @@ static void print_stats(RzCore *core, HtSU *ht, RzAnalysisFunction *fcn, RzCmdSt
|
|||
rz_list_sort(list, (RzListComparator)strcmp, NULL);
|
||||
if (state->mode == RZ_OUTPUT_MODE_TABLE) {
|
||||
RzTable *t = state->d.t;
|
||||
RzTableColumnType *typeString = rz_table_type("string");
|
||||
RzTableColumnType *typeNumber = rz_table_type("number");
|
||||
rz_table_add_column(t, typeString, "name", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
|
||||
rz_list_foreach (list, iter, name) {
|
||||
rz_table_add_column(t, typeNumber, name, 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, name);
|
||||
}
|
||||
RzPVector *items = rz_pvector_new(free);
|
||||
if (!items) {
|
||||
|
|
@ -3942,14 +3938,12 @@ RZ_IPI RzCmdStatus rz_analysis_function_all_opcode_stat_handler(RzCore *core, in
|
|||
rz_list_sort(keys, (RzListComparator)strcmp, NULL);
|
||||
|
||||
RzTable *t = state->d.t;
|
||||
RzTableColumnType *typeString = rz_table_type("string");
|
||||
RzTableColumnType *typeNumber = rz_table_type("number");
|
||||
rz_table_add_column(t, typeString, "name", 0);
|
||||
rz_table_add_column(t, typeNumber, "addr", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
|
||||
|
||||
char *key;
|
||||
rz_list_foreach (keys, iter, key) {
|
||||
rz_table_add_column(t, typeNumber, key, 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, key);
|
||||
}
|
||||
|
||||
RzListIter *iter2;
|
||||
|
|
|
|||
|
|
@ -759,7 +759,7 @@ static RzCmdStatus argv_call_cb(RzCmd *cmd, RzCmdDesc *cd, RzCmdParsedArgs *args
|
|||
return RZ_CMD_STATUS_WRONG_ARGS;
|
||||
}
|
||||
RzCmdStateOutput state;
|
||||
if (!rz_cmd_state_output_init(&state, mode)) {
|
||||
if (!rz_cmd_state_output_init(&state, mode, cmd->core)) {
|
||||
return RZ_CMD_STATUS_INVALID;
|
||||
}
|
||||
RzCmdStatus res = cd->d.argv_state_data.cb(cmd->core, args->argc, (const char **)args->argv, &state);
|
||||
|
|
@ -2453,6 +2453,14 @@ RZ_API void rz_cmd_state_output_set_columnsf(RzCmdStateOutput *state, const char
|
|||
va_end(ap);
|
||||
}
|
||||
|
||||
RZ_API void rz_cmd_state_output_set_color_selector(RzCmdStateOutput *state, RzTableColorSelector color_cb, void *user) {
|
||||
rz_return_if_fail(state);
|
||||
if (state->mode == RZ_OUTPUT_MODE_TABLE) {
|
||||
rz_return_if_fail(state->d.t);
|
||||
rz_table_set_color_selector(state->d.t, color_cb, user);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clear the inner fields of RzCmdStateOutput structure, but do not free it.
|
||||
*/
|
||||
|
|
@ -2488,10 +2496,100 @@ RZ_API void rz_cmd_state_output_free(RZ_NONNULL RzCmdStateOutput *state) {
|
|||
free(state);
|
||||
}
|
||||
|
||||
static inline bool table_value_is_invalid(const char *value) {
|
||||
if (RZ_STR_ISEMPTY(value)) {
|
||||
return true;
|
||||
}
|
||||
for (size_t i = 0; value[i]; ++i) {
|
||||
if (value[i] != '-') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool table_value_is_flags(const char *column) {
|
||||
if (!column) {
|
||||
return false;
|
||||
}
|
||||
return rz_str_startswith(column, "perm") ||
|
||||
rz_str_startswith(column, "flag");
|
||||
}
|
||||
|
||||
static inline bool table_value_is_offset(const char *column) {
|
||||
if (!column) {
|
||||
return false;
|
||||
}
|
||||
return RZ_STR_EQ(column, "vaddr") ||
|
||||
RZ_STR_EQ(column, "paddr") ||
|
||||
RZ_STR_EQ(column, "va") ||
|
||||
RZ_STR_EQ(column, "pa") ||
|
||||
RZ_STR_EQ(column, "va_end") ||
|
||||
RZ_STR_EQ(column, "pa_end") ||
|
||||
RZ_STR_EQ(column, "addr") ||
|
||||
RZ_STR_EQ(column, "offset");
|
||||
}
|
||||
|
||||
static inline bool table_value_is_meta(const char *column) {
|
||||
if (!column) {
|
||||
return false;
|
||||
}
|
||||
return rz_str_startswith(column, "type") ||
|
||||
rz_str_startswith(column, "meta") ||
|
||||
RZ_STR_EQ(column, "fd");
|
||||
}
|
||||
|
||||
static inline bool table_value_is_name(const char *column) {
|
||||
if (!column) {
|
||||
return false;
|
||||
}
|
||||
return rz_str_startswith(column, "name");
|
||||
}
|
||||
|
||||
static inline bool table_value_is_comment(const char *column) {
|
||||
if (!column) {
|
||||
return false;
|
||||
}
|
||||
return rz_str_startswith(column, "comment");
|
||||
}
|
||||
|
||||
static const char *core_cmd_default_table_color(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user) {
|
||||
const RzCore *core = (const RzCore *)user;
|
||||
const RzConsContext *ctx = core->cons->context;
|
||||
if (ctx->color_mode == COLOR_MODE_DISABLED) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (table_value_is_invalid(value)) {
|
||||
return ctx->pal.invalid;
|
||||
} else if (table_value_is_flags(column)) {
|
||||
return ctx->pal.flag;
|
||||
} else if (table_value_is_name(column)) {
|
||||
return ctx->pal.fname;
|
||||
} else if (table_value_is_meta(column)) {
|
||||
return ctx->pal.meta;
|
||||
} else if (table_value_is_comment(column)) {
|
||||
return ctx->pal.comment;
|
||||
} else if (table_value_is_offset(column)) {
|
||||
return ctx->pal.offset;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case RZ_TABLE_COLUMN_TYPE_STRING:
|
||||
return ctx->pal.label;
|
||||
case RZ_TABLE_COLUMN_TYPE_NUMBER:
|
||||
return ctx->pal.num;
|
||||
case RZ_TABLE_COLUMN_TYPE_BOOL:
|
||||
return ctx->pal.cjmp;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize a RzCmdStateOutput structure and its inner fields based on the provided mode
|
||||
*/
|
||||
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode) {
|
||||
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode, RZ_NULLABLE const RzCore *core) {
|
||||
rz_return_val_if_fail(state, false);
|
||||
|
||||
state->mode = mode;
|
||||
|
|
@ -2501,6 +2599,16 @@ RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutpu
|
|||
if (!state->d.t) {
|
||||
return false;
|
||||
}
|
||||
if (core && core->cons && core->cons->context) {
|
||||
if (core->cons->use_utf8_curvy) {
|
||||
rz_table_set_char_mode(state->d.t, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
|
||||
} else if (core->cons->use_utf8) {
|
||||
rz_table_set_char_mode(state->d.t, RZ_TABLE_CHAR_MODE_UTF8);
|
||||
}
|
||||
if (core->cons->context->color_mode != COLOR_MODE_DISABLED) {
|
||||
rz_table_set_color_selector(state->d.t, core_cmd_default_table_color, (void *)core);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_STR_BUF:
|
||||
state->d.sbuf = rz_strbuf_new("");
|
||||
|
|
|
|||
|
|
@ -745,7 +745,7 @@ RZ_IPI RzCmdStatus rz_cmd_debug_map_current_handler(RzCore *core, int argc, cons
|
|||
ut64 addr = core->offset;
|
||||
// RZ_OUTPUT_MODE_LONG is workaround for '.'
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG, core);
|
||||
rz_core_debug_map_print(core, addr, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
|
|||
|
|
@ -319,7 +319,7 @@ RZ_IPI RzCmdStatus rz_cmd_eval_color_load_next_theme_handler(RzCore *core, int a
|
|||
|
||||
RZ_IPI RzCmdStatus rz_cmd_eval_color_highlight_list_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, mode);
|
||||
rz_cmd_state_output_init(&state, mode, core);
|
||||
rz_core_meta_print_list_all(core, RZ_META_TYPE_HIGHLIGHT, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
@ -413,7 +413,7 @@ RZ_IPI RzCmdStatus rz_cmd_eval_color_highlight_instruction_word_handler(RzCore *
|
|||
|
||||
RZ_IPI RzCmdStatus rz_cmd_eval_color_highlight_list_current_handler(RzCore *core, int argc, const char **argv) {
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core);
|
||||
rz_core_meta_print_list_in_function(core, RZ_META_TYPE_COMMENT, core->offset, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
@ -434,7 +434,7 @@ static void print_all_plugin_configs(const RzCore *core) {
|
|||
// Incomplete plugin config key.
|
||||
RzConfig **cfg;
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, core);
|
||||
RzIterator *it = ht_sp_as_iter(core->plugin_configs);
|
||||
rz_iterator_foreach(it, cfg) {
|
||||
rz_core_config_print_all(*cfg, "", &state);
|
||||
|
|
@ -498,7 +498,7 @@ RZ_IPI RzCmdStatus rz_eval_getset_handler(RzCore *core, int argc, const char **a
|
|||
if (llen == 1 && rz_str_endswith(key, ".")) {
|
||||
// no value was set, only key with ".". List possible sub-keys.
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, core);
|
||||
rz_core_config_print_all(cfg, key, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ RZ_IPI RzCmdStatus rz_cmd_help_search_interactive_handler(RzCore *core, int argc
|
|||
// "?**e"
|
||||
RZ_IPI RzCmdStatus rz_cmd_help_search_interactive_settings_handler(RzCore *core, int argc, const char **argv) {
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STR_BUF);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STR_BUF, core);
|
||||
rz_core_config_print_all(core->config, "", &state);
|
||||
|
||||
RzConfig **cfg;
|
||||
|
|
|
|||
|
|
@ -266,7 +266,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_section_bars_handler(RzCore *core, int argc, cons
|
|||
}
|
||||
|
||||
int cols = rz_cons_get_size(NULL);
|
||||
RzList *list = rz_list_newf((RzListFree)rz_listinfo_free);
|
||||
RzList *list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
|
||||
if (!list) {
|
||||
goto sections_err;
|
||||
}
|
||||
|
|
@ -280,7 +280,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_section_bars_handler(RzCore *core, int argc, cons
|
|||
RzInterval vitv = (RzInterval){ section->vaddr, section->vsize };
|
||||
|
||||
rz_num_units(humansz, sizeof(humansz), section->size);
|
||||
RzListInfo *info = rz_listinfo_new(section->name, pitv, vitv, section->perm, humansz);
|
||||
RzDbgListInfo *info = rz_debug_listinfo_new(section->name, pitv, vitv, section->perm, humansz);
|
||||
if (!info) {
|
||||
RZ_LOG_ERROR("Cannot print section bars\n");
|
||||
goto list_err;
|
||||
|
|
@ -292,7 +292,7 @@ RZ_IPI RzCmdStatus rz_cmd_info_section_bars_handler(RzCore *core, int argc, cons
|
|||
RZ_LOG_ERROR("Cannot print section bars\n");
|
||||
goto list_err;
|
||||
}
|
||||
rz_table_visual_list(table, list, core->offset, 1, cols, core->io->va);
|
||||
rz_core_debug_listinfo_to_table(table, list, core->offset, 1, cols, core->io->va);
|
||||
|
||||
char *s = rz_table_tostring(table);
|
||||
if (!s) {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ RZ_IPI RzCmdStatus rz_cmd_heap_chunk_print_handler(RzCore *core, int argc, const
|
|||
RZ_IPI RzCmdStatus rz_cmd_heap_chunks_graph_handler(RzCore *core, int argc, const char **argv) {
|
||||
// RZ_OUTPUT_MODE_LONG_JSON mode workaround for graph
|
||||
RzCmdStateOutput state = { 0 };
|
||||
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG_JSON)) {
|
||||
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_LONG_JSON, core)) {
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
RzCmdStatus res;
|
||||
|
|
|
|||
|
|
@ -244,7 +244,7 @@ RZ_IPI RzCmdStatus rz_open_maps_remove_all_handler(RzCore *core, int argc, const
|
|||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_open_maps_list_ascii_handler(RzCore *core, int argc, const char **argv) {
|
||||
RzList *list = rz_list_newf((RzListFree)rz_listinfo_free);
|
||||
RzList *list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
|
||||
if (!list) {
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
|
@ -254,14 +254,14 @@ RZ_IPI RzCmdStatus rz_open_maps_list_ascii_handler(RzCore *core, int argc, const
|
|||
RzIOMap *map = *it;
|
||||
char temp[32];
|
||||
rz_strf(temp, "%d", map->fd);
|
||||
RzListInfo *info = rz_listinfo_new(map->name, map->itv, map->itv, map->perm, temp);
|
||||
RzDbgListInfo *info = rz_debug_listinfo_new(map->name, map->itv, map->itv, map->perm, temp);
|
||||
if (!info) {
|
||||
break;
|
||||
}
|
||||
rz_list_append(list, info);
|
||||
}
|
||||
RzTable *table = rz_core_table(core);
|
||||
rz_table_visual_list(table, list, core->offset, core->blocksize,
|
||||
rz_core_debug_listinfo_to_table(table, list, core->offset, core->blocksize,
|
||||
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
|
||||
char *tablestr = rz_table_tostring(table);
|
||||
rz_cons_printf("%s", tablestr);
|
||||
|
|
@ -678,7 +678,7 @@ RZ_IPI RzCmdStatus rz_open_binary_list_ascii_handler(RzCore *core, int argc, con
|
|||
if (!bin) {
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
RzList *list = rz_list_newf((RzListFree)rz_listinfo_free);
|
||||
RzList *list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
|
||||
if (!list) {
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
|
|
@ -687,14 +687,14 @@ RZ_IPI RzCmdStatus rz_open_binary_list_ascii_handler(RzCore *core, int argc, con
|
|||
rz_list_foreach (bin->binfiles, iter, bf) {
|
||||
char temp[64];
|
||||
RzInterval inter = (RzInterval){ bf->o->opts.baseaddr, bf->o->size };
|
||||
RzListInfo *info = rz_listinfo_new(bf->file, inter, inter, -1, sdb_itoa(bf->fd, temp, 10));
|
||||
RzDbgListInfo *info = rz_debug_listinfo_new(bf->file, inter, inter, -1, sdb_itoa(bf->fd, temp, 10));
|
||||
if (!info) {
|
||||
break;
|
||||
}
|
||||
rz_list_append(list, info);
|
||||
}
|
||||
RzTable *table = rz_core_table(core);
|
||||
rz_table_visual_list(table, list, core->offset, core->blocksize,
|
||||
rz_core_debug_listinfo_to_table(table, list, core->offset, core->blocksize,
|
||||
rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
|
||||
char *table_text = rz_table_tostring(table);
|
||||
rz_cons_printf("\n%s\n", table_text);
|
||||
|
|
|
|||
|
|
@ -1712,18 +1712,15 @@ static bool cmd_pxr(RzCore *core, ut64 at, int len, RzCmdStateOutput *state, int
|
|||
}
|
||||
|
||||
const ut8 *buf = core->block;
|
||||
|
||||
bool be = core->analysis->big_endian;
|
||||
int end = RZ_MIN(core->blocksize, len);
|
||||
int bitsize = wordsize * 8;
|
||||
RzOutputMode mode = state->mode;
|
||||
if (mode == RZ_OUTPUT_MODE_TABLE) {
|
||||
RzTable *t = state->d.t;
|
||||
RzTableColumnType *n = rz_table_type("number");
|
||||
RzTableColumnType *s = rz_table_type("string");
|
||||
rz_table_add_column(t, n, "addr", 0);
|
||||
rz_table_add_column(t, n, "value", 0);
|
||||
rz_table_add_column(t, s, "refs", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "value");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "refs");
|
||||
for (ut64 i = 0; i + wordsize < end; i += wordsize) {
|
||||
ut64 addr = at + i;
|
||||
ut64 val = rz_read_ble(buf + i, be, bitsize);
|
||||
|
|
@ -4724,7 +4721,7 @@ static void print_stack(RzCore *core) {
|
|||
RzCmdStateOutput so;
|
||||
ut64 sp_addr = rz_core_reg_getv_by_role_or_name(core, "SP");
|
||||
if (rz_config_get_b(core->config, "dbg.slow")) {
|
||||
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD, core);
|
||||
int wordsize = rz_analysis_get_address_bits(core->analysis) / 8;
|
||||
cmd_pxr(core, sp_addr, 128, &so, wordsize, NULL);
|
||||
rz_cmd_state_output_print(&so);
|
||||
|
|
@ -4741,7 +4738,7 @@ static void print_stack(RzCore *core) {
|
|||
} else if (core->rasm->bits == 32) {
|
||||
rz_core_print_dump(core, RZ_OUTPUT_MODE_STANDARD, sp_addr, 4, 128, RZ_CORE_PRINT_FORMAT_TYPE_HEXADECIMAL);
|
||||
}
|
||||
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD, core);
|
||||
core_disassembly(core, core->blocksize, 0, &so, false);
|
||||
rz_cmd_state_output_fini(&so);
|
||||
}
|
||||
|
|
@ -4778,7 +4775,7 @@ RZ_IPI RzCmdStatus rz_print_columns_debug_handler(RzCore *core, int argc, const
|
|||
rz_cons_push();
|
||||
rz_debug_regs_args_handler(core, 0, NULL, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cons_print("\nbacktrace:\n");
|
||||
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&so, RZ_OUTPUT_MODE_STANDARD, core);
|
||||
rz_cmd_debug_display_bt_handler(core, 0, NULL, &so);
|
||||
rz_cmd_state_output_print(&so);
|
||||
rz_cmd_state_output_fini(&so);
|
||||
|
|
@ -5399,12 +5396,10 @@ static bool print_rising_and_falling_entropy_table(RzCore *core, RzCmdStateOutpu
|
|||
bool resetFlag = 1;
|
||||
st8 lastEdge = 0;
|
||||
RzTable *t = state->d.t;
|
||||
RzTableColumnType *n = rz_table_type("number");
|
||||
RzTableColumnType *s = rz_table_type("string");
|
||||
rz_table_add_column(t, n, "addr", 0);
|
||||
rz_table_add_column(t, n, "index", 0);
|
||||
rz_table_add_column(t, s, "edge_type", 0);
|
||||
rz_table_add_column(t, n, "entropy_value", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "addr");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "index");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "edge_type");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "entropy_value");
|
||||
for (int i = 0; i < brange->nblocks; i++) {
|
||||
ut64 off = brange->from + (brange->blocksize * (i));
|
||||
if (!rz_io_read_at(core->io, off, tmp, brange->blocksize))
|
||||
|
|
|
|||
|
|
@ -2257,8 +2257,13 @@ RZ_API RzBuffer *rz_core_syscall(RzCore *core, const char *name, const char *arg
|
|||
|
||||
RZ_API RzTable *rz_core_table(RzCore *core) {
|
||||
RzTable *table = rz_table_new();
|
||||
if (table) {
|
||||
table->cons = core->cons;
|
||||
if (!table || !core->cons) {
|
||||
return table;
|
||||
}
|
||||
if (core->cons->use_utf8_curvy) {
|
||||
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
|
||||
} else if (core->cons->use_utf8) {
|
||||
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,7 @@ RZ_IPI bool rz_core_debug_pid_print(RzDebug *dbg, int pid, RzCmdStateOutput *sta
|
|||
RZ_IPI bool rz_core_debug_thread_print(RzDebug *dbg, int pid, RzCmdStateOutput *state);
|
||||
RZ_IPI bool rz_core_debug_desc_print(RzDebug *dbg, RzCmdStateOutput *state);
|
||||
RZ_IPI void rz_core_debug_signal_print(RzDebug *dbg, RzCmdStateOutput *state);
|
||||
RZ_IPI void rz_core_debug_listinfo_to_table(RZ_NONNULL RzTable *table, RZ_NULLABLE RzList /*<RzDbgListInfo *>*/ *list, ut64 seek, ut64 len, int width, bool va);
|
||||
|
||||
/* cfile.c */
|
||||
RZ_IPI RzCoreIOMapInfo *rz_core_io_map_info_new(RzCoreFile *cf, int perm_orig);
|
||||
|
|
|
|||
|
|
@ -18,14 +18,12 @@ rz_core_sources = [
|
|||
'basefind.c',
|
||||
'caddr.c',
|
||||
'cagraph.c',
|
||||
'cgraph.c',
|
||||
'canalysis.c',
|
||||
'cannotated_code.c',
|
||||
'carg.c',
|
||||
'casm.c',
|
||||
'cautocmpl.c',
|
||||
'cbin.c',
|
||||
'cmark.c',
|
||||
'cbounds.c',
|
||||
'cconfig.c',
|
||||
'ccrypto.c',
|
||||
|
|
@ -33,11 +31,13 @@ rz_core_sources = [
|
|||
'cesil.c',
|
||||
'cfile.c',
|
||||
'cflag.c',
|
||||
'cgraph.c',
|
||||
'chash.c',
|
||||
'cheap.c',
|
||||
'cil.c',
|
||||
'cio.c',
|
||||
'clang.c',
|
||||
'cmark.c',
|
||||
'cmeta.c',
|
||||
'cmp.c',
|
||||
'core.c',
|
||||
|
|
@ -48,9 +48,9 @@ rz_core_sources = [
|
|||
'creg.c',
|
||||
'csearch.c',
|
||||
'csign.c',
|
||||
'csyscall.c',
|
||||
'ctypes.c',
|
||||
'cvfile.c',
|
||||
'csyscall.c',
|
||||
'devirtualize_cxx.c',
|
||||
'devirtualize_objc.c',
|
||||
'disasm.c',
|
||||
|
|
|
|||
|
|
@ -1204,7 +1204,7 @@ repeat:
|
|||
bool asm_bytes = rz_config_get_b(core->config, "asm.bytes");
|
||||
rz_config_set_b(core->config, "asm.bytes", false);
|
||||
RzCmdStateOutput state;
|
||||
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD)) {
|
||||
if (!rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, core)) {
|
||||
return RZ_CMD_STATUS_INVALID;
|
||||
}
|
||||
rz_core_flag_describe(core, core->offset, false, &state);
|
||||
|
|
|
|||
|
|
@ -1230,14 +1230,17 @@ err:
|
|||
}
|
||||
|
||||
static RzTable *__new_heapblock_tbl(void) {
|
||||
RzTable *tbl = rz_table_new();
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "HeaderAddress", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "UserAddress", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Size", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Granularity", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Unused", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("String"), "Type", -1);
|
||||
return tbl;
|
||||
RzTable *t = rz_table_new();
|
||||
if (!t) {
|
||||
return NULL;
|
||||
}
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "HeaderAddress");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "UserAddress");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Size");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Granularity");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Unused");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "Type");
|
||||
return t;
|
||||
}
|
||||
|
||||
RZ_IPI void rz_heap_list_w32(RzCore *core, RzOutputMode mode) {
|
||||
|
|
@ -1257,10 +1260,10 @@ RZ_IPI void rz_heap_list_w32(RzCore *core, RzOutputMode mode) {
|
|||
CHECK_INFO(heapInfo);
|
||||
int i;
|
||||
RzTable *tbl = rz_table_new();
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Address", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Blocks", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Allocated", -1);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Commited", -1);
|
||||
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Address");
|
||||
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Blocks");
|
||||
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Allocated");
|
||||
rz_table_add_column(tbl, RZ_TABLE_COLUMN_TYPE_NUMBER, "Commited");
|
||||
PJ *pj = pj_new();
|
||||
pj_a(pj);
|
||||
for (i = 0; i < heapInfo->count; i++) {
|
||||
|
|
|
|||
|
|
@ -287,15 +287,15 @@ static window *window_from_handle(HANDLE hwnd) {
|
|||
}
|
||||
|
||||
static RzTable *create_window_table(void) {
|
||||
RzTable *tbl = rz_table_new();
|
||||
if (!tbl) {
|
||||
RzTable *t = rz_table_new();
|
||||
if (!t) {
|
||||
return NULL;
|
||||
}
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "Handle", ST32_MAX);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "PID", ST32_MAX);
|
||||
rz_table_add_column(tbl, rz_table_type("number"), "TID", ST32_MAX);
|
||||
rz_table_add_column(tbl, rz_table_type("string"), "Class Name", ST32_MAX);
|
||||
return tbl;
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "Handle");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "PID");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "TID");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "Class Name");
|
||||
return t;
|
||||
}
|
||||
|
||||
static void add_window_to_table(RzTable *tbl, window *win) {
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ RZ_API RzDebugTracepoint *rz_debug_trace_get(RzDebug *dbg, ut64 addr) {
|
|||
}
|
||||
|
||||
static int cmpaddr(const void *_a, const void *_b, void *user) {
|
||||
const RzListInfo *a = _a, *b = _b;
|
||||
const RzDbgListInfo *a = _a, *b = _b;
|
||||
return (rz_itv_begin(a->pitv) > rz_itv_begin(b->pitv)) ? 1 : (rz_itv_begin(a->pitv) < rz_itv_begin(b->pitv)) ? -1
|
||||
: 0;
|
||||
}
|
||||
|
|
@ -221,13 +221,13 @@ static int cmpaddr(const void *_a, const void *_b, void *user) {
|
|||
* Get all trace info
|
||||
* \param dbg core->dbg
|
||||
* \param offset offset of address
|
||||
* \return a RzList of RzListInfo
|
||||
* \return a RzList of RzDbgListInfo
|
||||
*/
|
||||
RZ_API RZ_OWN RzList /*<RzListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset) {
|
||||
RZ_API RZ_OWN RzList /*<RzDbgListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset) {
|
||||
rz_return_val_if_fail(dbg, NULL);
|
||||
int tag = dbg->trace->tag;
|
||||
RzListIter *iter;
|
||||
RzList *info_list = rz_list_new();
|
||||
RzList *info_list = rz_list_newf((RzListFree)rz_debug_listinfo_free);
|
||||
if (!info_list) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ RZ_API RZ_OWN RzList /*<RzListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64
|
|||
if (trace->tag && !(tag & trace->tag)) {
|
||||
continue;
|
||||
}
|
||||
RzListInfo *info = RZ_NEW0(RzListInfo);
|
||||
RzDbgListInfo *info = RZ_NEW0(RzDbgListInfo);
|
||||
if (!info) {
|
||||
rz_list_free(info_list);
|
||||
return NULL;
|
||||
|
|
@ -283,3 +283,25 @@ RZ_API void rz_debug_trace_reset(RzDebug *dbg) {
|
|||
t->traces = rz_list_new();
|
||||
t->traces->free = free;
|
||||
}
|
||||
|
||||
RZ_API RZ_OWN RzDbgListInfo *rz_debug_listinfo_new(RZ_NULLABLE const char *name, RzInterval pitv, RzInterval vitv, int perm, RZ_NULLABLE const char *extra) {
|
||||
RzDbgListInfo *info = RZ_NEW(RzDbgListInfo);
|
||||
if (!info) {
|
||||
return NULL;
|
||||
}
|
||||
info->name = rz_str_dup(name);
|
||||
info->pitv = pitv;
|
||||
info->vitv = vitv;
|
||||
info->perm = perm;
|
||||
info->extra = rz_str_dup(extra);
|
||||
return info;
|
||||
}
|
||||
|
||||
RZ_API void rz_debug_listinfo_free(RZ_NULLABLE RzDbgListInfo *info) {
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
free(info->name);
|
||||
free(info->extra);
|
||||
free(info);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -594,7 +594,8 @@ RZ_API char *rz_cmd_unescape_arg(const char *arg, RzCmdEscape escape);
|
|||
RZ_API void rz_cmd_state_output_array_start(RzCmdStateOutput *state);
|
||||
RZ_API void rz_cmd_state_output_array_end(RzCmdStateOutput *state);
|
||||
RZ_API void rz_cmd_state_output_set_columnsf(RzCmdStateOutput *state, const char *fmt, ...);
|
||||
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode);
|
||||
RZ_API void rz_cmd_state_output_set_color_selector(RzCmdStateOutput *state, RzTableColorSelector color_cb, void *user);
|
||||
RZ_API bool rz_cmd_state_output_init(RZ_NONNULL RzCmdStateOutput *state, RzOutputMode mode, RZ_NULLABLE const RzCore *core);
|
||||
RZ_API void rz_cmd_state_output_fini(RZ_NONNULL RzCmdStateOutput *state);
|
||||
RZ_API void rz_cmd_state_output_free(RZ_NONNULL RzCmdStateOutput *state);
|
||||
RZ_API void rz_cmd_state_output_print(RZ_NONNULL RzCmdStateOutput *state);
|
||||
|
|
|
|||
|
|
@ -428,6 +428,14 @@ typedef struct rz_debug_esil_watchpoint_t {
|
|||
char *expr;
|
||||
} RzDebugEsilWatchpoint;
|
||||
|
||||
typedef struct {
|
||||
char *name; ///< Name of the information
|
||||
RzInterval pitv; ///< Offset interval
|
||||
RzInterval vitv; ///< Virtual address interval
|
||||
int perm; ///< Permissions
|
||||
char *extra; ///< Extra printable information
|
||||
} RzDbgListInfo;
|
||||
|
||||
#ifdef RZ_API
|
||||
|
||||
/**
|
||||
|
|
@ -556,7 +564,7 @@ RZ_API int rz_debug_trace_pc(RzDebug *dbg, ut64 pc);
|
|||
RZ_API void rz_debug_trace_op(RzDebug *dbg, RzAnalysisOp *op);
|
||||
RZ_API RzDebugTracepoint *rz_debug_trace_get(RzDebug *dbg, ut64 addr);
|
||||
RZ_API void rz_debug_trace_print(RzDebug *dbg, RzCmdStateOutput *state, ut64 offset);
|
||||
RZ_API RZ_OWN RzList /*<RzListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset);
|
||||
RZ_API RZ_OWN RzList /*<RzDbgListInfo *>*/ *rz_debug_traces_info(RzDebug *dbg, ut64 offset);
|
||||
RZ_API void rz_debug_traces_ascii(RzDebug *dbg, ut64 offset);
|
||||
RZ_API RzDebugTracepoint *rz_debug_trace_add(RzDebug *dbg, ut64 addr, int size);
|
||||
RZ_API RzDebugTrace *rz_debug_trace_new(void);
|
||||
|
|
@ -607,6 +615,9 @@ RZ_API bool rz_debug_goto_cnum(RzDebug *dbg, ut32 cnum);
|
|||
RZ_API int rz_debug_step_cnum(RzDebug *dbg, int steps);
|
||||
RZ_API bool rz_debug_continue_back(RzDebug *dbg);
|
||||
|
||||
RZ_API RZ_OWN RzDbgListInfo *rz_debug_listinfo_new(RZ_NULLABLE const char *name, RzInterval pitv, RzInterval vitv, int perm, RZ_NULLABLE const char *extra);
|
||||
RZ_API void rz_debug_listinfo_free(RZ_NULLABLE RzDbgListInfo *info);
|
||||
|
||||
/* serialize */
|
||||
RZ_API void rz_serialize_debug_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzDebug *dbg);
|
||||
RZ_API bool rz_serialize_debug_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzDebug *dbg, RZ_NULLABLE RzSerializeResultInfo *res);
|
||||
|
|
|
|||
|
|
@ -7,88 +7,89 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
RzListComparator cmp;
|
||||
typedef enum {
|
||||
RZ_TABLE_ALIGN_LEFT = 0,
|
||||
RZ_TABLE_ALIGN_RIGHT,
|
||||
RZ_TABLE_ALIGN_CENTER,
|
||||
// size
|
||||
RZ_TABLE_ALIGN_ENUM_MAX,
|
||||
} RzTableAlign;
|
||||
|
||||
typedef enum {
|
||||
RZ_TABLE_COLUMN_TYPE_STRING = 0,
|
||||
RZ_TABLE_COLUMN_TYPE_NUMBER,
|
||||
RZ_TABLE_COLUMN_TYPE_BOOL,
|
||||
// size
|
||||
RZ_TABLE_COLUMN_TYPE_ENUM_MAX,
|
||||
} RzTableColumnType;
|
||||
|
||||
typedef int (*RzTableColumnTypeComparator)(const void *a, const void *b);
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
RzTableColumnType *type;
|
||||
int align; // left, right, center
|
||||
int width; // computed
|
||||
int maxWidth;
|
||||
bool forceUppercase;
|
||||
int total;
|
||||
char *name; ///< Column name
|
||||
RzTableColumnType type; ///< Inferred type of the data
|
||||
RzTableColumnTypeComparator type_cmp; ///< Column comparator used for sorting
|
||||
RzTableAlign align; ///< Column alignment left, right, center
|
||||
int width; ///< Computed column width
|
||||
int total; ///< Sum of the rows associated to this column.
|
||||
} RzTableColumn;
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
RzInterval pitv;
|
||||
RzInterval vitv;
|
||||
int perm;
|
||||
char *extra;
|
||||
} RzListInfo;
|
||||
|
||||
enum {
|
||||
RZ_TABLE_ALIGN_LEFT,
|
||||
RZ_TABLE_ALIGN_RIGHT,
|
||||
RZ_TABLE_ALIGN_CENTER
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
RzPVector /*<char *>*/ *items;
|
||||
} RzTableRow;
|
||||
|
||||
typedef void (*RzTableSelector)(RzTableRow *acc, RzTableRow *new_row, size_t nth);
|
||||
typedef const char *(*RzTableColorSelector)(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user);
|
||||
|
||||
typedef enum {
|
||||
RZ_TABLE_CHAR_MODE_ASCII = 0,
|
||||
RZ_TABLE_CHAR_MODE_UTF8,
|
||||
RZ_TABLE_CHAR_MODE_UTF8_CURVY,
|
||||
// size
|
||||
RZ_TABLE_CHAR_MODE_ENUM_MAX,
|
||||
} RzTableCharMode;
|
||||
|
||||
typedef struct {
|
||||
RzVector /*<RzTableRow>*/ *rows;
|
||||
RzVector /*<RzTableColumn>*/ *cols;
|
||||
int totalCols;
|
||||
bool showHeader;
|
||||
bool showFancy;
|
||||
bool showJSON;
|
||||
bool showCSV;
|
||||
bool showSum;
|
||||
bool adjustedCols;
|
||||
void *cons;
|
||||
RzVector /*<RzTableRow>*/ *rows; ///< Rows data
|
||||
RzVector /*<RzTableColumn>*/ *cols; ///< Columns data
|
||||
size_t totalCols; ///< Total number of columns
|
||||
bool showHeader; ///< When true, upon call of rz_table_tostring, it will show the header
|
||||
bool showFancy; ///< When true, upon call of rz_table_tostring, it will use the fancy table output
|
||||
bool showJSON; ///< When true, upon call of rz_table_tostring, it will return a json structure
|
||||
bool showCSV; ///< When true, upon call of rz_table_tostring, it will return a csv structure
|
||||
bool showSum; ///< When true, upon call of rz_table_tostring, it will show the toal sum of each row
|
||||
RzTableCharMode char_mode; ///< Sets the charset type used for the string output
|
||||
RzTableColorSelector color; ///< It is used to retrieve a color palette to use in each column data.
|
||||
void *color_user; ///< Additional data that is passed via RzTableColorSelector()
|
||||
} RzTable;
|
||||
|
||||
typedef void (*RzTableSelector)(RzTableRow *acc, RzTableRow *new_row, int nth);
|
||||
|
||||
RZ_API RzListInfo *rz_listinfo_new(const char *name, RzInterval pitv, RzInterval vitv, int perm, const char *extra);
|
||||
RZ_API void rz_listinfo_free(RzListInfo *info);
|
||||
|
||||
RZ_API void rz_table_row_fini(RZ_NONNULL void *_row);
|
||||
RZ_API void rz_table_column_fini(RZ_NONNULL void *_col);
|
||||
RZ_API RzTableColumn *rz_table_column_clone(RzTableColumn *col);
|
||||
RZ_API RzTableColumnType *rz_table_type(const char *name);
|
||||
RZ_API RzTable *rz_table_new(void);
|
||||
RZ_API void rz_table_free(RzTable *t);
|
||||
RZ_API int rz_table_column_nth(RzTable *t, const char *name);
|
||||
RZ_API void rz_table_add_column(RzTable *t, RzTableColumnType *type, const char *name, int maxWidth);
|
||||
RZ_API void rz_table_set_columnsf(RzTable *t, const char *fmt, ...);
|
||||
RZ_API void rz_table_set_vcolumnsf(RzTable *t, const char *fmt, va_list ap);
|
||||
RZ_API RzTableRow *rz_table_row_new(RzPVector /*<char *>*/ *items);
|
||||
RZ_API void rz_table_add_row(RZ_NONNULL RzTable *t, const char *name, ...);
|
||||
RZ_API void rz_table_add_vrowf(RZ_NONNULL RzTable *t, const char *fmt, va_list ap);
|
||||
RZ_API void rz_table_add_rowf(RzTable *t, const char *fmt, ...);
|
||||
RZ_API void rz_table_add_row_columnsf(RzTable *t, const char *fmt, ...);
|
||||
RZ_API void rz_table_add_row_vec(RZ_NONNULL RzTable *t, RZ_NONNULL RzPVector /*<char *>*/ *items);
|
||||
RZ_API RZ_OWN RzTable *rz_table_new(void);
|
||||
RZ_API void rz_table_free(RZ_NULLABLE RzTable *t);
|
||||
RZ_API void rz_table_add_column(RZ_NONNULL RzTable *t, const RzTableColumnType type, RZ_NONNULL const char *name);
|
||||
RZ_API void rz_table_set_columnsf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, ...);
|
||||
RZ_API void rz_table_set_vcolumnsf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, va_list ap);
|
||||
RZ_API void rz_table_add_row(RZ_NONNULL RzTable *t, RZ_NONNULL const char *name, ...);
|
||||
RZ_API void rz_table_add_vrowf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, va_list ap);
|
||||
RZ_API void rz_table_add_rowf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, ...);
|
||||
RZ_API void rz_table_add_row_columnsf(RZ_NONNULL RzTable *t, RZ_NONNULL const char *fmt, ...);
|
||||
RZ_API void rz_table_add_row_vec(RZ_NONNULL RzTable *t, RZ_NONNULL RZ_OWN RzPVector /*<char *>*/ *items);
|
||||
RZ_API RZ_OWN char *rz_table_tofancystring(RZ_NONNULL RzTable *t);
|
||||
RZ_API char *rz_table_tosimplestring(RzTable *t);
|
||||
RZ_API char *rz_table_tostring(RzTable *t);
|
||||
RZ_API char *rz_table_tocsv(RzTable *t);
|
||||
RZ_API RZ_OWN char *rz_table_tojson(RzTable *t);
|
||||
RZ_API void rz_table_filter(RzTable *t, int nth, int op, const char *un);
|
||||
RZ_API void rz_table_sort(RzTable *t, int nth, bool inc);
|
||||
RZ_API void rz_table_uniq(RzTable *t);
|
||||
RZ_API void rz_table_group(RzTable *t, int nth, RzTableSelector fcn);
|
||||
RZ_API bool rz_table_query(RzTable *t, const char *q);
|
||||
RZ_API void rz_table_hide_header(RzTable *t);
|
||||
RZ_API bool rz_table_align(RzTable *t, int nth, int align);
|
||||
RZ_API void rz_table_visual_list(RzTable *table, RzList /*<RzListInfo *>*/ *list, ut64 seek, ut64 len, int width, bool va);
|
||||
RZ_API RZ_OWN char *rz_table_tosimplestring(RZ_NONNULL RzTable *t);
|
||||
RZ_API RZ_OWN char *rz_table_tostring(RZ_NONNULL RzTable *t);
|
||||
RZ_API RZ_OWN char *rz_table_tocsv(RZ_NONNULL RzTable *t);
|
||||
RZ_API RZ_OWN char *rz_table_tojson(RZ_NONNULL RzTable *t);
|
||||
RZ_API void rz_table_sort(RZ_NONNULL RzTable *t, size_t nth, bool reverse);
|
||||
RZ_API void rz_table_sortlen(RZ_NONNULL RzTable *t, size_t nth, bool reverse);
|
||||
RZ_API void rz_table_uniq(RZ_NONNULL RzTable *t);
|
||||
RZ_API void rz_table_group(RZ_NONNULL RzTable *t, size_t nth, RZ_NULLABLE RzTableSelector selector);
|
||||
RZ_API bool rz_table_query(RZ_NONNULL RzTable *t, RZ_NULLABLE const char *q);
|
||||
RZ_API bool rz_table_align(RZ_NONNULL RzTable *t, size_t nth, RzTableAlign align);
|
||||
RZ_API RZ_OWN RzTable *rz_table_transpose(RZ_NONNULL RzTable *t);
|
||||
RZ_API void rz_table_columns(RzTable *t, RzList /*<char *>*/ *cols); // const char *name, ...);
|
||||
RZ_API void rz_table_columns_select(RZ_NONNULL RzTable *t, RZ_NONNULL RzList /*<char *>*/ *col_names);
|
||||
RZ_API void rz_table_show_header(RZ_NONNULL RzTable *t, bool show_header);
|
||||
RZ_API void rz_table_set_char_mode(RZ_NONNULL RzTable *t, RzTableCharMode mode);
|
||||
RZ_API void rz_table_set_color_selector(RZ_NONNULL RzTable *t, RZ_NULLABLE RzTableColorSelector color_cb, void *user);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -567,7 +567,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
|
|||
free(debugbackend);
|
||||
debugbackend = rz_str_dup(opt.arg);
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, r);
|
||||
if (!strcmp(opt.arg, "?")) {
|
||||
rz_core_debug_plugins_print(r, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
|
|
@ -781,7 +781,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
|
|||
}
|
||||
run_commands(r, NULL, prefiles, false, do_analysis);
|
||||
run_commands(r, cmds, files, quiet, do_analysis);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, r);
|
||||
rz_core_io_plugins_print(r->io, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
|
|||
|
|
@ -646,7 +646,7 @@ RZ_API int rz_main_rz_asm(int argc, const char *argv[]) {
|
|||
core->rasm = as->a;
|
||||
core->analysis = as->analysis;
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, as->json ? RZ_OUTPUT_MODE_JSON : RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&state, as->json ? RZ_OUTPUT_MODE_JSON : RZ_OUTPUT_MODE_STANDARD, core);
|
||||
if (opt.argv[opt.ind]) {
|
||||
rz_core_asm_cpu_plugin_print(core, &state, opt.argv[opt.ind]);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ static bool add_footer(RzCmdStateOutput *main_state, RzCmdStateOutput *state) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode mode, const char *header) {
|
||||
static RzCmdStateOutput *add_header(RzCmdStateOutput *main_state, RzOutputMode mode, const char *header, RzCore *core) {
|
||||
RzCmdStateOutput *state = RZ_NEW(RzCmdStateOutput);
|
||||
rz_cmd_state_output_init(state, mode);
|
||||
rz_cmd_state_output_init(state, mode, core);
|
||||
if (mode == RZ_OUTPUT_MODE_TABLE || mode == RZ_OUTPUT_MODE_STANDARD) {
|
||||
rz_cons_printf("[%c%s]\n", toupper(header[0]), header + 1);
|
||||
} else if (mode == RZ_OUTPUT_MODE_JSON) {
|
||||
|
|
@ -621,12 +621,12 @@ static void __listPlugins(RzBin *bin, const char *plugin_name, PJ *pj, int rad)
|
|||
RzCmdStateOutput state = { 0 };
|
||||
if (rad == RZ_MODE_JSON) {
|
||||
format = 'j';
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL);
|
||||
} else if (rad) {
|
||||
format = 'q';
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, NULL);
|
||||
} else {
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD);
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, NULL);
|
||||
}
|
||||
bin->cb_printf = (PrintfCallback)printf;
|
||||
if (plugin_name) {
|
||||
|
|
@ -1251,7 +1251,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
#define ismodejson (out_mode == RZ_MODE_JSON && actions > 0)
|
||||
#define run_action(n, x, y) \
|
||||
if (action & (x)) { \
|
||||
RzCmdStateOutput *st = add_header(&state, mode, n); \
|
||||
RzCmdStateOutput *st = add_header(&state, mode, n, &core); \
|
||||
y(&core, st); \
|
||||
add_footer(&state, st); \
|
||||
}
|
||||
|
|
@ -1272,7 +1272,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
|
||||
RzCmdStateOutput state;
|
||||
RzOutputMode mode = rad2outputmode(out_mode);
|
||||
if (!rz_cmd_state_output_init(&state, mode)) {
|
||||
if (!rz_cmd_state_output_init(&state, mode, &core)) {
|
||||
result = 1;
|
||||
goto chksum_err;
|
||||
}
|
||||
|
|
@ -1280,7 +1280,7 @@ RZ_API int rz_main_rz_bin(int argc, const char **argv) {
|
|||
|
||||
// List fatmach0 sub-binaries, etc
|
||||
if (action & RZ_BIN_REQ_LISTARCHS || (arch && bits && !rz_bin_select(bin, arch, bits, machine, NULL))) {
|
||||
RzCmdStateOutput *st = add_header(&state, mode == RZ_OUTPUT_MODE_STANDARD ? RZ_OUTPUT_MODE_TABLE : mode, "archs");
|
||||
RzCmdStateOutput *st = add_header(&state, mode == RZ_OUTPUT_MODE_STANDARD ? RZ_OUTPUT_MODE_TABLE : mode, "archs", &core);
|
||||
rz_core_bin_archs_print(bin, st);
|
||||
add_footer(&state, st);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ typedef struct diff_context_t {
|
|||
const char *input_b;
|
||||
const char *file_a;
|
||||
const char *file_b;
|
||||
const char *theme_name;
|
||||
DiffScreen screen;
|
||||
RzList /*<char *>*/ *evars;
|
||||
} DiffContext;
|
||||
|
|
@ -215,6 +216,7 @@ static void rz_diff_show_help(bool usage_only) {
|
|||
"-q", "", "Quiet output",
|
||||
"-V", "", "Show version information",
|
||||
"-v", "", "Be more verbose (stderr output)",
|
||||
"-K", "theme", "Set a give color theme (see rizin 'eco' command)",
|
||||
"-e", "k=v", "Set an evaluable config variable",
|
||||
"-A", "", "Compare virtual and physical addresses",
|
||||
"-B", "", "Run 'aaa' when loading the bin",
|
||||
|
|
@ -277,7 +279,7 @@ static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ct
|
|||
|
||||
RzGetopt opt;
|
||||
int c;
|
||||
rz_getopt_init(&opt, argc, argv, "hHjqvViABCTa:b:e:d:t:0:1:S:");
|
||||
rz_getopt_init(&opt, argc, argv, "hHjqvViABCTa:b:K:e:d:t:0:1:S:");
|
||||
while ((c = rz_getopt_next(&opt)) != -1) {
|
||||
switch (c) {
|
||||
case '0': rz_diff_ctx_set_def(ctx, input_a, NULL, opt.arg); break;
|
||||
|
|
@ -299,6 +301,7 @@ static void rz_diff_parse_arguments(int argc, const char **argv, DiffContext *ct
|
|||
case 'S': rz_diff_set_def(screen, NULL, opt.arg); break;
|
||||
case 'H': rz_diff_ctx_set_opt(ctx, DIFF_OPT_HEX_VISUAL); break;
|
||||
case 'e': rz_diff_ctx_add_evar(ctx, opt.arg); break;
|
||||
case 'K': rz_diff_set_def(ctx->theme_name, NULL, opt.arg); break;
|
||||
default:
|
||||
rz_diff_error_opt(ctx, DIFF_OPT_ERROR, "unknown flag '%c'\n", c);
|
||||
}
|
||||
|
|
@ -1992,7 +1995,7 @@ static void diff_similarity_as_json(RzAnalysisFunction *fcn_a, RzAnalysisFunctio
|
|||
pj_end(pj); // } -- match object end
|
||||
}
|
||||
|
||||
static void diff_similarity_as_table(RzAnalysisFunction *fcn_a, RzAnalysisFunction *fcn_b, double similarity, bool color, bool no_name, RzTable *table) {
|
||||
static void diff_similarity_as_table(RzAnalysisFunction *fcn_a, RzAnalysisFunction *fcn_b, double similarity, bool no_name, RzTable *table) {
|
||||
char tmp[128];
|
||||
const char *type_s = NULL;
|
||||
const char *type_n = NULL;
|
||||
|
|
@ -2003,18 +2006,18 @@ static void diff_similarity_as_table(RzAnalysisFunction *fcn_a, RzAnalysisFuncti
|
|||
if (similarity > 0.0 && fcn_a && fcn_b) {
|
||||
type_n = tmp;
|
||||
if (similarity >= 1.0) {
|
||||
rz_strf(tmp, color ? Color_BGREEN "%.6f" Color_RESET : "%.6f", similarity);
|
||||
type_s = color ? Color_BGREEN "COMPLETE" Color_RESET : "COMPLETE";
|
||||
rz_strf(tmp, "%.6f", similarity);
|
||||
type_s = "COMPLETE";
|
||||
} else if (similarity >= RZ_ANALYSIS_SIMILARITY_THRESHOLD) {
|
||||
rz_strf(tmp, color ? Color_BYELLOW "%.6f" Color_RESET : "%.6f", similarity);
|
||||
type_s = color ? Color_BYELLOW "PARTIAL " Color_RESET : "PARTIAL ";
|
||||
rz_strf(tmp, "%.6f", similarity);
|
||||
type_s = "PARTIAL";
|
||||
} else {
|
||||
rz_strf(tmp, color ? Color_BRED "%.4f" Color_RESET : "%.4f", similarity);
|
||||
type_s = color ? Color_BRED "UNLIKE " Color_RESET : "UNLIKE ";
|
||||
rz_strf(tmp, "%.4f", similarity);
|
||||
type_s = "UNLIKE";
|
||||
}
|
||||
} else {
|
||||
type_n = color ? Color_BRED "0.000000" Color_RESET : "0.000000";
|
||||
type_s = color ? Color_BRED "UNLIKE " Color_RESET : "UNLIKE ";
|
||||
type_n = "0.000000";
|
||||
type_s = "UNLIKE";
|
||||
}
|
||||
|
||||
if (no_name) {
|
||||
|
|
@ -2044,6 +2047,29 @@ static int comparePairFunctions(const RzAnalysisMatchPair *ma, const RzAnalysisM
|
|||
return (a && b && a->addr && b->addr ? (a->addr > b->addr) - (a->addr < b->addr) : 0);
|
||||
}
|
||||
|
||||
static const char *diff_table_color_selector(const char *value, const char *column, const size_t column_n, const RzTableColumnType type, void *user) {
|
||||
if (!column || !value) {
|
||||
return NULL;
|
||||
}
|
||||
const RzConsContext *ctx = (const RzConsContext *)user;
|
||||
if (RZ_STR_EQ(column, "type")) {
|
||||
if (RZ_STR_EQ(value, "COMPLETE")) {
|
||||
return ctx->pal.diff_match;
|
||||
} else if (RZ_STR_EQ(value, "PARTIAL")) {
|
||||
return ctx->pal.diff_unmatch;
|
||||
}
|
||||
return ctx->pal.diff_unknown;
|
||||
}
|
||||
if (RZ_STR_EQ(column, "similarity")) {
|
||||
return ctx->pal.cjmp;
|
||||
} else if (rz_str_startswith(column, "size")) {
|
||||
return ctx->pal.num;
|
||||
} else if (rz_str_startswith(column, "addr")) {
|
||||
return ctx->pal.offset;
|
||||
}
|
||||
return ctx->pal.label;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs function matching and shows the result in a table.
|
||||
*
|
||||
|
|
@ -2140,7 +2166,7 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
|
|||
if (mode == DIFF_MODE_JSON) {
|
||||
diff_similarity_as_json(fcn_a, fcn_b, pair->similarity, pj);
|
||||
} else {
|
||||
diff_similarity_as_table(fcn_a, fcn_b, pair->similarity, color, no_name, table);
|
||||
diff_similarity_as_table(fcn_a, fcn_b, pair->similarity, no_name, table);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2152,7 +2178,7 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
|
|||
if (mode == DIFF_MODE_JSON) {
|
||||
diff_similarity_as_json(fcn_a, NULL, 0.0, pj);
|
||||
} else {
|
||||
diff_similarity_as_table(fcn_a, NULL, 0.0, color, no_name, table);
|
||||
diff_similarity_as_table(fcn_a, NULL, 0.0, no_name, table);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2164,7 +2190,18 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
|
|||
if (mode == DIFF_MODE_JSON) {
|
||||
diff_similarity_as_json(NULL, fcn_b, 0.0, pj);
|
||||
} else {
|
||||
diff_similarity_as_table(NULL, fcn_b, 0.0, color, no_name, table);
|
||||
diff_similarity_as_table(NULL, fcn_b, 0.0, no_name, table);
|
||||
}
|
||||
}
|
||||
|
||||
if (table) {
|
||||
if (color) {
|
||||
rz_table_set_color_selector(table, diff_table_color_selector, core_a->cons->context);
|
||||
}
|
||||
if (core_a->cons->use_utf8_curvy) {
|
||||
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8_CURVY);
|
||||
} else if (core_a->cons->use_utf8) {
|
||||
rz_table_set_char_mode(table, RZ_TABLE_CHAR_MODE_UTF8);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2181,7 +2218,7 @@ static void core_diff_show(RzCore *core_a, RzCore *core_b, const char *addr_a, D
|
|||
break;
|
||||
default: // DIFF_MODE_QUIET
|
||||
rz_table_align(table, 0, RZ_TABLE_ALIGN_RIGHT);
|
||||
rz_table_hide_header(table);
|
||||
rz_table_show_header(table, false);
|
||||
output = rz_table_tosimplestring(table);
|
||||
rz_cons_printf("%s", output);
|
||||
break;
|
||||
|
|
@ -2289,6 +2326,9 @@ static bool rz_diff_graphs_files(DiffContext *ctx) {
|
|||
if (ctx->verbose) {
|
||||
fprintf(stderr, "rz-diff: start diffing.\n");
|
||||
}
|
||||
if (ctx->colors) {
|
||||
rz_core_theme_load(a->core, ctx->theme_name ? ctx->theme_name : "default");
|
||||
}
|
||||
core_diff_show(a->core, b->core, ctx->input_a, ctx->mode, ctx->verbose);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ RZ_API int rz_str_rwx(const char *str) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// Returns the string representation of the permission of the inputted integer.
|
||||
// Returns the string representation of the permission of the input integer.
|
||||
RZ_API const char *rz_str_rwx_i(int rwx) {
|
||||
if (rwx < 0 || rwx >= RZ_ARRAY_SIZE(rwxstr)) {
|
||||
rwx = 0;
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -420,6 +420,9 @@ CMDS=<<EOF
|
|||
obl~?
|
||||
i
|
||||
oc =
|
||||
# oc resets RzCore completely
|
||||
e scr.utf8=false
|
||||
e scr.color=0
|
||||
echo --
|
||||
obl~?
|
||||
i
|
||||
|
|
|
|||
|
|
@ -462,45 +462,46 @@ Environment:
|
|||
RZ_NOPLUGINS: # do not load plugins
|
||||
|
||||
[36mUsage: [0mrz-diff [options] <file0> <file1>
|
||||
[32m-a[0m[33m arch [0m[0mSpecify architecture plugin to use (x86, arm, ..)
|
||||
[32m-b[0m[33m bits [0m[0mSpecify register size for arch (16 (thumb), 32, 64, ..)
|
||||
[32m-d[0m[33m algo [0m[0mCompute edit distance based on the chosen algorithm:
|
||||
[32m[0m [0m myers | Eugene W. Myers' O(ND) algorithm (no substitution)
|
||||
[32m[0m [0m leven | Levenshtein O(N^2) algorithm (with substitution)
|
||||
[32m[0m [0m ssdeep | Context triggered piecewise hashing comparison
|
||||
[32m-i[0m [0mUse command line arguments instead of files (only for -d)
|
||||
[32m-H[0m [0mHexadecimal visual mode
|
||||
[32m-h[0m [0mShow this help
|
||||
[32m-j[0m [0mJSON output
|
||||
[32m-q[0m [0mQuiet output
|
||||
[32m-V[0m [0mShow version information
|
||||
[32m-v[0m [0mBe more verbose (stderr output)
|
||||
[32m-e[0m[33m k=v [0m [0mSet an evaluable config variable
|
||||
[32m-A[0m [0mCompare virtual and physical addresses
|
||||
[32m-B[0m [0mRun 'aaa' when loading the bin
|
||||
[32m-C[0m [0mDisable colors
|
||||
[32m-T[0m [0mShow timestamp information
|
||||
[32m-S[0m[33m WxH [0m [0mSet the width and height of the terminal for visual mode
|
||||
[32m-0[0m[33m cmd [0m [0mInput for file0 when option -t 'commands' is given.
|
||||
[32m[0m [0mThe same value will be set for file1, if -1 is not set.
|
||||
[32m-1[0m[33m cmd [0m [0mInput for file1 when option -t 'commands' is given.
|
||||
[32m-t[0m[33m type [0m[0mCompute the difference between two files based on its type:
|
||||
[32m[0m [0m bytes | compare raw bytes in the files (only for small files)
|
||||
[32m[0m [0m lines | compare text files
|
||||
[32m[0m [0m functions | compare functions found in the files
|
||||
[32m[0m [0m | optional -0 <fcn name|offset> to compare only one function
|
||||
[32m[0m [0m classes | compare classes found in the files
|
||||
[32m[0m [0m command | compare command output returned when executed in both files
|
||||
[32m[0m [0m | require -0 <cmd> and -1 <cmd> is optional
|
||||
[32m[0m [0m entries | compare entries found in the files
|
||||
[32m[0m [0m fields | compare fields found in the files
|
||||
[32m[0m [0m graphs | compare 2 functions and outputs in graphviz/dot format
|
||||
[32m[0m [0m | require -0 <fcn name|offset> and -1 <fcn name|offset> is optional
|
||||
[32m[0m [0m imports | compare imports found in the files
|
||||
[32m[0m [0m libraries | compare libraries found in the files
|
||||
[32m[0m [0m sections | compare sections found in the files
|
||||
[32m[0m [0m strings | compare strings found in the files
|
||||
[32m[0m [0m symbols | compare symbols found in the files
|
||||
[32m-a[0m[33m arch [0m [0mSpecify architecture plugin to use (x86, arm, ..)
|
||||
[32m-b[0m[33m bits [0m [0mSpecify register size for arch (16 (thumb), 32, 64, ..)
|
||||
[32m-d[0m[33m algo [0m [0mCompute edit distance based on the chosen algorithm:
|
||||
[32m[0m [0m myers | Eugene W. Myers' O(ND) algorithm (no substitution)
|
||||
[32m[0m [0m leven | Levenshtein O(N^2) algorithm (with substitution)
|
||||
[32m[0m [0m ssdeep | Context triggered piecewise hashing comparison
|
||||
[32m-i[0m [0mUse command line arguments instead of files (only for -d)
|
||||
[32m-H[0m [0mHexadecimal visual mode
|
||||
[32m-h[0m [0mShow this help
|
||||
[32m-j[0m [0mJSON output
|
||||
[32m-q[0m [0mQuiet output
|
||||
[32m-V[0m [0mShow version information
|
||||
[32m-v[0m [0mBe more verbose (stderr output)
|
||||
[32m-K[0m[33m theme [0m[0mSet a give color theme (see rizin 'eco' command)
|
||||
[32m-e[0m[33m k=v [0m [0mSet an evaluable config variable
|
||||
[32m-A[0m [0mCompare virtual and physical addresses
|
||||
[32m-B[0m [0mRun 'aaa' when loading the bin
|
||||
[32m-C[0m [0mDisable colors
|
||||
[32m-T[0m [0mShow timestamp information
|
||||
[32m-S[0m[33m WxH [0m [0mSet the width and height of the terminal for visual mode
|
||||
[32m-0[0m[33m cmd [0m [0mInput for file0 when option -t 'commands' is given.
|
||||
[32m[0m [0mThe same value will be set for file1, if -1 is not set.
|
||||
[32m-1[0m[33m cmd [0m [0mInput for file1 when option -t 'commands' is given.
|
||||
[32m-t[0m[33m type [0m [0mCompute the difference between two files based on its type:
|
||||
[32m[0m [0m bytes | compare raw bytes in the files (only for small files)
|
||||
[32m[0m [0m lines | compare text files
|
||||
[32m[0m [0m functions | compare functions found in the files
|
||||
[32m[0m [0m | optional -0 <fcn name|offset> to compare only one function
|
||||
[32m[0m [0m classes | compare classes found in the files
|
||||
[32m[0m [0m command | compare command output returned when executed in both files
|
||||
[32m[0m [0m | require -0 <cmd> and -1 <cmd> is optional
|
||||
[32m[0m [0m entries | compare entries found in the files
|
||||
[32m[0m [0m fields | compare fields found in the files
|
||||
[32m[0m [0m graphs | compare 2 functions and outputs in graphviz/dot format
|
||||
[32m[0m [0m | require -0 <fcn name|offset> and -1 <fcn name|offset> is optional
|
||||
[32m[0m [0m imports | compare imports found in the files
|
||||
[32m[0m [0m libraries | compare libraries found in the files
|
||||
[32m[0m [0m sections | compare sections found in the files
|
||||
[32m[0m [0m strings | compare strings found in the files
|
||||
[32m[0m [0m symbols | compare symbols found in the files
|
||||
palette colors can be changed by adding the following lines
|
||||
inside the $HOME/.rizinrc file
|
||||
ec diff.unknown blue | offset color
|
||||
|
|
@ -527,7 +528,7 @@ ec diff.unmatch red | mismatch color
|
|||
[32m-S[0m[33m str [0m [0mSearch for a symbol in symbol table.
|
||||
[32m-t[0m[33m to [0m [0mStop search at address 'to'
|
||||
[32m-q[0m [0mQuiet - do not show headings (filenames) above matching contents (default for searching a single file)
|
||||
[32m-v[0m [0mShow version information
|
||||
[32m-v[0m [0mShow version information
|
||||
[32m-V[0m [0mVerbose: prints each file scanned
|
||||
[32m-x[0m[33m hex [0m [0mSearch for hexpair string (909090) (can be used multiple times)
|
||||
[32m-X[0m [0mShow hexdump of search results
|
||||
|
|
|
|||
|
|
@ -945,7 +945,7 @@ RUN
|
|||
|
||||
NAME=rz-diff functions comparison
|
||||
FILE==
|
||||
CMDS=!rz-diff -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions bins/other/rz-diff/true bins/other/rz-diff/false
|
||||
CMDS=!rz-diff -e 'scr.utf8=false' -e 'scr.utf8.curvy=false' -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions bins/other/rz-diff/true bins/other/rz-diff/false
|
||||
EXPECT=<<EOF
|
||||
.-------------------------------------------------------------------------------------------------.
|
||||
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
|
||||
|
|
@ -964,38 +964,38 @@ RUN
|
|||
|
||||
NAME=rz-diff functions comparison (colored)
|
||||
FILE==
|
||||
CMDS=!rz-diff -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -t functions bins/other/rz-diff/true bins/other/rz-diff/false
|
||||
CMDS=!rz-diff -K ayu -e 'scr.utf8=false' -e 'scr.utf8.curvy=false' -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -t functions bins/other/rz-diff/true bins/other/rz-diff/false
|
||||
EXPECT=<<EOF
|
||||
.-------------------------------------------------------------------------------------------------.
|
||||
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
|
||||
)-------------------------------------------------------------------------------------------------(
|
||||
| test.00401460 | 41 | 0x00401460 | [92mCOMPLETE[0m | [92m1.000000[0m | 0x00401470 | 41 | test.00401470 |
|
||||
| test.00401990 | 137 | 0x00401990 | [93mPARTIAL [0m | [93m0.985401[0m | 0x004019a0 | 137 | test.004019a0 |
|
||||
| test.00401a20 | 162 | 0x00401a20 | [92mCOMPLETE[0m | [92m1.000000[0m | 0x00401a30 | 162 | test.00401a30 |
|
||||
| test.00401ae0 | 228 | 0x00401ae0 | [93mPARTIAL [0m | [93m0.964912[0m | 0x00401af0 | 228 | test.00401af0 |
|
||||
| test.00401be0 | 2728 | 0x00401be0 | [93mPARTIAL [0m | [93m0.991569[0m | 0x00401bf0 | 2728 | test.00401bf0 |
|
||||
| test.00402730 | 425 | 0x00402730 | [93mPARTIAL [0m | [93m0.971765[0m | 0x00402740 | 425 | test.00402740 |
|
||||
| test.004029a0 | 50 | 0x004029a0 | [93mPARTIAL [0m | [93m0.980000[0m | 0x004029b0 | 50 | test.004029b0 |
|
||||
| test.00402e20 | 204 | 0x00402e20 | [93mPARTIAL [0m | [93m0.960784[0m | 0x00402e30 | 204 | test.00402e30 |
|
||||
| [36mtest.00401460 [0m|[31m 41[0m |[31m 0x00401460[0m | [90mCOMPLETE [0m| [33m1.000000 [0m|[31m 0x00401470[0m |[31m 41[0m | [36mtest.00401470 [0m|
|
||||
| [36mtest.00401990 [0m|[31m 137[0m |[31m 0x00401990[0m | [33mPARTIAL [0m| [33m0.985401 [0m|[31m 0x004019a0[0m |[31m 137[0m | [36mtest.004019a0 [0m|
|
||||
| [36mtest.00401a20 [0m|[31m 162[0m |[31m 0x00401a20[0m | [90mCOMPLETE [0m| [33m1.000000 [0m|[31m 0x00401a30[0m |[31m 162[0m | [36mtest.00401a30 [0m|
|
||||
| [36mtest.00401ae0 [0m|[31m 228[0m |[31m 0x00401ae0[0m | [33mPARTIAL [0m| [33m0.964912 [0m|[31m 0x00401af0[0m |[31m 228[0m | [36mtest.00401af0 [0m|
|
||||
| [36mtest.00401be0 [0m|[31m 2728[0m |[31m 0x00401be0[0m | [33mPARTIAL [0m| [33m0.991569 [0m|[31m 0x00401bf0[0m |[31m 2728[0m | [36mtest.00401bf0 [0m|
|
||||
| [36mtest.00402730 [0m|[31m 425[0m |[31m 0x00402730[0m | [33mPARTIAL [0m| [33m0.971765 [0m|[31m 0x00402740[0m |[31m 425[0m | [36mtest.00402740 [0m|
|
||||
| [36mtest.004029a0 [0m|[31m 50[0m |[31m 0x004029a0[0m | [33mPARTIAL [0m| [33m0.980000 [0m|[31m 0x004029b0[0m |[31m 50[0m | [36mtest.004029b0 [0m|
|
||||
| [36mtest.00402e20 [0m|[31m 204[0m |[31m 0x00402e20[0m | [33mPARTIAL [0m| [33m0.960784 [0m|[31m 0x00402e30[0m |[31m 204[0m | [36mtest.00402e30 [0m|
|
||||
`-------------------------------------------------------------------------------------------------'
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=rz-diff functions comparison against only one function
|
||||
FILE==
|
||||
CMDS=!rz-diff -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions -0 test.00401ae0 bins/other/rz-diff/true bins/other/rz-diff/false
|
||||
CMDS=!rz-diff -e 'scr.utf8=false' -e 'scr.utf8.curvy=false' -e 'analysis.fcnprefix=test' -e 'analysis.limits=true' -e 'analysis.from=0x401460' -e 'analysis.to=0x4033d0' -C -t functions -0 test.00401ae0 bins/other/rz-diff/true bins/other/rz-diff/false
|
||||
EXPECT=<<EOF
|
||||
.-------------------------------------------------------------------------------------------------.
|
||||
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
|
||||
)-------------------------------------------------------------------------------------------------(
|
||||
| test.00401470 | 41 | 0x00401470 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.004019a0 | 137 | 0x004019a0 | UNLIKE | 0.1228 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401a30 | 162 | 0x00401a30 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401af0 | 228 | 0x00401af0 | PARTIAL | 0.964912 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401bf0 | 2728 | 0x00401bf0 | UNLIKE | 0.0433 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00402740 | 425 | 0x00402740 | UNLIKE | 0.1106 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.004029b0 | 50 | 0x004029b0 | UNLIKE | 0.0702 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00402e30 | 204 | 0x00402e30 | UNLIKE | 0.1140 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
`-------------------------------------------------------------------------------------------------'
|
||||
.------------------------------------------------------------------------------------------------.
|
||||
| name0 | size0 | addr0 | type | similarity | addr1 | size1 | name1 |
|
||||
)------------------------------------------------------------------------------------------------(
|
||||
| test.00401470 | 41 | 0x00401470 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.004019a0 | 137 | 0x004019a0 | UNLIKE | 0.1228 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401a30 | 162 | 0x00401a30 | UNLIKE | 0.0746 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401af0 | 228 | 0x00401af0 | PARTIAL | 0.964912 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00401bf0 | 2728 | 0x00401bf0 | UNLIKE | 0.0433 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00402740 | 425 | 0x00402740 | UNLIKE | 0.1106 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.004029b0 | 50 | 0x004029b0 | UNLIKE | 0.0702 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
| test.00402e30 | 204 | 0x00402e30 | UNLIKE | 0.1140 | 0x00401ae0 | 228 | test.00401ae0 |
|
||||
`------------------------------------------------------------------------------------------------'
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
|
|
@ -1089,7 +1089,7 @@ static void func2_output(RzCmdStateOutput *state) {
|
|||
|
||||
bool test_state_output_concat_standard(void) {
|
||||
RzCmdStateOutput state;
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_STANDARD, NULL), "state is initialized correctly");
|
||||
|
||||
rz_cons_flush();
|
||||
rz_cons_push();
|
||||
|
|
@ -1118,11 +1118,11 @@ bool test_state_output_concat_table(void) {
|
|||
|
||||
rz_cons_flush();
|
||||
rz_cons_push();
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE, NULL), "state is initialized correctly");
|
||||
func1_output(&state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE, NULL), "state is initialized correctly");
|
||||
func2_output(&state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
@ -1145,11 +1145,11 @@ bool test_state_output_concat_mix(void) {
|
|||
|
||||
rz_cons_flush();
|
||||
rz_cons_push();
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_TABLE, NULL), "state is initialized correctly");
|
||||
func1_output(&state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET, NULL), "state is initialized correctly");
|
||||
func2_output(&state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
@ -1170,11 +1170,11 @@ bool test_state_output_concat_json(void) {
|
|||
|
||||
rz_cons_flush();
|
||||
rz_cons_push();
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL), "state is initialized correctly");
|
||||
func1_output(&state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL), "state is initialized correctly");
|
||||
func2_output(&state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
|
|
@ -1186,7 +1186,7 @@ bool test_state_output_concat_json(void) {
|
|||
|
||||
rz_cons_flush();
|
||||
rz_cons_push();
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON), "state is initialized correctly");
|
||||
mu_assert_true(rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_JSON, NULL), "state is initialized correctly");
|
||||
pj_o(state.d.pj);
|
||||
pj_k(state.d.pj, "first");
|
||||
func1_output(&state);
|
||||
|
|
|
|||
|
|
@ -11,11 +11,8 @@ bool test_rz_table(void) {
|
|||
RzTable *t = rz_table_new();
|
||||
|
||||
// rz_table_fromcsv (t, csv);
|
||||
RzTableColumnType *typeString = rz_table_type("string");
|
||||
RzTableColumnType *typeNumber = rz_table_type("number");
|
||||
|
||||
rz_table_add_column(t, typeString, "name", 0);
|
||||
rz_table_add_column(t, typeNumber, "address", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "name");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "address");
|
||||
|
||||
rz_table_add_row(t, "hello", "100", NULL);
|
||||
rz_table_add_row(t, "namings", "20000", NULL);
|
||||
|
|
@ -37,8 +34,8 @@ bool test_rz_table(void) {
|
|||
RzTable *__table_test_data1() {
|
||||
RzTable *t = rz_table_new();
|
||||
|
||||
rz_table_add_column(t, rz_table_type("string"), "ascii", 0);
|
||||
rz_table_add_column(t, rz_table_type("number"), "code", 0);
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_STRING, "ascii");
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "code");
|
||||
|
||||
rz_table_add_row(t, "a", "97", NULL);
|
||||
rz_table_add_row(t, "b", "98", NULL);
|
||||
|
|
@ -47,24 +44,6 @@ RzTable *__table_test_data1() {
|
|||
return t;
|
||||
}
|
||||
|
||||
bool test_rz_table_column_type(void) {
|
||||
RzTable *t = __table_test_data1();
|
||||
RzTableColumn *c = rz_vector_index_ptr(t->cols, 1);
|
||||
c->type = rz_table_type("NUMBER");
|
||||
rz_table_sort(t, 1, true);
|
||||
char *s = rz_table_tostring(t);
|
||||
mu_assert_streq(s,
|
||||
"ascii code \n"
|
||||
"-----------\n"
|
||||
"a 97\n"
|
||||
"b 98\n"
|
||||
"c 99\n",
|
||||
"not sorted by second column due to undefined type");
|
||||
free(s);
|
||||
rz_table_free(t);
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool test_rz_table_tostring(void) {
|
||||
RzTable *t = __table_test_data1();
|
||||
char buf[BUF_LENGTH];
|
||||
|
|
@ -156,29 +135,29 @@ bool test_rz_table_uniq(void) {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
static void simple_merge(RzTableRow *acc, RzTableRow *new_row, int nth) {
|
||||
static void simple_merge(RzTableRow *acc, RzTableRow *new_row, size_t nth) {
|
||||
RzPVector *lhs = acc->items;
|
||||
RzPVector *rhs = new_row->items;
|
||||
char *item_lhs;
|
||||
int cnt;
|
||||
|
||||
for (cnt = 0; cnt < rz_pvector_len(lhs) && cnt < rz_pvector_len(rhs); cnt++) {
|
||||
for (size_t cnt = 0; cnt < rz_pvector_len(lhs) && cnt < rz_pvector_len(rhs); cnt++) {
|
||||
if (cnt == nth) {
|
||||
continue;
|
||||
}
|
||||
|
||||
item_lhs = rz_pvector_at(lhs, cnt);
|
||||
|
||||
if (cnt != nth) {
|
||||
if (!strcmp(item_lhs, "a")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("a | e"));
|
||||
} else if (!strcmp(item_lhs, "b")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("b | f"));
|
||||
} else if (!strcmp(item_lhs, "c")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("c | h"));
|
||||
} else if (!strcmp(item_lhs, "d")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("d | g"));
|
||||
}
|
||||
if (!strcmp(item_lhs, "a")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("a | e"));
|
||||
} else if (!strcmp(item_lhs, "b")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("b | f"));
|
||||
} else if (!strcmp(item_lhs, "c")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("c | h"));
|
||||
} else if (!strcmp(item_lhs, "d")) {
|
||||
free(item_lhs);
|
||||
rz_pvector_set(lhs, cnt, rz_str_dup("d | g"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -243,13 +222,13 @@ bool test_rz_table_group(void) {
|
|||
mu_end;
|
||||
}
|
||||
|
||||
bool test_rz_table_columns() {
|
||||
bool test_rz_table_columns_select() {
|
||||
RzTable *t = NULL;
|
||||
#define CREATE_TABLE \
|
||||
rz_table_free(t); \
|
||||
t = rz_table_new(); \
|
||||
rz_table_add_column(t, rz_table_type("number"), "name", 0); \
|
||||
rz_table_add_column(t, rz_table_type("number"), "address", 0); \
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "name"); \
|
||||
rz_table_add_column(t, RZ_TABLE_COLUMN_TYPE_NUMBER, "address"); \
|
||||
rz_table_add_row(t, "hello", "100", NULL); \
|
||||
rz_table_add_row(t, "namings", "20000", NULL);
|
||||
|
||||
|
|
@ -263,18 +242,14 @@ bool test_rz_table_columns() {
|
|||
free(s);
|
||||
|
||||
RzList *newcols = rz_list_new();
|
||||
rz_table_columns(t, newcols);
|
||||
rz_table_columns_select(t, newcols);
|
||||
s = rz_table_tocsv(t);
|
||||
mu_assert_streq(s,
|
||||
"\n"
|
||||
"\n"
|
||||
"\n",
|
||||
"no cols");
|
||||
mu_assert_streq(s, "", "no cols");
|
||||
free(s);
|
||||
|
||||
CREATE_TABLE
|
||||
rz_list_push(newcols, "address");
|
||||
rz_table_columns(t, newcols);
|
||||
rz_table_columns_select(t, newcols);
|
||||
s = rz_table_tocsv(t);
|
||||
mu_assert_streq(s,
|
||||
"address\n"
|
||||
|
|
@ -285,7 +260,7 @@ bool test_rz_table_columns() {
|
|||
|
||||
CREATE_TABLE
|
||||
rz_list_push(newcols, "name");
|
||||
rz_table_columns(t, newcols);
|
||||
rz_table_columns_select(t, newcols);
|
||||
s = rz_table_tocsv(t);
|
||||
mu_assert_streq(s,
|
||||
"address,name\n"
|
||||
|
|
@ -297,7 +272,7 @@ bool test_rz_table_columns() {
|
|||
CREATE_TABLE
|
||||
rz_list_push(newcols, "name");
|
||||
rz_list_push(newcols, "address");
|
||||
rz_table_columns(t, newcols);
|
||||
rz_table_columns_select(t, newcols);
|
||||
s = rz_table_tocsv(t);
|
||||
mu_assert_streq(s,
|
||||
"address,name,name,address\n"
|
||||
|
|
@ -350,7 +325,7 @@ bool test_rz_table_add_row_columnsf() {
|
|||
|
||||
bool test_rz_table_query(void) {
|
||||
RzTable *t = __table_test_data1();
|
||||
bool qr = rz_table_query(t, "code/sort/dec");
|
||||
bool qr = rz_table_query(t, "code/sort/rev");
|
||||
mu_assert_true(qr, "table sorted decrementally");
|
||||
char *s = rz_table_tostring(t);
|
||||
mu_assert_streq(s,
|
||||
|
|
@ -361,7 +336,7 @@ bool test_rz_table_query(void) {
|
|||
"a 97\n",
|
||||
"sort table by number column");
|
||||
free(s);
|
||||
qr = rz_table_query(t, "code/sort/dec");
|
||||
qr = rz_table_query(t, "code/sort/rev");
|
||||
mu_assert_true(qr, "table sorted incrementally");
|
||||
qr = rz_table_query(t, "code/le/98");
|
||||
mu_assert_true(qr, "table filter by <=98");
|
||||
|
|
@ -410,12 +385,11 @@ bool test_rz_table_query(void) {
|
|||
|
||||
bool all_tests() {
|
||||
mu_run_test(test_rz_table);
|
||||
mu_run_test(test_rz_table_column_type);
|
||||
mu_run_test(test_rz_table_tostring);
|
||||
mu_run_test(test_rz_table_sort1);
|
||||
mu_run_test(test_rz_table_uniq);
|
||||
mu_run_test(test_rz_table_group);
|
||||
mu_run_test(test_rz_table_columns);
|
||||
mu_run_test(test_rz_table_columns_select);
|
||||
mu_run_test(test_rz_table_transpose);
|
||||
mu_run_test(test_rz_table_add_row_columnsf);
|
||||
mu_run_test(test_rz_table_query);
|
||||
|
|
|
|||
Loading…
Reference in a new issue