diff --git a/binr/radare2/radare2.c b/binr/radare2/radare2.c index f7042e3daf..8ba1d2b767 100644 --- a/binr/radare2/radare2.c +++ b/binr/radare2/radare2.c @@ -1341,7 +1341,7 @@ int main(int argc, char **argv, char **envp) { } // no flagspace selected by default the beginning - r.flags->space_idx = -1; + r_flag_space_set (r.flags, NULL); /* load .r2 */ { char f[128]; @@ -1440,7 +1440,7 @@ int main(int argc, char **argv, char **envp) { } // no flagspace selected by default the beginning - r.flags->space_idx = -1; + r_flag_space_set (r.flags, NULL); if (!debug && r.bin && r.bin->cur && r.bin->cur->o && r.bin->cur->o->info) { if (r.bin->cur->o->info->arch) { r_core_cmd0 (&r, "aeip"); diff --git a/libr/core/cmd.c b/libr/core/cmd.c index ec9bed29f8..416238bb21 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -2663,7 +2663,7 @@ escape_backtick: bool is_arch_set = false; char *tmpeval = NULL; char *tmpasm = NULL; - int flgspc = -123; + bool flgspc_changed = false; int tmpfd = -1; int sz, len; ut8 *buf; @@ -2718,8 +2718,7 @@ repeat_arroba: } else if (ptr[0] && ptr[1] == ':' && ptr[2]) { switch (ptr[0]) { case 'F': // "@F:" // temporary flag space - flgspc = r_flag_space_get (core->flags, ptr + 2); - r_flag_space_set (core->flags, ptr + 2); + flgspc_changed = r_flag_space_push (core->flags, ptr + 2); break; case 'B': // "@B:#" // seek to the last instruction in current bb { @@ -3002,8 +3001,8 @@ next_arroba: r_core_cmd0 (core, tmpeval); R_FREE (tmpeval); } - if (flgspc != -123) { - r_flag_space_set_i (core->flags, flgspc); + if (flgspc_changed) { + r_flag_space_pop (core->flags); } *ptr = '@'; rc = ret; @@ -3607,7 +3606,7 @@ R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) { } str[i] = ch; { - int flagspace = core->flags->space_idx; + const RSpace *flagspace = r_flag_space_cur (core->flags); RList *match_flag_items = r_list_newf ((RListFree)r_flag_item_free); if (!match_flag_items) { break; @@ -3642,7 +3641,6 @@ R_API int r_core_cmd_foreach(RCore *core, const char *cmd, char *each) { } r_list_free (match_flag_items); - core->flags->space_idx = flagspace; core->rcmd->macro.counter++ ; R_FREE (word); } diff --git a/libr/core/cmd_flag.c b/libr/core/cmd_flag.c index bf289e4088..694ff3ee5a 100644 --- a/libr/core/cmd_flag.c +++ b/libr/core/cmd_flag.c @@ -341,6 +341,56 @@ static bool adjust_offset(RFlagItem *flag, void *user) { return true; } +static void print_space_stack(RFlag *f, int ordinal, const char *name, bool selected, PJ *pj, int mode) { + bool first = ordinal == 0; + switch (mode) { + case 'j': { + char *ename = r_str_escape (name); + if (!ename) { + return; + } + + pj_o (pj); + pj_ki (pj, "ordinal", ordinal); + pj_ks (pj, "name", ename); + pj_kb (pj, "selected", selected); + pj_end (pj); + free (ename); + break; + } + case '*': { + const char *fmt = first? "fs %s\n": "fs+%s\n"; + r_cons_printf (fmt, name); + break; + } + default: + r_cons_printf ("%-2d %s%s\n", ordinal, name, selected? " (selected)": ""); + break; + } +} + +static int flag_space_stack_list(RFlag *f, int mode) { + RListIter *iter; + char *space; + int i = 0; + PJ *pj = NULL; + if (mode == 'j') { + pj = pj_new (); + pj_a (pj); + } + r_list_foreach (f->spaces.spacestack, iter, space) { + print_space_stack (f, i++, space, false, pj, mode); + } + const char *cur_name = r_flag_space_cur_name (f); + print_space_stack (f, i++, cur_name, true, pj, mode); + if (mode == 'j') { + pj_end (pj); + r_cons_printf ("%s\n", pj_string (pj)); + pj_free (pj); + } + return i; +} + static int cmd_flag(void *data, const char *input) { static int flagenum = 0; RCore *core = (RCore *)data; @@ -709,19 +759,20 @@ rep: } break; case 's': - r_flag_space_stack_list (core->flags, input[2]); + flag_space_stack_list (core->flags, input[2]); break; case '-': switch (input[2]) { case '*': r_flag_space_unset (core->flags, NULL); break; - case '.': - { - const char *curfs = r_flag_space_cur (core->flags); - r_flag_space_unset (core->flags, curfs); + case '.': { + const RSpace *sp = r_flag_space_cur (core->flags); + if (sp) { + r_flag_space_unset (core->flags, sp->name); } break; + } case 0: r_flag_space_pop (core->flags); break; @@ -734,7 +785,7 @@ rep: case '\0': case '*': case 'q': - r_flag_space_list (core->flags, input[1]); + spaces_list (&core->flags->spaces, input[1]); break; case ' ': r_flag_space_set (core->flags, input+2); @@ -747,21 +798,15 @@ rep: } f = r_flag_get_i (core->flags, off); if (f) { - f->space = core->flags->space_idx; + f->space = r_flag_space_cur (core->flags); } else { eprintf ("Cannot find any flag at 0x%"PFMT64x".\n", off); } } break; - default: { - int i, j = 0; - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (core->flags->spaces[i]) - r_cons_printf ("%02d %c %s\n", j++, - (i == core->flags->space_idx)?'*':' ', - core->flags->spaces[i]); - } - } break; + default: + spaces_list (&core->flags->spaces, 0); + break; } break; case 'g': @@ -888,7 +933,6 @@ rep: ut64 addr = core->offset; char *arg = NULL; RFlagItem *f = NULL; - bool space_strict = true; bool strict_offset = false; switch (input[1]) { case '?': @@ -901,7 +945,6 @@ rep: addr = core->offset; break; case 'd': - space_strict = false; arg = strchr (input, ' '); if (arg) { addr = r_num_math (core->num, arg + 1); @@ -924,47 +967,46 @@ rep: } return 0; } - case 'w': - { + case 'w': { arg = strchr (input, ' '); - if (arg) { - arg++; - if (*arg) { - RFlag *f = core->flags; - RList *temp = r_flag_all_list (f); - ut64 loff = 0; - ut64 uoff = 0; - ut64 curseek = core->offset; - char *lmatch = NULL , *umatch = NULL; - RFlagItem *flag; - RListIter *iter; - r_list_sort (temp, &cmpflag); - r_list_foreach (temp, iter, flag) { - if ((f->space_idx != -1) && (flag->space != f->space_idx)) { - continue; - } - if (strstr (flag->name , arg) != NULL) { - if (flag->offset < core->offset) { - loff = flag->offset; - lmatch = flag->name; - continue; - } - uoff = flag->offset; - umatch = flag->name; - break; - } - } - char *match = (curseek - loff) < (uoff - curseek) ? lmatch : umatch ; - if (match) { - if (*match) { - r_cons_println (match); - } - } - r_list_free (temp); - } + if (!arg) { + return 0; } + arg++; + if (!*arg) { + return 0; + } + + RFlag *f = core->flags; + RList *temp = r_flag_all_list (f, true); + ut64 loff = 0; + ut64 uoff = 0; + ut64 curseek = core->offset; + char *lmatch = NULL , *umatch = NULL; + RFlagItem *flag; + RListIter *iter; + r_list_sort (temp, &cmpflag); + r_list_foreach (temp, iter, flag) { + if (strstr (flag->name , arg) != NULL) { + if (flag->offset < core->offset) { + loff = flag->offset; + lmatch = flag->name; + continue; + } + uoff = flag->offset; + umatch = flag->name; + break; + } + } + char *match = (curseek - loff) < (uoff - curseek) ? lmatch : umatch ; + if (match) { + if (*match) { + r_cons_println (match); + } + } + r_list_free (temp); return 0; - } + } default: arg = strchr (input, ' '); if (arg) { @@ -972,9 +1014,7 @@ rep: } break; } - core->flags->space_strict = space_strict; f = r_flag_get_at (core->flags, addr, !strict_offset); - core->flags->space_strict = false; if (f) { if (f->offset != addr) { // if input contains 'j' print json diff --git a/libr/core/cmd_meta.c b/libr/core/cmd_meta.c index a6c464dbbd..89c0a94d73 100644 --- a/libr/core/cmd_meta.c +++ b/libr/core/cmd_meta.c @@ -1098,17 +1098,10 @@ static int cmd_meta(void *data, const char *input) { case ' ': // "CS " r_spaces_set (ms, input + 2); break; - default: { - RSpace *s; - RBIter it; - const RSpace *cur = r_spaces_current (ms); - r_rbtree_foreach (ms->spaces, it, s, RSpace, rb) { - r_cons_printf ("%c %s\n", (s == cur)? '*': ' ', - s->name); - } + default: + spaces_list (ms, 0); break; } - } break; } return true; diff --git a/libr/core/cmd_print.c b/libr/core/cmd_print.c index b1c9d801e0..80c1d99e62 100644 --- a/libr/core/cmd_print.c +++ b/libr/core/cmd_print.c @@ -1761,7 +1761,7 @@ R_API void r_core_print_examine(RCore *core, const char *str) { } struct count_pz_t { - int flagspace; + RSpace *flagspace; ut64 addr; ut64 size; int *ret; @@ -1821,8 +1821,7 @@ static int printzoomcallback(void *user, int mode, ut64 addr, ut8 *bufz, ut64 si } break; case 's': // "pzs" - j = r_flag_space_get (core->flags, "strings"); - u.flagspace = j; + u.flagspace = r_flag_space_get (core->flags, "strings"); u.addr = addr; u.size = size; u.ret = &ret; diff --git a/libr/core/cmd_seek.c b/libr/core/cmd_seek.c index e3054e6e76..28585c02ad 100644 --- a/libr/core/cmd_seek.c +++ b/libr/core/cmd_seek.c @@ -493,9 +493,7 @@ static int cmd_seek(void *data, const char *input) { r_list_foreach (list, iter, undo) { char *name = NULL; - core->flags->space_strict = true; RFlagItem *f = r_flag_get_at (core->flags, undo->off, true); - core->flags->space_strict = false; if (f) { if (f->offset != undo->off) { name = r_str_newf ("%s+%d", f->name, @@ -551,9 +549,7 @@ static int cmd_seek(void *data, const char *input) { r_list_foreach (list, iter, undo) { char *name = NULL; - core->flags->space_strict = true; RFlagItem *f = r_flag_get_at (core->flags, undo->off, true); - core->flags->space_strict = false; if (f) { if (f->offset != undo->off) { name = r_str_newf ("%s + %d\n", f->name, diff --git a/libr/core/core.c b/libr/core/core.c index 4eefb3bcbe..380c3010d4 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -1173,10 +1173,10 @@ static void autocomplete_zignatures(RLine* line, const char* msg) { int length = strlen (msg); RSpaces *zs = &core->anal->zign_spaces; RSpace *s; - RBIter it; + RSpaceIter it; int i = 0; - r_rbtree_foreach (zs->spaces, it, s, RSpace, rb) { + r_spaces_foreach (zs, it, s) { if (i == TMP_ARGV_SZ - 1) { break; } @@ -1202,23 +1202,21 @@ static void autocomplete_flagspaces(RLine* line, const char* msg) { } int length = strlen (msg); RFlag *flag = core->flags; - int j, i = 0; - for (j = 0; j < R_FLAG_SPACES_MAX - 1; j++) { - if (flag->spaces[j] && flag->spaces[j][0]) { - if (i == TMP_ARGV_SZ - 1) { - break; - } - if (!strncmp (msg, flag->spaces[j], length)) { - if (i + 1 < TMP_ARGV_SZ) { - tmp_argv[i++] = flag->spaces[j]; - } + int i = 0; + RSpaceIter it; + RSpace *s; + r_flag_space_foreach (flag, it, s) { + if (i == TMP_ARGV_SZ - 1) { + break; + } + if (!strncmp (msg, s->name, length)) { + if (i + 1 < TMP_ARGV_SZ) { + tmp_argv[i++] = s->name; } } } - if (flag->spaces[j] && !strncmp (msg, flag->spaces[j], strlen (msg))) { - if (i + 1 < TMP_ARGV_SZ) { - tmp_argv[i++] = "*"; - } + if (i + 1 < TMP_ARGV_SZ) { + tmp_argv[i++] = "*"; } tmp_argv[i] = NULL; line->completion.argc = i; @@ -2209,25 +2207,28 @@ static char *get_comments_cb(void *user, ut64 addr) { } R_IPI void spaces_list(RSpaces *sp, int mode) { - RBIter it; + RSpaceIter it; RSpace *s; bool first = true; const RSpace *cur = r_spaces_current (sp); + PJ *pj = NULL; if (mode == 'j') { - r_cons_printf ("["); + pj = pj_new (); + pj_a (pj); } - r_rbtree_foreach (sp->spaces, it, s, RSpace, rb) { + r_spaces_foreach (sp, it, s) { int count = r_spaces_count (sp, s->name); if (mode == 'j') { - r_cons_printf ("%s{\"name\":\"%s\"%s,\"count\":%d}", - !first? ",": "", s->name, - cur == s? ",\"selected\":true": "", - count); + pj_o (pj); + pj_ks (pj, "name", s->name); + pj_ki (pj, "count", count); + pj_kb (pj, "selected", cur == s); + pj_end (pj); } else if (mode == '*') { r_cons_printf ("%s %s\n", sp->name, s->name); } else { - r_cons_printf ("%d %c %s\n", count, cur == s? '*': '.', - s->name); + r_cons_printf ("%5d %c %s\n", count, (!cur || cur == s)? '*': '.', + s->name); } first = false; } @@ -2235,7 +2236,9 @@ R_IPI void spaces_list(RSpaces *sp, int mode) { r_cons_printf ("%s %s # current\n", sp->name, r_spaces_current_name (sp)); } if (mode == 'j') { - r_cons_printf ("]\n"); + pj_end (pj); + r_cons_printf ("%s\n", pj_string (pj)); + pj_free (pj); } } diff --git a/libr/core/disasm.c b/libr/core/disasm.c index 04f8623c6b..51a07ef3d9 100644 --- a/libr/core/disasm.c +++ b/libr/core/disasm.c @@ -160,7 +160,7 @@ typedef struct { RStrEnc strenc; int cursor; int show_comment_right_default; - int flagspace_ports; + RSpace *flagspace_ports; int show_flag_in_bytes; int lbytes; int show_comment_right; @@ -985,18 +985,18 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) { ds->opstr = strdup (ds->hint->opcode); } if (ds->filter) { - int ofs = core->parser->flagspace; - int fs = ds->flagspace_ports; + RSpace *ofs = core->parser->flagspace; + RSpace *fs = ds->flagspace_ports; if (ds->analop.type == R_ANAL_OP_TYPE_IO) { - core->parser->notin_flagspace = -1; + core->parser->notin_flagspace = NULL; core->parser->flagspace = fs; } else { - if (fs != -1) { + if (fs) { core->parser->notin_flagspace = fs; core->parser->flagspace = fs; } else { - core->parser->notin_flagspace = -1; - core->parser->flagspace = -1; + core->parser->notin_flagspace = NULL; + core->parser->flagspace = NULL; } } if (ds->analop.refptr) { @@ -5362,18 +5362,18 @@ R_API int r_core_print_disasm_instructions(RCore *core, int nb_bytes, int nb_opc } } else if (ds->filter) { char *asm_str; - int ofs = core->parser->flagspace; - int fs = ds->flagspace_ports; + RSpace *ofs = core->parser->flagspace; + RSpace *fs = ds->flagspace_ports; if (ds->analop.type == R_ANAL_OP_TYPE_IO) { - core->parser->notin_flagspace = -1; + core->parser->notin_flagspace = NULL; core->parser->flagspace = fs; } else { - if (fs != -1) { + if (fs) { core->parser->notin_flagspace = fs; core->parser->flagspace = fs; } else { - core->parser->notin_flagspace = -1; - core->parser->flagspace = -1; + core->parser->notin_flagspace = NULL; + core->parser->flagspace = NULL; } } core->parser->hint = ds->hint; diff --git a/libr/core/project.c b/libr/core/project.c index 2563743c29..ca8aba6ecd 100644 --- a/libr/core/project.c +++ b/libr/core/project.c @@ -606,7 +606,7 @@ static bool simpleProjectSaveScript(RCore *core, const char *file, int opts) { static bool projectSaveScript(RCore *core, const char *file, int opts) { char *filename, *hl, *ohl = NULL; - int fd, fdold, tmp; + int fd, fdold; if (!file || *file == '\0') { return false; @@ -633,10 +633,9 @@ static bool projectSaveScript(RCore *core, const char *file, int opts) { if (opts & R_CORE_PRJ_FLAGS) { r_str_write (fd, "# flags\n"); - tmp = core->flags->space_idx; - core->flags->space_idx = -1; + r_flag_space_push (core->flags, NULL); r_flag_list (core->flags, true, NULL); - core->flags->space_idx = tmp; + r_flag_space_pop (core->flags); r_cons_flush (); } // Set file.path and file.lastpath to empty string to signal diff --git a/libr/core/visual.c b/libr/core/visual.c index 00812674e1..ae6d3ff0ff 100644 --- a/libr/core/visual.c +++ b/libr/core/visual.c @@ -3512,24 +3512,15 @@ R_API void r_core_visual_title(RCore *core, int color) { filename = desc? desc->name: ""; { /* get flag with delta */ ut64 addr = core->offset + (core->print->cur_enabled? core->print->cur: 0); -#if 1 /* TODO: we need a helper into r_flags to do that */ - bool oss = core->flags->space_strict; - int osi = core->flags->space_idx; RFlagItem *f = NULL; - core->flags->space_strict = true; - core->anal->flb.set_fs (core->flags, "symbols"); - if (core->flags->space_idx != -1) { + if (core->anal->flb.push_fs (core->flags, "symbols")) { f = core->anal->flb.get_at (core->flags, addr, showDelta); + core->anal->flb.pop_fs (core->flags); } - core->flags->space_strict = oss; - core->flags->space_idx = osi; if (!f) { f = r_flag_get_at (core->flags, addr, showDelta); } -#else - RFlagItem *f = r_flag_get_at (core->flags, addr, false); -#endif if (f) { if (f->offset == addr || !f->offset) { snprintf (pos, sizeof (pos), "@ %s", f->name); diff --git a/libr/core/vmenus.c b/libr/core/vmenus.c index f40fdfadd0..980dbadf29 100644 --- a/libr/core/vmenus.c +++ b/libr/core/vmenus.c @@ -595,7 +595,7 @@ static int sdbforcb (void *p, const char *k, const char *v) { R_API int r_core_visual_types(RCore *core) { RCoreVisualTypes vt = {core, 0, 0}; - int i, j, ch; + int i, ch; int _option = 0; int option = 0; char *txt; @@ -612,12 +612,7 @@ R_API int r_core_visual_types(RCore *core) { NULL }; bool use_color = core->print->flags & R_PRINT_FLAGS_COLOR; - for (j = i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (core->flags->spaces[i]) { - j = 1; - } - } - if (j == 0) { + if (r_flag_space_is_empty (core->flags)) { menu = 1; } for (;;) { @@ -716,12 +711,7 @@ R_API int r_core_visual_types(RCore *core) { option = _option; if (menu==0) { // if no flagspaces, just quit - for (j = i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (core->flags->spaces[i]) { - j = 1; - } - } - if (!j) { + if (r_flag_space_is_empty (core->flags)) { return true; } } @@ -1518,12 +1508,7 @@ R_API int r_core_visual_trackflags(RCore *core) { int menu = 0; int sort = SORT_NONE; - for (j=i=0; iflags->spaces[i]) { - j = 1; - } - } - if (j == 0) { + if (r_flag_space_is_empty (core->flags)) { menu = 1; } for (;;) { @@ -1532,19 +1517,14 @@ R_API int r_core_visual_trackflags(RCore *core) { if (menu) { r_cons_printf ("Flags in flagspace '%s'. Press '?' for help.\n\n", - (core->flags->space_idx==-1)?"*":core->flags->spaces[core->flags->space_idx]); + r_flag_space_cur_name (core->flags)); hit = 0; i = j = 0; - RList *l = r_flag_all_list (core->flags); + RList *l = r_flag_all_list (core->flags, true); RListIter *iter; RFlagItem *fi; sort_flags (l, sort); r_list_foreach (l, iter, fi) { - /* filter per flag spaces */ - if ((core->flags->space_idx != -1) && - (fi->space != core->flags->space_idx)) { - continue; - } if (option == i) { fs2 = fi->name; hit = 1; @@ -1591,34 +1571,32 @@ R_API int r_core_visual_trackflags(RCore *core) { } else { r_cons_printf ("Flag spaces:\n\n"); hit = 0; - for (j=i=0;iflags->spaces[i]) { - if (option == i) { - fs = core->flags->spaces[i]; - hit = 1; - } - if ((i >= option - delta) && ((i < option + delta)|| \ - ((option < delta) && (i < (delta << 1))))) { - r_cons_printf (" %c %02d %c %s\n", - (option==i)?'>':' ', j, - (i==core->flags->space_idx)?'*':' ', - core->flags->spaces[i]); - j++; - } - } - } - if (core->flags->spaces[9]) { - if (option == j) { - fs = "*"; + RSpaceIter it; + const RSpace *s, *cur = r_flag_space_cur (core->flags); + int i = 0; + r_flag_space_foreach (core->flags, it, s) { + if (option == i) { + fs = s->name; hit = 1; } - r_cons_printf (" %c %02d %c %s\n", - (option==j)?'>':' ', j, - (i==core->flags->space_idx)?'*':' ', - "*"); + if ((i >= option - delta) && ((i < option + delta) || + ((option < delta) && (i < (delta << 1))))) { + r_cons_printf (" %c %c %s\n", + (option == i)? '>': ' ', + (s == cur)? '*': ' ', + s->name); + } + i++; } - if (!hit && j > 0) { - option = j - 1; + if (option == i) { + fs = "*"; + hit = 1; + } + r_cons_printf (" %c %c %s\n", (option == i)? '>': ' ', + !cur? '*': ' ', "*"); + i++; + if (!hit && i > 0) { + option = i - 1; continue; } } @@ -1663,12 +1641,7 @@ R_API int r_core_visual_trackflags(RCore *core) { if (menu == 0) { r_flag_space_set (core->flags, NULL); // if no flagspaces, just quit - for (j=i=0;iflags->spaces[i]) { - j = 1; - } - } - if (!j) { + if (r_flag_space_is_empty (core->flags)) { return true; } } diff --git a/libr/flag/Makefile b/libr/flag/Makefile index ea3a6692ba..1dbedbbcea 100644 --- a/libr/flag/Makefile +++ b/libr/flag/Makefile @@ -2,6 +2,6 @@ include ../config.mk NAME=r_flag DEPS=r_util -OBJS=flag.o spaces.o zones.o tags.o +OBJS=flag.o zones.o tags.o include ../rules.mk diff --git a/libr/flag/flag.c b/libr/flag/flag.c index ef72941ef7..a23b04174a 100644 --- a/libr/flag/flag.c +++ b/libr/flag/flag.c @@ -7,8 +7,8 @@ R_LIB_VERSION(r_flag); -#define IS_FI_NOTIN_SPACE(f, i) ((f)->space_idx != -1 && (i)->space != (f)->space_idx) -#define IS_FI_IN_SPACE(fi, spidx) ((spidx) == -1 || (fi)->space == (spidx)) +#define IS_FI_NOTIN_SPACE(f, i) (r_flag_space_cur (f) && (i)->space != r_flag_space_cur (f)) +#define IS_FI_IN_SPACE(fi, sp) (!(sp) || (fi)->space == (sp)) #define STRDUP_OR_NULL(s) (!R_STR_ISEMPTY (s)? strdup (s): NULL) static const char *str_callback(RNum *user, ut64 off, int *ok) { @@ -190,8 +190,38 @@ static void ht_free_flag(HtPPKv *kv) { r_flag_item_free (kv->value); } +static bool count_flags(RFlagItem *fi, void *user) { + int *count = (int *)user; + (*count)++; + return true; +} + +static bool unset_flags_space(RFlagItem *fi, void *user) { + fi->space = NULL; + return true; +} + +static void count_flags_in_space(REvent *ev, int type, void *user, void *data) { + RSpaces *sp = (RSpaces *)user; + RFlag *f = container_of (sp, RFlag, spaces); + RSpaceEvent *spe = (RSpaceEvent *)data; + r_flag_foreach_space (f, spe->data.count.space, count_flags, &spe->res); +} + +static void unset_flagspace(REvent *ev, int type, void *user, void *data) { + RSpaces *sp = (RSpaces *)user; + RFlag *f = container_of (sp, RFlag, spaces); + const RSpaceEvent *spe = (const RSpaceEvent *)data; + r_flag_foreach_space (f, spe->data.unset.space, unset_flags_space, NULL); +} + +static void new_spaces(RFlag *f) { + r_spaces_init (&f->spaces, "fs"); + r_event_hook (f->spaces.event, R_SPACE_EVENT_COUNT, count_flags_in_space); + r_event_hook (f->spaces.event, R_SPACE_EVENT_UNSET, unset_flagspace); +} + R_API RFlag *r_flag_new() { - int i; RFlag *f = R_NEW0 (RFlag); if (!f) { return NULL; @@ -209,12 +239,6 @@ R_API RFlag *r_flag_new() { f->zones = NULL; #endif f->tags = sdb_new0 (); - f->space_idx = -1; - f->spacestack = r_list_newf (NULL); - if (!f->spacestack) { - r_flag_free (f); - return NULL; - } f->ht_name = ht_pp_new (NULL, ht_free_flag, NULL); f->by_off = r_skiplist_new (flag_skiplist_free, flag_skiplist_cmp); #if R_FLAG_ZONE_USE_SDB @@ -222,9 +246,7 @@ R_API RFlag *r_flag_new() { #else r_list_free (f->zones); #endif - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - f->spaces[i] = NULL; - } + new_spaces(f); return f; } @@ -261,15 +283,10 @@ R_API void r_flag_item_free(RFlagItem *item) { R_API RFlag *r_flag_free(RFlag *f) { r_return_val_if_fail (f, NULL); - int i; - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - free (f->spaces[i]); - } r_skiplist_free (f->by_off); ht_pp_free (f->ht_name); - sdb_free (f->tags); - r_list_free (f->spacestack); + r_spaces_fini (&f->spaces); r_num_free (f->num); free (f); return NULL; @@ -287,7 +304,7 @@ struct print_flag_t { bool in_range; ut64 range_from; ut64 range_to; - int fs; + RSpace *fs; bool real; const char *pfx; }; @@ -317,13 +334,9 @@ static bool print_flag_rad(RFlagItem *flag, void *user) { if (u->in_range && (flag->offset < u->range_from || flag->offset >= u->range_to)) { return true; } - if (u->fs == -1 || flag->space != u->fs) { + if (!u->fs || flag->space != u->fs) { u->fs = flag->space; - const char *flagspace = r_flag_space_get_i (u->f, u->fs); - if (!flagspace || !*flagspace) { - flagspace = "*"; - } - u->f->cb_printf ("fs %s\n", flagspace); + u->f->cb_printf ("fs %s\n", u->fs? u->fs->name: "*"); } if (flag->alias) { u->f->cb_printf ("fa %s %s\n", flag->name, flag->alias); @@ -360,7 +373,6 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) { bool in_range = false; ut64 range_from = UT64_MAX; ut64 range_to = UT64_MAX; - int fs = -1; if (rad == 'i') { char *sp, *arg = strdup (pfx + 1); sp = strchr (arg, ' '); @@ -385,7 +397,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) { switch (rad) { case 'q': - r_flag_foreach_space (f, f->space_idx, print_flag_name, f); + r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_name, f); break; case 'j': { PJ *pj = pj_new (); @@ -398,7 +410,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) { .real = false }; pj_a (pj); - r_flag_foreach_space (f, f->space_idx, print_flag_json, &u); + r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_json, &u); pj_end (pj); f->cb_printf ("%s\n", pj_string (pj)); pj_free (pj); @@ -411,10 +423,10 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) { .in_range = in_range, .range_from = range_from, .range_to = range_to, - .fs = fs, + .fs = NULL, .pfx = pfx }; - r_flag_foreach_space (f, f->space_idx, print_flag_rad, &u); + r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_rad, &u); break; } default: @@ -427,7 +439,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) { .range_to = range_to, .real = (rad == 'n') }; - r_flag_foreach_space (f, f->space_idx, print_flag_orig_name, &u); + r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_orig_name, &u); } else { PJ *pj = pj_new (); struct print_flag_t u = { @@ -439,7 +451,7 @@ R_API void r_flag_list(RFlag *f, int rad, const char *pfx) { .real = true }; pj_a (pj); - r_flag_foreach_space (f, f->space_idx, print_flag_json, &u); + r_flag_foreach_space (f, r_flag_space_cur (f), print_flag_json, &u); pj_end (pj); f->cb_printf ("%s\n", pj_string (pj)); pj_free (pj); @@ -554,7 +566,7 @@ R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest) { } if (flags_at->off == off) { r_list_foreach (flags_at->flags, iter, item) { - if (f->space_idx != -1 && item->space != f->space_idx) { + if (IS_FI_NOTIN_SPACE (f, item)) { continue; } if (nice) { @@ -573,7 +585,7 @@ R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest) { } while (!nice && flags_at) { r_list_foreach (flags_at->flags, iter, item) { - if (f->space_strict && IS_FI_NOTIN_SPACE (f, item)) { + if (IS_FI_NOTIN_SPACE (f, item)) { continue; } if (item->offset == off) { @@ -592,17 +604,20 @@ R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest) { return nice? evalFlag (f, nice): NULL; } -static bool append_to_list(void *user, const void *k, const void *v) { +static bool append_to_list(RFlagItem *fi, void *user) { RList *ret = (RList *)user; - r_list_append (ret, (RFlagItem *)v); + r_list_append (ret, fi); return true; } -R_API RList *r_flag_all_list(RFlag *f) { +R_API RList *r_flag_all_list(RFlag *f, bool by_space) { RList *ret = r_list_new (); - if (ret) { - ht_pp_foreach (f->ht_name, append_to_list, ret); + if (!ret) { + return NULL; } + + RSpace *cur = by_space? r_flag_space_cur (f): NULL; + r_flag_foreach_space (f, cur, append_to_list, ret); return ret; } @@ -676,7 +691,7 @@ R_API RFlagItem *r_flag_set(RFlag *f, const char *name, ut64 off, ut32 size) { } } - item->space = f->space_idx; + item->space = r_flag_space_cur (f); item->size = size; update_flag_item_offset (f, item, off + f->base, true); @@ -774,11 +789,11 @@ R_API bool r_flag_unset_name(RFlag *f, const char *name) { /* unset all flag items in the RFlag f */ R_API void r_flag_unset_all(RFlag *f) { r_return_if_fail (f); - f->space_idx = -1; ht_pp_free (f->ht_name); f->ht_name = ht_pp_new (NULL, ht_free_flag, NULL); r_skiplist_purge (f->by_off); - r_flag_space_unset (f, NULL); + r_spaces_fini (&f->spaces); + new_spaces (f); } struct flag_relocate_t { @@ -900,6 +915,6 @@ R_API void r_flag_foreach_glob(RFlag *f, const char *glob, RFlagItemCb cb, void FOREACH_BODY (!glob || r_str_glob (fi->name, glob)); } -R_API void r_flag_foreach_space(RFlag *f, int space, RFlagItemCb cb, void *user) { +R_API void r_flag_foreach_space(RFlag *f, const RSpace *space, RFlagItemCb cb, void *user) { FOREACH_BODY (IS_FI_IN_SPACE (fi, space)); } diff --git a/libr/flag/meson.build b/libr/flag/meson.build index 43ac7418e4..09efa6e781 100644 --- a/libr/flag/meson.build +++ b/libr/flag/meson.build @@ -1,7 +1,6 @@ r_flag_sources = [ 'flag.c', 'tags.c', - 'spaces.c', 'zones.c' ] diff --git a/libr/flag/spaces.c b/libr/flag/spaces.c deleted file mode 100644 index 90af8a0be6..0000000000 --- a/libr/flag/spaces.c +++ /dev/null @@ -1,252 +0,0 @@ -/* radare - LGPL - Copyright 2008-2016 - pancake */ - -#include -#include - -R_API int r_flag_space_get(RFlag *f, const char *name) { - int i; - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (f->spaces[i] != NULL) { - if (!strcmp (name, f->spaces[i])) { - return i; - } - } - } - return -1; -} - -R_API const char *r_flag_space_get_i(RFlag *f, int idx) { - if (idx == -1 || idx >= R_FLAG_SPACES_MAX || !f || !f->spaces[idx] || !*f->spaces[idx]) { - return ""; - } - return f->spaces[idx]; -} - -R_API const char *r_flag_space_cur(RFlag *f) { - r_return_val_if_fail (f, NULL); - return r_flag_space_get_i (f, f->space_idx); -} - -R_API bool r_flag_space_push(RFlag *f, const char *name) { - r_return_val_if_fail (f && name, false); - if (f->space_idx != -1 && f->spaces[f->space_idx]) { - r_list_push (f->spacestack, f->spaces[f->space_idx]); - } else { - r_list_push (f->spacestack, "*"); - } - r_flag_space_set (f, name); - return true; -} - -R_API bool r_flag_space_pop(RFlag *f) { - r_return_val_if_fail (f, false); - char *p = r_list_pop (f->spacestack); - if (p) { - if (*p) { - r_flag_space_set (f, p); - } - return true; - } - return false; -} - -R_API bool r_flag_space_set_i(RFlag *f, int idx) { - int i; - r_return_val_if_fail (f, false); - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (f->spaces[i]) { - f->space_idx = idx; - return true; - } - } - return false; -} - -R_API int r_flag_space_set(RFlag *f, const char *name) { - int i; - if (!name || !*name || *name == '*') { - f->space_idx = -1; - return f->space_idx; - } - if (f->space_idx != -1) { - if (!strcmp (name, f->spaces[f->space_idx])) { - return f->space_idx; - } - } - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (f->spaces[i] && !strcmp (name, f->spaces[i])) { - f->space_idx = i; - return f->space_idx; - } - } - /* not found */ - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (!f->spaces[i]) { - f->spaces[i] = strdup (name); - f->space_idx = i; - break; - } - } - return f->space_idx; -} - -static bool unset_space(RFlagItem *fi, void *user) { - fi->space = -1; - return true; -} - -R_API int r_flag_space_unset(RFlag *f, const char *fs) { - r_return_val_if_fail (f, false); - int i, count = 0; - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (!f->spaces[i]) { - continue; - } - if (!fs || !strcmp (fs, f->spaces[i])) { - if (f->space_idx == i) { - f->space_idx = -1; - } - R_FREE (f->spaces[i]); - // remove all flags space references - r_flag_foreach_space (f, i, unset_space, NULL); - count++; - } - } - return count; -} - -static bool space_count(RFlagItem *fi, void *user) { - int *count = (int *)user; - (*count)++; - return true; -} - -static int r_flag_space_count(RFlag *f, int n) { - int count = 0; - if (n != -1) { - r_flag_foreach_space (f, n, space_count, &count); - } - return count; -} - -R_API int r_flag_space_list(RFlag *f, int mode) { - r_return_val_if_fail (f, -1); - const char *defspace = NULL; - int count, len, i, j = 0; - bool allSelected = f->space_idx == -1; - if (mode == 'j') { - f->cb_printf ("["); - } - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (!f->spaces[i]) { - continue; - } - count = r_flag_space_count (f, i); - if (mode == 'q') { - f->cb_printf ("%s\n", f->spaces[i]); - } else if (mode == 'j') { - f->cb_printf ("%s{\"name\":\"%s\",\"count\":%d,\"selected\":%s}", - j? ",":"", f->spaces[i], count, - (allSelected || i == f->space_idx)? "true":"false"); - } else if (mode=='*') { - f->cb_printf ("fs %s\n", f->spaces[i]); - if (i == f->space_idx) { - defspace = f->spaces[i]; - } - } else { - #define INDENT 5 - char num0[64], num1[64], spaces[32]; - snprintf (num0, sizeof (num0), "%d", i); - snprintf (num1, sizeof (num1), "%d", count); - memset(spaces, ' ', sizeof (spaces)); - len = strlen (num0) + strlen (num1); - if (len < INDENT) { - spaces[INDENT-len] = 0; - } else { - spaces[0] = 0; - } - f->cb_printf ("%s%s %s %c %s\n", num0, spaces, num1, - (allSelected || i==f->space_idx)?'*':'.', - f->spaces[i]); - } - j++; - } - if (defspace) { - f->cb_printf ("fs %s # current\n", defspace); - } - if (mode == 'j') { - f->cb_printf ("]\n"); - } - return j; -} - -R_API bool r_flag_space_rename (RFlag *f, const char *oname, const char *nname) { - int i; - r_return_val_if_fail (f && nname, false); - if (!oname) { - if (f->space_idx == -1) { - return false; - } - oname = f->spaces[f->space_idx]; - } - oname = r_str_trim_ro (oname); - nname = r_str_trim_ro (nname); - for (i = 0; i < R_FLAG_SPACES_MAX; i++) { - if (f->spaces[i] && !strcmp (oname, f->spaces[i])) { - free (f->spaces[i]); - f->spaces[i] = strdup (nname); - return true; - } - } - return false; -} - -static void print_space_stack(RFlag *f, int ordinal, char *name, bool selected, int mode) { - bool first = ordinal == 0; - switch (mode) { - case 'j': - if (!first) { - f->cb_printf (","); - } - { - char *ename = r_str_escape (name); - f->cb_printf ("{\"ordinal\":%d,\"name\":\"%s\",\"selected\":%s}", - ordinal, ename, selected? "true":"false"); - free (ename); - } - break; - case '*': - if (first) { - f->cb_printf ("fs %s\n", name); - } else { - f->cb_printf ("fs+%s\n", name); - } - break; - default: - f->cb_printf ("%-2d %s%s\n", ordinal, name, selected? " (selected)":""); - break; - } -} - -R_API int r_flag_space_stack_list(RFlag *f, int mode) { - RListIter *iter; - char *space; - int i = 0; - if (mode == 'j') { - f->cb_printf ("["); - } - r_list_foreach (f->spacestack, iter, space) { - print_space_stack (f, i++, space, false, mode); - } - if (f->space_idx == -1) { - print_space_stack (f, i++, "*", true, mode); - } else { - if (f->spaces[f->space_idx]) { - print_space_stack (f, i++, f->spaces[f->space_idx], true, mode); - } - } - if (mode == 'j') { - f->cb_printf ("]\n"); - } - return i; -} diff --git a/libr/include/r_flag.h b/libr/include/r_flag.h index 411500c01d..12d55f0adb 100644 --- a/libr/include/r_flag.h +++ b/libr/include/r_flag.h @@ -14,7 +14,6 @@ extern "C" { R_LIB_VERSION_HEADER(r_flag); #define R_FLAG_NAME_SIZE 512 -#define R_FLAG_SPACES_MAX 128 /* zones.c */ @@ -42,23 +41,20 @@ typedef struct r_flag_item_t { char *realname; /* real name, without any escaping */ ut64 offset; /* offset flagged by this item */ ut64 size; /* size of the flag item */ - int space; /* flag space this item belongs to */ + RSpace *space; /* flag space this item belongs to */ char *color; /* item color */ char *comment; /* item comment */ char *alias; /* used to define a flag based on a math expression (e.g. foo + 3) */ } RFlagItem; typedef struct r_flag_t { + RSpaces spaces; /* handle flag spaces */ st64 base; /* base address for all flag items */ - int space_idx; /* index of the selected space in spaces array */ - bool space_strict; /* when true returned flag items must belong to the selected space */ bool realnames; - char *spaces[R_FLAG_SPACES_MAX]; /* array of flag spaces */ Sdb *tags; RNum *num; RSkipList *by_off; /* flags sorted by offset, value=RFlagsAtOffset */ HtPP *ht_name; /* hashmap key=item name, value=RList of items */ - RList *spacestack; PrintfCallback cb_printf; #if R_FLAG_ZONE_USE_SDB Sdb *zones; @@ -76,7 +72,7 @@ typedef RFlagItem* (*RFlagSet)(RFlag *f, const char *name, ut64 addr, ut32 size) typedef bool (*RFlagUnset)(RFlag *f, RFlagItem *item); typedef bool (*RFlagUnsetName)(RFlag *f, const char *name); typedef bool (*RFlagUnsetOff)(RFlag *f, ut64 addr); -typedef int (*RFlagSetSpace)(RFlag *f, const char *name); +typedef RSpace *(*RFlagSetSpace)(RFlag *f, const char *name); typedef bool (*RFlagPopSpace)(RFlag *f); typedef bool (*RFlagPushSpace)(RFlag *f, const char *name); @@ -109,7 +105,7 @@ R_API RFlagItem *r_flag_get(RFlag *f, const char *name); R_API RFlagItem *r_flag_get_i(RFlag *f, ut64 off); R_API RFlagItem *r_flag_get_i2(RFlag *f, ut64 off); R_API RFlagItem *r_flag_get_at(RFlag *f, ut64 off, bool closest); -R_API RList *r_flag_all_list(RFlag *f); +R_API RList *r_flag_all_list(RFlag *f, bool by_space); R_API const RList* /**/ r_flag_get_list(RFlag *f, ut64 off); R_API char *r_flag_get_liststr(RFlag *f, ut64 off); R_API bool r_flag_unset(RFlag *f, RFlagItem *item); @@ -128,25 +124,55 @@ R_API int r_flag_rename(RFlag *f, RFlagItem *item, const char *name); R_API int r_flag_relocate(RFlag *f, ut64 off, ut64 off_mask, ut64 to); R_API bool r_flag_move (RFlag *f, ut64 at, ut64 to); R_API const char *r_flag_color(RFlag *f, RFlagItem *it, const char *color); +R_API int r_flag_count(RFlag *f, const char *glob); R_API void r_flag_foreach(RFlag *f, RFlagItemCb cb, void *user); R_API void r_flag_foreach_prefix(RFlag *f, const char *pfx, int pfx_len, RFlagItemCb cb, void *user); R_API void r_flag_foreach_range(RFlag *f, ut64 from, ut64 to, RFlagItemCb cb, void *user); R_API void r_flag_foreach_glob(RFlag *f, const char *glob, RFlagItemCb cb, void *user); -R_API void r_flag_foreach_space(RFlag *f, int space, RFlagItemCb cb, void *user); +R_API void r_flag_foreach_space(RFlag *f, const RSpace *space, RFlagItemCb cb, void *user); /* spaces */ -R_API int r_flag_space_get(RFlag *f, const char *name); -R_API const char *r_flag_space_get_i(RFlag *f, int idx); -R_API const char *r_flag_space_cur(RFlag *f); -R_API int r_flag_space_set(RFlag *f, const char *name); -R_API bool r_flag_space_set_i(RFlag *f, int idx); -R_API int r_flag_count(RFlag *f, const char *name); -R_API int r_flag_space_unset(RFlag *f, const char *fs); -R_API int r_flag_space_list(RFlag *f, int mode); -R_API bool r_flag_space_rename(RFlag *f, const char *oname, const char *nname); -R_API bool r_flag_space_pop(RFlag *f); -R_API bool r_flag_space_push(RFlag *f, const char *name); -R_API int r_flag_space_stack_list(RFlag *f, int mode); +static inline RSpace *r_flag_space_get(RFlag *f, const char *name) { + return r_spaces_get (&f->spaces, name); +} + +static inline RSpace *r_flag_space_cur(RFlag *f) { + return r_spaces_current (&f->spaces); +} + +static inline const char *r_flag_space_cur_name(RFlag *f) { + return r_spaces_current_name (&f->spaces); +} + +static inline RSpace *r_flag_space_set(RFlag *f, const char *name) { + return r_spaces_set (&f->spaces, name); +} + +static inline bool r_flag_space_unset(RFlag *f, const char *name) { + return r_spaces_unset (&f->spaces, name); +} + +static inline bool r_flag_space_rename(RFlag *f, const char *oname, const char *nname) { + return r_spaces_rename (&f->spaces, oname, nname); +} + +static inline bool r_flag_space_push(RFlag *f, const char *name) { + return r_spaces_push (&f->spaces, name); +} + +static inline bool r_flag_space_pop(RFlag *f) { + return r_spaces_pop (&f->spaces); +} + +static inline int r_flag_space_count(RFlag *f, const char *name) { + return r_spaces_count (&f->spaces, name); +} + +static inline bool r_flag_space_is_empty(RFlag *f) { + return r_spaces_is_empty (&f->spaces); +} + +#define r_flag_space_foreach(f, it, s) r_spaces_foreach (&(f)->spaces, (it), (s)) /* tags */ R_API RList *r_flag_tags_list(RFlag *f); diff --git a/libr/include/r_parse.h b/libr/include/r_parse.h index 96887953cd..e450fbb2c7 100644 --- a/libr/include/r_parse.h +++ b/libr/include/r_parse.h @@ -20,8 +20,8 @@ typedef RList* (*RAnalVarList)(RAnal *anal, RAnalFunction *fcn, int kind); typedef struct r_parse_t { void *user; - int flagspace; - int notin_flagspace; + RSpace *flagspace; + RSpace *notin_flagspace; bool pseudo; bool relsub; // replace rip relative expressions in instruction bool tailsub; // replace any immediate relative to current address with .. prefix syntax diff --git a/libr/include/r_util/r_spaces.h b/libr/include/r_util/r_spaces.h index d25c8a2725..fc107ca871 100644 --- a/libr/include/r_util/r_spaces.h +++ b/libr/include/r_util/r_spaces.h @@ -73,7 +73,7 @@ R_API RSpace *r_spaces_get(RSpaces *sp, const char *name); R_API RSpace *r_spaces_add(RSpaces *sp, const char *name); // Add and select a new RSpace if one does not already exist, otherwise return and select the existing one R_API RSpace *r_spaces_set(RSpaces *sp, const char *name); -// Remove the RSpace with the given name +// Remove the RSpace with the given name or all of them if name is NULL R_API bool r_spaces_unset(RSpaces *sp, const char *name); // Change the name of RSpace with oname to nname R_API bool r_spaces_rename(RSpaces *sp, const char *oname, const char *nname); @@ -92,6 +92,15 @@ static inline const char *r_spaces_current_name(RSpaces *sp) { return sp->current? sp->current->name: "*"; } +static inline bool r_spaces_is_empty(RSpaces *sp) { + RBIter it = r_rbtree_first (sp->spaces); + return it.len == 0; +} + +typedef RBIter RSpaceIter; +#define r_spaces_foreach(sp, it, s) \ + r_rbtree_foreach ((sp)->spaces, (it), (s), RSpace, rb) + #ifdef __cplusplus } #endif diff --git a/libr/parse/parse.c b/libr/parse/parse.c index cde13f14b4..b1562eb394 100644 --- a/libr/parse/parse.c +++ b/libr/parse/parse.c @@ -23,8 +23,8 @@ R_API RParse *r_parse_new() { return NULL; } p->parsers->free = NULL; // memleak - p->notin_flagspace = -1; - p->flagspace = -1; + p->notin_flagspace = NULL; + p->flagspace = NULL; p->pseudo = false; p->relsub = false; p->tailsub = false; @@ -275,11 +275,11 @@ static int filter(RParse *p, ut64 addr, RFlag *f, char *data, char *str, int len } } if (isvalidflag (flag)) { - if (p->notin_flagspace != -1) { + if (p->notin_flagspace) { if (p->flagspace == flag->space) { continue; } - } else if (p->flagspace != -1 && (p->flagspace != flag->space)) { + } else if (p->flagspace && (p->flagspace != flag->space)) { ptr = ptr2; continue; } @@ -588,10 +588,6 @@ R_API void r_parse_set_user_ptr(RParse *p, void *user) { p->user = user; } -R_API void r_parse_set_flagspace(RParse *p, int fs) { - p->flagspace = fs; -} - /* TODO: DEPRECATE */ R_API int r_parse_list(RParse *p) { RListIter *iter; diff --git a/libr/util/spaces.c b/libr/util/spaces.c index 4d425d4b96..cfd1d123df 100644 --- a/libr/util/spaces.c +++ b/libr/util/spaces.c @@ -69,6 +69,9 @@ static int name_space_cmp(const void *incoming, const RBNode *rb) { } R_API RSpace *r_spaces_get(RSpaces *sp, const char *name) { + if (!name) { + return NULL; + } RBNode *n = r_rbtree_find (sp->spaces, (void *)name, name_space_cmp); return n? container_of (n, RSpace, rb): NULL; } @@ -110,7 +113,7 @@ R_API RSpace *r_spaces_set(RSpaces *sp, const char *name) { return sp->current; } -R_API bool r_spaces_unset(RSpaces *sp, const char *name) { +static bool spaces_unset_single(RSpaces *sp, const char *name) { RSpace *space = r_spaces_get (sp, name); if (!space) { return false; @@ -121,6 +124,32 @@ R_API bool r_spaces_unset(RSpaces *sp, const char *name) { return r_rbtree_delete (&sp->spaces, (void *)name, name_space_cmp, space_node_free); } +R_API bool r_spaces_unset(RSpaces *sp, const char *name) { + if (name) { + return spaces_unset_single (sp, name); + } + + RList *names = r_list_newf ((RListFree)free); + if (!names) { + return false; + } + + RBIter it; + RSpace *s; + r_spaces_foreach (sp, it, s) { + r_list_append (names, strdup (s->name)); + } + + RListIter *lit; + const char *n; + bool res = false; + r_list_foreach (names, lit, n) { + res |= spaces_unset_single (sp, n); + } + r_list_free (names); + return res; +} + R_API int r_spaces_count(RSpaces *sp, const char *name) { RSpace *s = r_spaces_get (sp, name); if (!s) {