Implement 'cols' RTable.query to filter by column names ##print

* r_str_split_list() rewritten to support nth limit

r2 -qq -c 'aac;aflt size/gt/200,addr/cols/name/nbbs,nbbs/sort/inc' /bin/ls
This commit is contained in:
pancake 2019-08-28 22:34:16 +02:00 committed by radare
parent f5fba6fe55
commit a228c9297b
23 changed files with 87 additions and 62 deletions

View File

@ -25,8 +25,8 @@ R_API void r_anal_cc_set(RAnal *anal, const char *expr) {
char *end = strchr (args, ')');
if (end) {
*end++ = 0;
RList *retName = r_str_split_list (e, " ");
RList *ccArgs = r_str_split_list (args, ",");
RList *retName = r_str_split_list (e, " ", 0);
RList *ccArgs = r_str_split_list (args, ",", 0);
if (r_list_length (retName) == 2) {
const char *ret = r_list_get_n (retName, 0);
const char *name = r_list_get_n (retName, 1);

View File

@ -492,7 +492,7 @@ R_API RAnalMetaItem *r_meta_find_in(RAnal *a, ut64 at, int type, int where) {
if (!res) {
return NULL;
}
RList *list = r_str_split_list (res, ",");
RList *list = r_str_split_list (res, ",", 0);
RListIter *iter;
const char *meta;
r_list_foreach (list, iter, meta) {
@ -513,7 +513,7 @@ R_API RList *r_meta_find_list_in(RAnal *a, ut64 at, int type, int where) {
if (!res) {
return NULL;
}
RList *list = r_str_split_list (res, ",");
RList *list = r_str_split_list (res, ",", 0);
RList *out = r_list_new ();
if (!out) {
return NULL;

View File

@ -653,7 +653,7 @@ static RList *create_cache_bins(RBinFile *bf, RBuffer *cache_buf, cache_hdr_t *h
char *target_libs = NULL;
target_libs = r_sys_getenv ("R_DYLDCACHE_FILTER");
if (target_libs) {
RList *target_lib_names = r_str_split_list (target_libs, ":");
RList *target_lib_names = r_str_split_list (target_libs, ":", 0);
if (!target_lib_names) {
R_FREE (target_libs);
r_list_free (bins);

View File

@ -614,7 +614,7 @@ R_API bool r_config_eval(RConfig *cfg, const char *str, bool many) {
if (many) {
// space separated list of k=v k=v,..
// if you want to use spaces go for base64 or e.
RList *list = r_str_split_list (s, ",");
RList *list = r_str_split_list (s, ",", 0);
RListIter *iter;
char *name;
r_list_foreach (list, iter, name) {

View File

@ -1039,7 +1039,7 @@ static int bin_source(RCore *r, int mode) {
SdbList *ls = sdb_foreach_list (binfile->sdb_addrinfo, false);
ls_foreach (ls, iter, kv) {
char *v = sdbkv_value (kv);
RList *list = r_str_split_list (v, "|");
RList *list = r_str_split_list (v, "|", 0);
srcline = r_list_get_bottom (list);
if (srcline) {
if (!strstr (srcline, "0x")){

View File

@ -436,7 +436,7 @@ static void update_cmdpdc_options(RCore *core, RConfigNode *node) {
RListIter *iter;
r_list_purge (node->options);
char *opts = r_core_cmd_str (core, "e cmd.pdc=?");
RList *optl = r_str_split_list (opts, "\n");
RList *optl = r_str_split_list (opts, "\n", 0);
char *opt;
node->options->free = free;
r_list_foreach (optl, iter, opt) {

View File

@ -2786,7 +2786,7 @@ static int cmd_anal_fcn(RCore *core, const char *input) {
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
if (fcn) {
char *args = strdup (input + 2);
RList *argv = r_str_split_list (args, " ");
RList *argv = r_str_split_list (args, " ", 0);
ut64 table = r_num_math (core->num, r_list_get_n (argv, 0));
ut64 elements = r_num_math (core->num, r_list_get_n (argv, 1));
r_anal_jmptbl (core->anal, fcn, core->offset, table, elements, UT64_MAX);
@ -5256,7 +5256,7 @@ static void __core_anal_appcall(RCore *core, const char *input) {
RListIter *iter;
char *arg;
char *inp = strdup (input);
RList *args = r_str_split_list (inp, " ");
RList *args = r_str_split_list (inp, " ", 0);
int i = 0;
r_list_foreach (args, iter, arg) {
const char *alias = sdb_fmt ("A%d", i);
@ -6771,8 +6771,8 @@ static bool cmd_anal_refs(RCore *core, const char *input) {
char *res1 = sdb_get (core->anal->sdb_fcns, wvar, 0);
const char *ref;
RListIter *iter;
RList *list = (res && *res)? r_str_split_list (res, ","): NULL;
RList *list1 = (res1 && *res1)? r_str_split_list (res1, ","): NULL;
RList *list = (res && *res)? r_str_split_list (res, ",", 0): NULL;
RList *list1 = (res1 && *res1)? r_str_split_list (res1, ",", 0): NULL;
r_list_join (list , list1);
r_list_foreach (list, iter, ref) {
ut64 addr = r_num_math (NULL, ref);

View File

@ -865,7 +865,7 @@ static int step_until_optype(RCore *core, const char *_optypes) {
goto end;
}
optypes_list = r_str_split_list (optypes, " ");
optypes_list = r_str_split_list (optypes, " ", 0);
r_cons_break_push (NULL, NULL);
for (;;) {
@ -2285,7 +2285,7 @@ static void cmd_debug_reg(RCore *core, const char *str) {
all = strdup (all);
}
char *arg;
RList *args = r_str_split_list (all, " ");
RList *args = r_str_split_list (all, " ", 0);
r_debug_reg_sync (core->dbg, R_REG_TYPE_ALL, false); //R_REG_TYPE_GPR, false);
int count = r_list_length (args);
r_list_foreach (args, iter, arg) {
@ -4629,7 +4629,7 @@ static int cmd_debug(void *data, const char *input) {
case '+': // "dt+"
if (input[2] == '+') { // "dt++"
char *a, *s = r_str_trim_dup (input + 3);
RList *args = r_str_split_list (s, " ");
RList *args = r_str_split_list (s, " ", 0);
RListIter *iter;
r_list_foreach (args, iter, a) {
ut64 addr = r_num_get (NULL, a);

View File

@ -937,7 +937,7 @@ static int cmd_help(void *data, const char *input) {
case 'p':
{
char *word, *str = strdup (input + 2);
RList *list = r_str_split_list (str, " ");
RList *list = r_str_split_list (str, " ", 0);
ut64 *nums = calloc (sizeof (ut64), r_list_length (list));
int i = 0;
r_list_foreach (list, iter, word) {

View File

@ -1245,7 +1245,7 @@ static void cmd_print_gadget(RCore *core, const char *_input) {
} else {
space = "";
}
RList *args = r_str_split_list (space, " ");
RList *args = r_str_split_list (space, " ", 0);
char *x = r_list_pop_head (args);
char *y = r_list_pop_head (args);
char *w = r_list_pop_head (args);
@ -1261,7 +1261,7 @@ static void cmd_print_gadget(RCore *core, const char *_input) {
}
} else if (*_input == ' ') { // "pg "
char *input = strdup (_input);
RList *args = r_str_split_list (input, " ");
RList *args = r_str_split_list (input, " ", 0);
char *x = r_list_pop_head (args);
char *y = r_list_pop_head (args);
char *w = r_list_pop_head (args);

View File

@ -205,7 +205,7 @@ static void __core_cmd_tcc(RCore *core, const char *input) {
case 'j':
{
char *ccs = r_core_cmd_strf (core, "afcl");
RList *list = r_str_split_list (ccs, "\n");
RList *list = r_str_split_list (ccs, "\n", 0);
RListIter *iter;
const char *cc;
PJ *pj = pj_new ();
@ -226,7 +226,7 @@ static void __core_cmd_tcc(RCore *core, const char *input) {
case 'l':
{
char *ccs = r_core_cmd_strf (core, "afcl");
RList *list = r_str_split_list (ccs, "\n");
RList *list = r_str_split_list (ccs, "\n", 0);
RListIter *iter;
const char *cc;
r_list_foreach (list, iter, cc) {
@ -241,7 +241,7 @@ static void __core_cmd_tcc(RCore *core, const char *input) {
case '*':
{
char *ccs = r_core_cmd_strf (core, "afcl");
RList *list = r_str_split_list (ccs, "\n");
RList *list = r_str_split_list (ccs, "\n", 0);
RListIter *iter;
const char *cc;
r_list_foreach (list, iter, cc) {
@ -351,7 +351,7 @@ static void cmd_type_noreturn(RCore *core, const char *input) {
char *s = strdup (r_str_trim_ro (input + 1));
RListIter *iter;
char *k;
RList *list = r_str_split_list (s, " ");
RList *list = r_str_split_list (s, " ", 0);
r_list_foreach (list, iter, k) {
r_anal_noreturn_drop (core->anal, k);
}

View File

@ -3185,7 +3185,7 @@ int __show_all_decompiler_cb(void *user) {
RPanelsRoot *root = core->panels_root;
const char *pdc_now = r_config_get (core->config, "cmd.pdc");
char *opts = r_core_cmd_str (core, "e cmd.pdc=?");
RList *optl = r_str_split_list (opts, "\n");
RList *optl = r_str_split_list (opts, "\n", 0);
RListIter *iter;
char *opt;
int i = 0;
@ -4685,7 +4685,7 @@ bool __init_panels_menu(RCore *core) {
{
parent = "Settings.Decompiler";
char *opts = r_core_cmd_str (core, "e cmd.pdc=?");
RList *optl = r_str_split_list (opts, "\n");
RList *optl = r_str_split_list (opts, "\n", 0);
RListIter *iter;
char *opt;
r_list_foreach (optl, iter, opt) {

View File

@ -106,7 +106,7 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
pfile = r_file_slurp (httpauthfile, &sz);
if (pfile) {
so.authtokens = r_str_split_list (pfile, "\n");
so.authtokens = r_str_split_list (pfile, "\n", 0);
} else {
r_socket_free (s);
eprintf ("Empty list of HTTP users\n");
@ -377,7 +377,6 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
} else {
const char *root = r_config_get (core->config, "http.root");
const char *homeroot = r_config_get (core->config, "http.homeroot");
const char *index = r_config_get (core->config, "http.index");
char *path;
if (!strcmp (rs->path, "/")) {
free (rs->path);
@ -404,7 +403,6 @@ static int r_core_rtr_http_run(RCore *core, int launch, int browse, const char *
}
// FD IS OK HERE
if (rs->path [strlen (rs->path) - 1] == '/') {
const char *index = r_config_get (core->config, "http.index");
path = (*index == '/')? strdup (index): r_str_append (path, index);
} else {
//snprintf (path, sizeof (path), "%s/%s", root, rs->path);

View File

@ -1366,7 +1366,7 @@ R_API int r_core_visual_view_rop(RCore *core) {
eprintf ("Searching ROP gadgets...\n");
char *ropstr = r_core_cmd_strf (core, "\"/Rl %s\" @e:scr.color=0", line);
RList *rops = r_str_split_list (ropstr, "\n");
RList *rops = r_str_split_list (ropstr, "\n", 0);
int delta = 0;
bool show_color = core->print->flags & R_PRINT_FLAGS_COLOR;
bool forceaddr = false;
@ -1518,7 +1518,7 @@ R_API int r_core_visual_view_rop(RCore *core) {
free (ropstr);
ropstr = r_core_cmd_strf (core, "\"/Rl %s\" @e:scr.color=0", line);
r_list_free (rops);
rops = r_str_split_list (ropstr, "\n");
rops = r_str_split_list (ropstr, "\n", 0);
}
}
break;

View File

@ -14,7 +14,7 @@ R_API RList *r_flag_tags_list(RFlag *f, const char *name) {
if (name) {
const char *k = sdb_fmt ("tag.%s", name);
char *words = sdb_get (f->tags, k, NULL);
return r_str_split_list (words, " ");
return r_str_split_list (words, " ", 0);
}
RList *res = r_list_newf (free);
SdbList *o = sdb_foreach_list (f->tags, false);
@ -61,7 +61,7 @@ R_API RList *r_flag_tags_get(RFlag *f, const char *name) {
RList *res = r_list_newf (NULL);
char *words = sdb_get (f->tags, k, NULL);
if (words) {
RList *list = r_str_split_list (words, " ");
RList *list = r_str_split_list (words, " ", 0);
struct iter_glob_flag_t u = { .res = res, .words = list };
r_flag_foreach (f, iter_glob_flag, &u);
r_list_free (list);

View File

@ -57,7 +57,7 @@ R_API const char *r_str_casestr(const char *a, const char *b);
R_API const char *r_str_firstbut(const char *s, char ch, const char *but);
R_API const char *r_str_lastbut(const char *s, char ch, const char *but);
R_API int r_str_split(char *str, char ch);
R_API RList *r_str_split_list(char *str, const char *c);
R_API RList *r_str_split_list(char *str, const char *c, int n);
R_API RList *r_str_split_duplist(const char *str, const char *c);
R_API int *r_str_split_lines(char *str, int *count);
R_API char* r_str_replace(char *str, const char *key, const char *val, int g);

View File

@ -56,6 +56,6 @@ R_API char *r_table_tohtml(RTable *t);
R_API void r_table_transpose(RTable *t);
R_API void r_table_format(RTable *t, int nth, RTableColumnType *type);
R_API ut64 r_table_reduce(RTable *t, int nth);
R_API void r_table_columns(RTable *t, const char *name, ...);
R_API void r_table_columns(RTable *t, RList *cols); // const char *name, ...);
#endif

View File

@ -128,7 +128,7 @@ R_API int r_io_plugin_list_json(RIO *io) {
if (plugin->uris) {
char *uri;
char *uris = strdup (plugin->uris);
RList *plist = r_str_split_list (uris, ",");
RList *plist = r_str_split_list (uris, ",", 0);
RListIter *piter;
pj_k (pj, "uris");
pj_a (pj);

View File

@ -87,7 +87,7 @@ R_API int r_main_r2agent(int argc, char **argv) {
int sz;
pfile = r_file_slurp (httpauthfile, &sz);
if (pfile) {
so.authtokens = r_str_split_list (pfile, "\n");
so.authtokens = r_str_split_list (pfile, "\n", 0);
} else {
eprintf ("Empty list of HTTP users\\n");
return usage (0);

View File

@ -3050,28 +3050,27 @@ R_API bool r_str_endswith(const char *str, const char *needle) {
}
// Splits the string <str> by string <c> and returns the result in a list.
R_API RList *r_str_split_list(char *str, const char *c) {
R_API RList *r_str_split_list(char *str, const char *c, int n) {
r_return_val_if_fail (str && c, NULL);
RList *lst = r_list_new ();
char *aux;
bool first_loop = true;
for (;;) {
if (first_loop) {
aux = strtok (str, c);
first_loop = false;
} else {
aux = strtok (NULL, c);
RList *lst = r_list_newf (NULL);
char *aux = str;
int i = 0;
char *e = aux;
for (;e;) {
e = strstr (aux, c);
if (n > 0) {
if (++i > n) {
r_list_append (lst, aux);
break;
}
}
if (!aux) {
break;
if (e) {
*e++ = 0;
}
r_str_trim (aux);
r_list_append (lst, aux);
aux = e;
}
return lst;
}
@ -3505,7 +3504,7 @@ R_API char *r_str_scale(const char *s, int w, int h) {
RListIter *iter;
char *line;
char *str = strdup (s);
RList *lines = r_str_split_list (str, "\n");
RList *lines = r_str_split_list (str, "\n", 0);
int i, j;
int rows = 0;
int maxcol = 0;

View File

@ -57,7 +57,7 @@ R_API void r_str_trim_path(char *s) {
}
R_API char* r_str_trim_lines(char *str) {
RList *list = r_str_split_list (str, "\n");
RList *list = r_str_split_list (str, "\n", 0);
char *s;
RListIter *iter;
RStrBuf *sb = r_strbuf_new ("");

View File

@ -273,7 +273,7 @@ R_API char *r_syscmd_sort(const char *file) {
if (!data) {
eprintf ("No such file or directory\n");
} else {
list = r_str_split_list (data, "\n");
list = r_str_split_list (data, "\n", 0);
r_list_sort (list, cmpstr);
data = r_list_to_str (list, '\n');
r_list_free (list);
@ -352,7 +352,7 @@ R_API char *r_syscmd_uniq(const char *file) {
if (!data) {
eprintf ("No such file or directory\n");
} else {
list = r_str_split_list (data, "\n");
list = r_str_split_list (data, "\n", 0);
RList *uniq_list = r_list_uniq (list, cmpstr);
data = r_list_to_str (uniq_list, '\n');
r_list_free (uniq_list);
@ -399,8 +399,8 @@ R_API char *r_syscmd_join(const char *file1, const char *file2) {
if (!data1 && !data2) {
eprintf ("No such files or directory\n");
} else {
list1 = r_str_split_list (data1, "\n");
list2 = r_str_split_list (data2, "\n");
list1 = r_str_split_list (data1, "\n", 0);
list2 = r_str_split_list (data2, "\n", 0);
char *str1, *str2;
r_list_foreach (list1, iter1, str1) {

View File

@ -110,7 +110,6 @@ static bool addRow (RTable *t, RList *items, const char *arg, int col) {
}
R_API void r_table_add_row_list(RTable *t, RList *items) {
int col = 0;
RTableRow *row = r_table_row_new (items);
r_list_append (t->rows, row);
// throw warning if not enough columns defined in header
@ -361,6 +360,30 @@ static void __table_column_free(void *_col) {
free (col);
}
R_API void r_table_columns(RTable *t, RList *colNames) {
RListIter *iter, *iterCol;
char * colName;
RTableRow *row;
r_list_foreach (t->rows, iter, row) {
RList *items = r_list_newf (r_table_row_free);
r_list_foreach (colNames, iterCol, colName) {
int fc = r_table_column_nth (t, colName);
RTableRow *item = r_list_get_n (row->items, fc);
r_list_append (items, item);
}
row->items = items;
}
RList *cols = r_list_newf (r_table_column_free);
r_list_foreach (colNames, iterCol, colName) {
int fc = r_table_column_nth (t, colName);
if (fc >= 0) {
RTableColumn *c = r_list_get_n (t->cols, fc);
r_list_append (cols, c);
}
}
t->cols = cols;
}
R_API void r_table_filter_columns(RTable *t, RList *list) {
const char *col;
RListIter *iter;
@ -384,10 +407,10 @@ R_API void r_table_query(RTable *t, const char *q) {
// addr/gt/200,addr/lt/400,addr/sort/dec,offset/sort/inc
RListIter *iter;
char *qq = strdup (q);
RList *queries = r_str_split_list (qq, ",");
RList *queries = r_str_split_list (qq, ",", 0);
char *query;
r_list_foreach (queries, iter, query) {
RList *q = r_str_split_list (query, "/");
RList *q = r_str_split_list (query, "/", 2);
const char *columnName = r_list_get_n (q, 0);
const char *operation = r_list_get_n (q, 1);
const char *operand = r_list_get_n (q, 2);
@ -396,7 +419,7 @@ R_API void r_table_query(RTable *t, const char *q) {
if (*columnName == '[') {
col = atoi (columnName + 1);
} else {
eprintf ("Invalid column name (%s)\n", columnName);
eprintf ("Invalid column name (%s) for (%s)\n", columnName, query);
}
}
if (!operation) {
@ -405,7 +428,12 @@ R_API void r_table_query(RTable *t, const char *q) {
if (!strcmp (operation, "sort")) {
r_table_sort (t, col, operand && !strcmp (operand, "dec"));
} else if (!strcmp (operation, "cols")) {
eprintf ("(%s)\n", qq);
char *op = strdup (operand);
RList *list = r_str_split_list (op, "/", 0);
r_list_prepend (list, strdup (columnName));
r_table_columns (t, list); // select/reorder columns
r_list_free (list);
free (op);
// TODO r_table_filter_columns (t, q);
} else if (!strcmp (operation, "quiet")) {
t->showHeader = false;