mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-27 15:10:53 +00:00
Add r_cmd_desc_remove
API to unregister commands (#17349)
This commit is contained in:
parent
1c74f3f729
commit
652df7f497
@ -30,6 +30,34 @@ static bool cmd_desc_set_parent(RCmdDesc *cd, RCmdDesc *parent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void cmd_desc_unset_parent(RCmdDesc *cd) {
|
||||
r_return_if_fail (cd && cd->parent);
|
||||
RCmdDesc *parent = cd->parent;
|
||||
r_pvector_remove_data (&parent->children, cd);
|
||||
parent->n_children--;
|
||||
cd->parent = NULL;
|
||||
}
|
||||
|
||||
static void cmd_desc_remove_from_ht_cmds(RCmd *cmd, RCmdDesc *cd) {
|
||||
void **it_cd;
|
||||
bool res = ht_pp_delete (cmd->ht_cmds, cd->name);
|
||||
r_return_if_fail (res);
|
||||
r_cmd_desc_children_foreach (cd, it_cd) {
|
||||
RCmdDesc *child_cd = *it_cd;
|
||||
cmd_desc_remove_from_ht_cmds (cmd, child_cd);
|
||||
}
|
||||
}
|
||||
|
||||
static void cmd_desc_free(RCmdDesc *cd) {
|
||||
if (!cd) {
|
||||
return;
|
||||
}
|
||||
|
||||
r_pvector_clear (&cd->children);
|
||||
free (cd->name);
|
||||
free (cd);
|
||||
}
|
||||
|
||||
static RCmdDesc *create_cmd_desc(RCmd *cmd, RCmdDesc *parent, RCmdDescType type, const char *name, const RCmdDescHelp *help) {
|
||||
RCmdDesc *res = R_NEW0 (RCmdDesc);
|
||||
if (!res) {
|
||||
@ -42,14 +70,14 @@ static RCmdDesc *create_cmd_desc(RCmd *cmd, RCmdDesc *parent, RCmdDescType type,
|
||||
}
|
||||
res->n_children = 0;
|
||||
res->help = help? help: ¬_defined_help;
|
||||
r_pvector_init (&res->children, (RPVectorFree)r_cmd_desc_free);
|
||||
r_pvector_init (&res->children, (RPVectorFree)cmd_desc_free);
|
||||
if (!ht_pp_insert (cmd->ht_cmds, name, res)) {
|
||||
goto err;
|
||||
}
|
||||
cmd_desc_set_parent (res, parent);
|
||||
return res;
|
||||
err:
|
||||
r_cmd_desc_free (res);
|
||||
cmd_desc_free (res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -97,7 +125,7 @@ R_API RCmd *r_cmd_free(RCmd *cmd) {
|
||||
R_FREE (cmd->cmds[i]);
|
||||
}
|
||||
}
|
||||
r_cmd_desc_free (cmd->root_cmd_desc);
|
||||
cmd_desc_free (cmd->root_cmd_desc);
|
||||
free (cmd);
|
||||
return NULL;
|
||||
}
|
||||
@ -1132,17 +1160,17 @@ R_API RCmdDesc *r_cmd_desc_oldinput_new(RCmd *cmd, RCmdDesc *parent, const char
|
||||
return res;
|
||||
}
|
||||
|
||||
R_API void r_cmd_desc_free(RCmdDesc *cd) {
|
||||
if (!cd) {
|
||||
return;
|
||||
}
|
||||
|
||||
r_pvector_clear (&cd->children);
|
||||
free (cd->name);
|
||||
free (cd);
|
||||
}
|
||||
|
||||
R_API RCmdDesc *r_cmd_desc_parent(RCmdDesc *cd) {
|
||||
r_return_val_if_fail (cd, NULL);
|
||||
return cd->parent;
|
||||
}
|
||||
|
||||
R_API bool r_cmd_desc_remove(RCmd *cmd, RCmdDesc *cd) {
|
||||
r_return_val_if_fail (cmd && cd, false);
|
||||
if (cd->parent) {
|
||||
cmd_desc_unset_parent (cd);
|
||||
}
|
||||
cmd_desc_remove_from_ht_cmds (cmd, cd);
|
||||
cmd_desc_free (cd);
|
||||
return true;
|
||||
}
|
||||
|
@ -167,8 +167,8 @@ R_API char *r_cmd_get_help(RCmd *cmd, RCmdParsedArgs *args, bool use_color);
|
||||
/* RCmdDescriptor */
|
||||
R_API RCmdDesc *r_cmd_desc_argv_new(RCmd *cmd, RCmdDesc *parent, const char *name, RCmdArgvCb cb, const RCmdDescHelp *help);
|
||||
R_API RCmdDesc *r_cmd_desc_oldinput_new(RCmd *cmd, RCmdDesc *parent, const char *name, RCmdCb cb, const RCmdDescHelp *help);
|
||||
R_API void r_cmd_desc_free(RCmdDesc *cd);
|
||||
R_API RCmdDesc *r_cmd_desc_parent(RCmdDesc *cd);
|
||||
R_API bool r_cmd_desc_remove(RCmd *cmd, RCmdDesc *cd);
|
||||
|
||||
#define r_cmd_desc_children_foreach(root, it_cd) r_pvector_foreach (&root->children, it_cd)
|
||||
|
||||
|
@ -385,6 +385,34 @@ bool test_cmd_oldinput_help(void) {
|
||||
mu_end;
|
||||
}
|
||||
|
||||
bool test_remove_cmd(void) {
|
||||
RCmd *cmd = r_cmd_new ();
|
||||
RCmdDesc *root = r_cmd_get_root (cmd);
|
||||
RCmdDesc *x_cd = r_cmd_desc_argv_new (cmd, root, "x", NULL, NULL);
|
||||
RCmdDesc *p_cd = r_cmd_desc_argv_new (cmd, root, "p", NULL, NULL);
|
||||
RCmdDesc *pd_cd = r_cmd_desc_argv_new (cmd, p_cd, "pd", pd_handler, NULL);
|
||||
r_cmd_desc_argv_new (cmd, p_cd, "px", pd_handler, NULL);
|
||||
|
||||
mu_assert_ptreq (r_cmd_get_desc (cmd, "x"), x_cd, "x is found");
|
||||
mu_assert_ptreq (r_cmd_get_desc (cmd, "pd"), pd_cd, "pd is found");
|
||||
mu_assert_eq (root->n_children, 2, "root has 2 commands as children");
|
||||
r_cmd_desc_remove (cmd, p_cd);
|
||||
mu_assert_eq (root->n_children, 1, "p was removed, now root has 1 command as children");
|
||||
mu_assert_null (r_cmd_get_desc (cmd, "p"), "p should not be found anymore");
|
||||
mu_assert_null (r_cmd_get_desc (cmd, "pd"), "pd should not be found anymore");
|
||||
mu_assert_null (r_cmd_get_desc (cmd, "px"), "px should not be found anymore");
|
||||
|
||||
void **it_cd;
|
||||
r_cmd_desc_children_foreach (root, it_cd) {
|
||||
RCmdDesc *cd = *it_cd;
|
||||
mu_assert_ptrneq (cd, p_cd, "p should not be found anymore");
|
||||
}
|
||||
|
||||
r_cmd_free (cmd);
|
||||
r_cons_free ();
|
||||
mu_end;
|
||||
}
|
||||
|
||||
int all_tests() {
|
||||
mu_run_test (test_parsed_args_noargs);
|
||||
mu_run_test (test_parsed_args_onearg);
|
||||
@ -401,6 +429,7 @@ int all_tests() {
|
||||
mu_run_test (test_cmd_help);
|
||||
mu_run_test (test_cmd_group_help);
|
||||
mu_run_test (test_cmd_oldinput_help);
|
||||
mu_run_test (test_remove_cmd);
|
||||
return tests_passed != tests_run;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user