Use PJ in config_print_node() (#1488)
* Remove `cb_printf` from `RzConfig` * Rename `rz_config_list` to `rz_core_config_print_all` * Remove `rz_cmd_eval` and run clang-format
This commit is contained in:
parent
0ef69ba2e8
commit
dba3fb0197
12 changed files with 222 additions and 499 deletions
|
|
@ -45,231 +45,6 @@ RZ_API void rz_config_node_free(void *n) {
|
|||
free(node);
|
||||
}
|
||||
|
||||
static void config_print_value_json(RzConfig *cfg, RzConfigNode *node) {
|
||||
rz_return_if_fail(cfg && node);
|
||||
const char *val = node->value;
|
||||
if (!val) {
|
||||
val = "0";
|
||||
}
|
||||
char *sval = rz_str_escape(val);
|
||||
if (rz_config_node_is_bool(node) || rz_config_node_is_int(node)) {
|
||||
if (!strncmp(val, "0x", 2)) {
|
||||
ut64 n = rz_num_get(NULL, val);
|
||||
cfg->cb_printf("%" PFMT64d, n);
|
||||
} else if (rz_str_isnumber(val) || (*val /* HACK */ && rz_str_is_bool(val))) {
|
||||
cfg->cb_printf("%s", val); // TODO: always use true/false for bool json str
|
||||
} else {
|
||||
cfg->cb_printf("\"%s\"", sval);
|
||||
}
|
||||
} else {
|
||||
cfg->cb_printf("\"%s\"", sval);
|
||||
}
|
||||
free(sval);
|
||||
}
|
||||
|
||||
static void config_print_node(RzConfig *cfg, RzConfigNode *node, const char *pfx, const char *sfx, bool verbose, bool json) {
|
||||
rz_return_if_fail(cfg && node && pfx && sfx);
|
||||
char *option;
|
||||
bool isFirst;
|
||||
RzListIter *iter;
|
||||
char *es = NULL;
|
||||
|
||||
if (json) {
|
||||
if (verbose) {
|
||||
cfg->cb_printf("{");
|
||||
cfg->cb_printf("\"name\":\"%s\",", node->name);
|
||||
cfg->cb_printf("\"value\":");
|
||||
config_print_value_json(cfg, node);
|
||||
cfg->cb_printf(",\"type\":\"%s\",", rz_config_node_type(node));
|
||||
es = rz_str_escape(node->desc);
|
||||
if (es) {
|
||||
cfg->cb_printf("\"desc\":\"%s\",", es);
|
||||
free(es);
|
||||
}
|
||||
cfg->cb_printf("\"ro\":%s", rz_str_bool(rz_config_node_is_ro(node)));
|
||||
if (!rz_list_empty(node->options)) {
|
||||
isFirst = true;
|
||||
cfg->cb_printf(",\"options\":[");
|
||||
rz_list_foreach (node->options, iter, option) {
|
||||
es = rz_str_escape(option);
|
||||
if (es) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
cfg->cb_printf(",");
|
||||
}
|
||||
cfg->cb_printf("\"%s\"", es);
|
||||
free(es);
|
||||
}
|
||||
}
|
||||
cfg->cb_printf("]");
|
||||
}
|
||||
cfg->cb_printf("}");
|
||||
} else {
|
||||
cfg->cb_printf("\"%s\":", node->name);
|
||||
config_print_value_json(cfg, node);
|
||||
}
|
||||
} else {
|
||||
if (verbose) {
|
||||
cfg->cb_printf("%s%s = %s%s %s; %s", pfx,
|
||||
node->name, node->value, sfx,
|
||||
rz_config_node_is_ro(node) ? "(ro)" : "",
|
||||
node->desc);
|
||||
if (!rz_list_empty(node->options)) {
|
||||
isFirst = true;
|
||||
cfg->cb_printf(" [");
|
||||
rz_list_foreach (node->options, iter, option) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
cfg->cb_printf(", ");
|
||||
}
|
||||
cfg->cb_printf("%s", option);
|
||||
}
|
||||
cfg->cb_printf("]");
|
||||
}
|
||||
cfg->cb_printf("\n");
|
||||
} else {
|
||||
cfg->cb_printf("%s%s = %s%s\n", pfx,
|
||||
node->name, node->value, sfx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API void rz_config_list(RzConfig *cfg, const char *str, int rad) {
|
||||
rz_return_if_fail(cfg);
|
||||
RzConfigNode *node;
|
||||
RzListIter *iter;
|
||||
const char *sfx = "";
|
||||
const char *pfx = "";
|
||||
int len = 0;
|
||||
bool verbose = false;
|
||||
bool json = false;
|
||||
bool isFirst = false;
|
||||
|
||||
if (RZ_STR_ISNOTEMPTY(str)) {
|
||||
str = rz_str_trim_head_ro(str);
|
||||
len = strlen(str);
|
||||
if (len > 0 && str[0] == 'j') {
|
||||
str++;
|
||||
len--;
|
||||
json = true;
|
||||
rad = 'J';
|
||||
}
|
||||
if (len > 0 && str[0] == ' ') {
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
if (strlen(str) == 0) {
|
||||
str = NULL;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
switch (rad) {
|
||||
case 1:
|
||||
pfx = "\"e ";
|
||||
sfx = "\"";
|
||||
/* fallthrou */
|
||||
case 0:
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
if (!str || (str && (!strncmp(str, node->name, len)))) {
|
||||
config_print_node(cfg, node, pfx, sfx, verbose, json);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
if (!str || (str && (!strncmp(str, node->name, len)))) {
|
||||
if (!str || !strncmp(str, node->name, len)) {
|
||||
cfg->cb_printf("%20s: %s\n", node->name,
|
||||
node->desc ? node->desc : "");
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if (str && *str) {
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
char *space = strdup(node->name);
|
||||
char *dot = strchr(space, '.');
|
||||
if (dot) {
|
||||
*dot = 0;
|
||||
}
|
||||
if (!strcmp(str, space)) {
|
||||
cfg->cb_printf("%s\n", dot + 1);
|
||||
}
|
||||
free(space);
|
||||
}
|
||||
} else {
|
||||
char *oldSpace = NULL;
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
char *space = strdup(node->name);
|
||||
char *dot = strchr(space, '.');
|
||||
if (dot) {
|
||||
*dot = 0;
|
||||
}
|
||||
if (oldSpace) {
|
||||
if (!strcmp(space, oldSpace)) {
|
||||
free(space);
|
||||
continue;
|
||||
}
|
||||
free(oldSpace);
|
||||
oldSpace = space;
|
||||
} else {
|
||||
oldSpace = space;
|
||||
}
|
||||
cfg->cb_printf("%s\n", space);
|
||||
}
|
||||
free(oldSpace);
|
||||
}
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
if (!str || (str && (!strncmp(str, node->name, len)))) {
|
||||
config_print_node(cfg, node, pfx, sfx, verbose, json);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
if (!str || (str && (!strncmp(str, node->name, len)))) {
|
||||
cfg->cb_printf("%s\n", node->name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'J':
|
||||
verbose = true;
|
||||
/* fallthrou */
|
||||
case 'j':
|
||||
isFirst = true;
|
||||
if (verbose) {
|
||||
cfg->cb_printf("[");
|
||||
} else {
|
||||
cfg->cb_printf("{");
|
||||
}
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
if (!str || (str && (!strncmp(str, node->name, len)))) {
|
||||
if (!str || !strncmp(str, node->name, len)) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
cfg->cb_printf(",");
|
||||
}
|
||||
config_print_node(cfg, node, pfx, sfx, verbose, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (verbose) {
|
||||
cfg->cb_printf("]\n");
|
||||
} else {
|
||||
cfg->cb_printf("}\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API RzConfigNode *rz_config_node_get(RzConfig *cfg, const char *name) {
|
||||
rz_return_val_if_fail(cfg && name, NULL);
|
||||
return ht_pp_find(cfg->ht, name, NULL);
|
||||
|
|
@ -674,65 +449,6 @@ beach:
|
|||
return node;
|
||||
}
|
||||
|
||||
static void __evalString(RzConfig *cfg, char *name) {
|
||||
if (!*name) {
|
||||
return;
|
||||
}
|
||||
char *eq = strchr(name, '=');
|
||||
if (eq) {
|
||||
*eq++ = 0;
|
||||
rz_str_trim(name);
|
||||
rz_str_trim(eq);
|
||||
if (*name) {
|
||||
(void)rz_config_set(cfg, name, eq);
|
||||
}
|
||||
} else {
|
||||
if (rz_str_endswith(name, ".")) {
|
||||
rz_config_list(cfg, name, 0);
|
||||
} else {
|
||||
const char *v = rz_config_get(cfg, name);
|
||||
if (v) {
|
||||
cfg->cb_printf("%s\n", v);
|
||||
} else {
|
||||
eprintf("Invalid config key %s\n", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RZ_API bool rz_config_eval(RzConfig *cfg, const char *str, bool many) {
|
||||
rz_return_val_if_fail(cfg && str, false);
|
||||
|
||||
char *s = rz_str_trim_dup(str);
|
||||
|
||||
if (!*s || !strcmp(s, "help")) {
|
||||
rz_config_list(cfg, NULL, 0);
|
||||
free(s);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*s == '-') {
|
||||
rz_config_rm(cfg, s + 1);
|
||||
free(s);
|
||||
return false;
|
||||
}
|
||||
if (many) {
|
||||
// space separated list of k=v k=v,..
|
||||
// if you want to use spaces go for base64 or e.
|
||||
RzList *list = rz_str_split_list(s, ",", 0);
|
||||
RzListIter *iter;
|
||||
char *name;
|
||||
rz_list_foreach (list, iter, name) {
|
||||
__evalString(cfg, name);
|
||||
}
|
||||
free(s);
|
||||
return true;
|
||||
}
|
||||
__evalString(cfg, s);
|
||||
free(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int cmp(RzConfigNode *a, RzConfigNode *b) {
|
||||
return strcmp(a->name, b->name);
|
||||
}
|
||||
|
|
@ -765,7 +481,6 @@ RZ_API RzConfig *rz_config_new(void *user) {
|
|||
cfg->user = user;
|
||||
cfg->num = NULL;
|
||||
cfg->lock = 0;
|
||||
cfg->cb_printf = (void *)printf;
|
||||
return cfg;
|
||||
}
|
||||
|
||||
|
|
@ -782,7 +497,6 @@ RZ_API RzConfig *rz_config_clone(RzConfig *cfg) {
|
|||
rz_list_append(c->nodes, nn);
|
||||
}
|
||||
c->lock = cfg->lock;
|
||||
c->cb_printf = cfg->cb_printf;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
@ -831,3 +545,24 @@ RZ_API bool rz_config_unserialize(RZ_NONNULL RzConfig *config, RZ_NONNULL Sdb *d
|
|||
sdb_foreach(db, load_config_cb, config);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sets the configuration variable and its value passed as argument
|
||||
*
|
||||
* \param cfg reference to RzConfig
|
||||
* \param str reference the configuration variable string (eg, 'asm.arch=x86')
|
||||
*/
|
||||
RZ_API bool rz_config_eval(RZ_NONNULL RzConfig *cfg, RZ_NONNULL const char *str) {
|
||||
rz_return_val_if_fail(str, false);
|
||||
|
||||
char *name = rz_str_trim_dup(str);
|
||||
char *value = strchr(name, '=');
|
||||
if (!value) {
|
||||
free(name);
|
||||
return false;
|
||||
}
|
||||
*value++ = 0;
|
||||
rz_config_set(cfg, name, value);
|
||||
free(name);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1737,6 +1737,122 @@ RZ_API bool rz_core_esil_cmd(RzAnalysisEsil *esil, const char *cmd, ut64 a1, ut6
|
|||
return false;
|
||||
}
|
||||
|
||||
static void config_print_node(RzConfig *cfg, RzConfigNode *node, RzCmdStateOutput *state) {
|
||||
rz_return_if_fail(cfg && node && state);
|
||||
char *option;
|
||||
bool isFirst;
|
||||
RzOutputMode mode = state->mode;
|
||||
PJ *pj = state->d.pj;
|
||||
RzListIter *iter;
|
||||
char *es = NULL;
|
||||
|
||||
switch (mode) {
|
||||
case RZ_OUTPUT_MODE_JSON:
|
||||
if (rz_str_isnumber(node->value)) {
|
||||
pj_kn(pj, node->name, rz_num_math(NULL, node->value));
|
||||
return;
|
||||
} else if (rz_str_is_bool(node->value)) {
|
||||
pj_kb(pj, node->name, (node->value));
|
||||
return;
|
||||
} else {
|
||||
pj_ks(pj, node->name, node->value);
|
||||
}
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_LONG_JSON:
|
||||
pj_o(pj);
|
||||
pj_ks(pj, "name", node->name);
|
||||
if (rz_str_isnumber(node->value)) {
|
||||
pj_kn(pj, "value", rz_num_math(NULL, node->value));
|
||||
} else if (rz_str_is_bool(node->value)) {
|
||||
pj_kb(pj, "value", (node->value));
|
||||
} else {
|
||||
pj_ks(pj, "value", node->value);
|
||||
}
|
||||
pj_ks(pj, "type", rz_config_node_type(node));
|
||||
es = rz_str_escape(node->desc);
|
||||
if (es) {
|
||||
pj_ks(pj, "desc", es);
|
||||
free(es);
|
||||
}
|
||||
pj_kb(pj, "ro", rz_config_node_is_ro(node));
|
||||
if (!rz_list_empty(node->options)) {
|
||||
pj_ka(pj, "options");
|
||||
rz_list_foreach (node->options, iter, option) {
|
||||
pj_s(pj, option);
|
||||
}
|
||||
pj_end(pj);
|
||||
}
|
||||
pj_end(pj);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_LONG:
|
||||
rz_cons_printf("%s = %s %s; %s",
|
||||
node->name, node->value,
|
||||
rz_config_node_is_ro(node) ? "(ro)" : "",
|
||||
node->desc);
|
||||
if (!rz_list_empty(node->options)) {
|
||||
isFirst = true;
|
||||
rz_cons_printf(" [");
|
||||
rz_list_foreach (node->options, iter, option) {
|
||||
if (isFirst) {
|
||||
isFirst = false;
|
||||
} else {
|
||||
rz_cons_printf(", ");
|
||||
}
|
||||
rz_cons_printf("%s", option);
|
||||
}
|
||||
rz_cons_printf("]");
|
||||
}
|
||||
rz_cons_println("");
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_QUIET:
|
||||
rz_cons_printf("%s=%s\n", node->name, node->value);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_RIZIN:
|
||||
es = rz_cmd_escape_arg(node->value, RZ_CMD_ESCAPE_ONE_ARG);
|
||||
rz_cons_printf("e %s=%s\n", node->name, es);
|
||||
free(es);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_STANDARD:
|
||||
rz_cons_printf("%20s: %s\n", node->name,
|
||||
node->desc ? node->desc : "");
|
||||
break;
|
||||
default:
|
||||
rz_warn_if_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Prints the configuation variables with their description and its values
|
||||
*
|
||||
* \param cfg reference to RzConfig
|
||||
* \param str reference to the key that can be passed to filter the output
|
||||
* \param state reference to RzCmdStateOutput
|
||||
*/
|
||||
RZ_API void rz_core_config_print_all(RzConfig *cfg, const char *str, RzCmdStateOutput *state) {
|
||||
rz_return_if_fail(cfg);
|
||||
RzConfigNode *node;
|
||||
RzListIter *iter;
|
||||
PJ *pj = state->d.pj;
|
||||
RzOutputMode mode = state->mode;
|
||||
|
||||
if (mode == RZ_OUTPUT_MODE_LONG_JSON) {
|
||||
pj_a(pj);
|
||||
} else if (mode == RZ_OUTPUT_MODE_JSON) {
|
||||
pj_o(pj);
|
||||
}
|
||||
|
||||
rz_list_foreach (cfg->nodes, iter, node) {
|
||||
if (rz_str_startswith(node->name, str)) {
|
||||
config_print_node(cfg, node, state);
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == RZ_OUTPUT_MODE_LONG_JSON || mode == RZ_OUTPUT_MODE_JSON) {
|
||||
pj_end(pj);
|
||||
}
|
||||
}
|
||||
|
||||
static bool cb_cmd_esil_ioer(void *user, void *data) {
|
||||
RzCore *core = (RzCore *)user;
|
||||
RzConfigNode *node = (RzConfigNode *)data;
|
||||
|
|
@ -2789,7 +2905,6 @@ RZ_API int rz_core_config_init(RzCore *core) {
|
|||
if (!cfg) {
|
||||
return 0;
|
||||
}
|
||||
cfg->cb_printf = rz_cons_printf;
|
||||
cfg->num = core->num;
|
||||
/* dir.prefix is used in other modules, set it first */
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6490,7 +6490,6 @@ RZ_API void rz_core_cmd_init(RzCore *core) {
|
|||
{ "c", "compare memory", rz_cmd_cmp },
|
||||
{ "C", "code metadata", rz_cmd_meta },
|
||||
{ "d", "debugger operations", rz_cmd_debug },
|
||||
{ "e", "evaluate configuration variable", rz_cmd_eval },
|
||||
{ "f", "get/set flags", rz_cmd_flag },
|
||||
{ "g", "egg manipulation", rz_cmd_egg },
|
||||
{ "k", "perform sdb query", rz_cmd_kuery },
|
||||
|
|
|
|||
|
|
@ -5912,7 +5912,7 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) {
|
|||
|
||||
RzCmdDesc *e_cd = rz_cmd_desc_group_new(core->rcmd, root_cd, "e", rz_eval_getset_handler, &eval_getset_help, &e_help);
|
||||
rz_warn_if_fail(e_cd);
|
||||
RzCmdDesc *eval_list_cd = rz_cmd_desc_argv_modes_new(core->rcmd, e_cd, "el", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_LONG | RZ_OUTPUT_MODE_LONG_JSON, rz_eval_list_handler, &eval_list_help);
|
||||
RzCmdDesc *eval_list_cd = rz_cmd_desc_argv_state_new(core->rcmd, e_cd, "el", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_RIZIN | RZ_OUTPUT_MODE_JSON | RZ_OUTPUT_MODE_QUIET | RZ_OUTPUT_MODE_LONG | RZ_OUTPUT_MODE_LONG_JSON, rz_eval_list_handler, &eval_list_help);
|
||||
rz_warn_if_fail(eval_list_cd);
|
||||
|
||||
RzCmdDesc *eval_reset_cd = rz_cmd_desc_argv_new(core->rcmd, e_cd, "e-", rz_eval_reset_handler, &eval_reset_help);
|
||||
|
|
|
|||
|
|
@ -164,7 +164,7 @@ RZ_IPI RzCmdStatus rz_cmd_debug_heap_block_flag_handler(RzCore *core, int argc,
|
|||
RZ_IPI int rz_cmd_debug_heap_jemalloc(void *data, const char *input);
|
||||
RZ_IPI int rz_cmd_debug(void *data, const char *input);
|
||||
RZ_IPI RzCmdStatus rz_eval_getset_handler(RzCore *core, int argc, const char **argv);
|
||||
RZ_IPI RzCmdStatus rz_eval_list_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode);
|
||||
RZ_IPI RzCmdStatus rz_eval_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state);
|
||||
RZ_IPI RzCmdStatus rz_eval_reset_handler(RzCore *core, int argc, const char **argv);
|
||||
RZ_IPI RzCmdStatus rz_eval_bool_invert_handler(RzCore *core, int argc, const char **argv);
|
||||
RZ_IPI int rz_eval_color(void *data, const char *input);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ commands:
|
|||
comment: "Set asm.bytes to true and asm.offset to false"
|
||||
- name: el
|
||||
cname: eval_list
|
||||
type: RZ_CMD_DESC_TYPE_ARGV_STATE
|
||||
summary: List config variables with their descriptions
|
||||
modes:
|
||||
- RZ_OUTPUT_MODE_STANDARD
|
||||
|
|
|
|||
|
|
@ -5,31 +5,6 @@
|
|||
#include <stdbool.h>
|
||||
#include "rz_core.h"
|
||||
|
||||
static const char *help_msg_e[] = {
|
||||
"Usage:", "e [var[=value]]", "Evaluable vars",
|
||||
"e", "?asm.bytes", "show description",
|
||||
"e", "??", "list config vars with description",
|
||||
"e", " a", "get value of var 'a'",
|
||||
"e", " a=b", "set var 'a' the 'b' value",
|
||||
"e var=?", "", "print all valid values of var",
|
||||
"e var=??", "", "print all valid values of var with description",
|
||||
"e.", "a=b", "same as 'e a=b' but without using a space",
|
||||
"e,", "k=v,k=v,k=v", "comma separated k[=v]",
|
||||
"e-", "", "reset config vars",
|
||||
"e*", "", "dump config vars in r commands",
|
||||
"e!", "a", "invert the boolean value of 'a' var",
|
||||
"ec", " [k] [color]", "set color for given key (prompt, offset, ...)",
|
||||
"ee", "var", "open editor to change the value of var",
|
||||
"ej", "", "list config vars in JSON",
|
||||
"env", " [k[=v]]", "get/set environment variable",
|
||||
"er", " [key]", "set config key as readonly. no way back",
|
||||
"es", " [space]", "list all eval spaces [or keys]",
|
||||
"et", " [key]", "show type of given config variable",
|
||||
"ev", " [key]", "list config vars in verbose format",
|
||||
"evj", " [key]", "list config vars in verbose format in JSON",
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *help_msg_ec[] = {
|
||||
"Usage ec[s?] [key][[=| ]fg] [bg]", "", "",
|
||||
"ec", " [key]", "list all/key color keys",
|
||||
|
|
@ -498,145 +473,7 @@ RZ_IPI int rz_eval_color(void *data, const char *input) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
RZ_IPI int rz_cmd_eval(void *data, const char *input) {
|
||||
RzCore *core = (RzCore *)data;
|
||||
switch (input[0]) {
|
||||
case '\0': // "e"
|
||||
rz_config_list(core->config, NULL, 0);
|
||||
break;
|
||||
case '?': // "e?"
|
||||
default:
|
||||
switch (input[1]) {
|
||||
case '\0': rz_core_cmd_help(core, help_msg_e); break;
|
||||
case '?': rz_config_list(core->config, input + 2, 2); break;
|
||||
default: rz_config_list(core->config, input + 1, 2); break;
|
||||
}
|
||||
break;
|
||||
case 't': // "et"
|
||||
if (input[1] == 'a') {
|
||||
rz_cons_printf("%s\n", (rz_num_rand(10) % 2) ? "wen" : "son");
|
||||
} else if (input[1] == ' ' && input[2]) {
|
||||
RzConfigNode *node = rz_config_node_get(core->config, input + 2);
|
||||
if (node) {
|
||||
const char *type = rz_config_node_type(node);
|
||||
if (type && *type) {
|
||||
rz_cons_println(type);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eprintf("Usage: et [varname] ; show type of eval var\n");
|
||||
}
|
||||
break;
|
||||
case 'n': // "en"
|
||||
if (!strchr(input, '=')) {
|
||||
char *var, *p;
|
||||
var = strchr(input, ' ');
|
||||
if (var)
|
||||
while (*var == ' ')
|
||||
var++;
|
||||
p = rz_sys_getenv(var);
|
||||
if (p) {
|
||||
rz_cons_println(p);
|
||||
free(p);
|
||||
} else {
|
||||
char **e = rz_sys_get_environ();
|
||||
while (e && *e) {
|
||||
rz_cons_println(*e);
|
||||
e++;
|
||||
}
|
||||
}
|
||||
} else if (strlen(input) > 3) {
|
||||
char *v, *k = strdup(input + 3);
|
||||
if (!k)
|
||||
break;
|
||||
v = strchr(k, '=');
|
||||
if (v) {
|
||||
*v++ = 0;
|
||||
rz_str_trim(k);
|
||||
rz_str_trim(v);
|
||||
rz_sys_setenv(k, v);
|
||||
}
|
||||
free(k);
|
||||
}
|
||||
return true;
|
||||
case 'x': // exit
|
||||
// XXX we need headers for the cmd_xxx files.
|
||||
return rz_cmd_quit(data, "");
|
||||
case 'j': // json
|
||||
rz_config_list(core->config, NULL, 'j');
|
||||
break;
|
||||
case 'v': // verbose
|
||||
rz_config_list(core->config, input + 1, 'v');
|
||||
break;
|
||||
case 'q': // quiet list of eval keys
|
||||
rz_config_list(core->config, NULL, 'q');
|
||||
break;
|
||||
case 'c': // "ec"
|
||||
rz_eval_color(core, input + 1);
|
||||
break;
|
||||
case 'e': // "ee"
|
||||
if (input[1] == ' ') {
|
||||
char *p;
|
||||
const char *input2 = strchr(input + 2, ' ');
|
||||
input2 = (input2) ? input2 + 1 : input + 2;
|
||||
const char *val = rz_config_get(core->config, input2);
|
||||
p = rz_core_editor(core, NULL, val);
|
||||
if (p) {
|
||||
rz_str_replace_char(p, '\n', ';');
|
||||
rz_config_set(core->config, input2, p);
|
||||
}
|
||||
} else {
|
||||
eprintf("Usage: ee varname # use $EDITOR to edit this config value\n");
|
||||
}
|
||||
break;
|
||||
case '!': // "e!"
|
||||
input = rz_str_trim_head_ro(input + 1);
|
||||
if (!rz_config_toggle(core->config, input)) {
|
||||
eprintf("rz_config: '%s' is not a boolean variable.\n", input);
|
||||
}
|
||||
break;
|
||||
case 's': // "es"
|
||||
rz_config_list(core->config, (input[1]) ? input + 1 : NULL, 's');
|
||||
break;
|
||||
case '-': // "e-"
|
||||
rz_core_config_init(core);
|
||||
//eprintf ("BUG: 'e-' command locks the eval hashtable. patches are welcome :)\n");
|
||||
break;
|
||||
case '*': // "e*"
|
||||
rz_config_list(core->config, NULL, 1);
|
||||
break;
|
||||
case 'r': // "er"
|
||||
if (input[1]) {
|
||||
const char *key = input + ((input[1] == ' ') ? 2 : 1);
|
||||
if (!rz_config_readonly(core->config, key)) {
|
||||
eprintf("cannot find key '%s'\n", key);
|
||||
}
|
||||
} else {
|
||||
eprintf("Usage: er [key] # make an eval key PERMANENTLY read only\n");
|
||||
}
|
||||
break;
|
||||
case ',': // "e."
|
||||
rz_config_eval(core->config, input + 1, true);
|
||||
break;
|
||||
case '.': // "e "
|
||||
case ' ': // "e "
|
||||
if (rz_str_endswith(input, ".")) {
|
||||
rz_config_list(core->config, input + 1, 0);
|
||||
} else {
|
||||
// XXX we cant do "e cmd.gprompt=dr=", because the '=' is a token, and quotes dont affect him
|
||||
rz_config_eval(core->config, input + 1, false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_eval_getset_handler(RzCore *core, int argc, const char **argv) {
|
||||
if (argc == 1) {
|
||||
rz_config_list(core->config, NULL, 0);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 1; i < argc; i++) {
|
||||
RzList *l = rz_str_split_duplist_n(argv[i], "=", 1, false);
|
||||
|
|
@ -655,7 +492,11 @@ 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.
|
||||
rz_config_list(core->config, key, false);
|
||||
RzCmdStateOutput state = { 0 };
|
||||
rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET);
|
||||
rz_core_config_print_all(core->config, key, &state);
|
||||
rz_cmd_state_output_print(&state);
|
||||
rz_cmd_state_output_fini(&state);
|
||||
} else if (llen == 1) {
|
||||
// no value was set, show the value of the key
|
||||
const char *v = rz_config_get(core->config, key);
|
||||
|
|
@ -668,39 +509,14 @@ RZ_IPI RzCmdStatus rz_eval_getset_handler(RzCore *core, int argc, const char **a
|
|||
char *value = rz_list_get_n(l, 1);
|
||||
rz_config_set(core->config, key, value);
|
||||
}
|
||||
|
||||
rz_list_free(l);
|
||||
}
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
RZ_IPI RzCmdStatus rz_eval_list_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
|
||||
RZ_IPI RzCmdStatus rz_eval_list_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) {
|
||||
const char *arg = argc > 1 ? argv[1] : "";
|
||||
switch (mode) {
|
||||
case RZ_OUTPUT_MODE_STANDARD:
|
||||
rz_config_list(core->config, arg, 2);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_JSON:
|
||||
rz_config_list(core->config, arg, 'j');
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_RIZIN:
|
||||
rz_config_list(core->config, arg, 1);
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_QUIET:
|
||||
rz_config_list(core->config, arg, 'q');
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_LONG:
|
||||
rz_config_list(core->config, arg, 'v');
|
||||
break;
|
||||
case RZ_OUTPUT_MODE_LONG_JSON: {
|
||||
char *a = rz_str_newf("j%s", arg);
|
||||
rz_config_list(core->config, a, 'v');
|
||||
free(a);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return RZ_CMD_STATUS_ERROR;
|
||||
}
|
||||
rz_core_config_print_all(core->config, arg, state);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -741,7 +557,34 @@ RZ_IPI RzCmdStatus rz_eval_readonly_handler(RzCore *core, int argc, const char *
|
|||
|
||||
RZ_IPI RzCmdStatus rz_eval_spaces_handler(RzCore *core, int argc, const char **argv) {
|
||||
const char *arg = argc > 1 ? argv[1] : "";
|
||||
rz_config_list(core->config, arg, 's');
|
||||
RzConfigNode *node;
|
||||
RzListIter *iter;
|
||||
char *oldSpace = NULL;
|
||||
rz_list_foreach (core->config->nodes, iter, node) {
|
||||
char *space = strdup(node->name);
|
||||
char *dot = strchr(space, '.');
|
||||
if (dot) {
|
||||
*dot = 0;
|
||||
}
|
||||
if (arg && *arg) {
|
||||
if (!strcmp(arg, space)) {
|
||||
rz_cons_println(dot + 1);
|
||||
}
|
||||
free(space);
|
||||
continue;
|
||||
} else if (oldSpace) {
|
||||
if (!strcmp(space, oldSpace)) {
|
||||
free(space);
|
||||
continue;
|
||||
}
|
||||
free(oldSpace);
|
||||
oldSpace = space;
|
||||
} else {
|
||||
oldSpace = space;
|
||||
}
|
||||
rz_cons_println(space);
|
||||
}
|
||||
free(oldSpace);
|
||||
return RZ_CMD_STATUS_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ typedef struct rz_config_t {
|
|||
int lock;
|
||||
void *user;
|
||||
RzNum *num;
|
||||
PrintfCallback cb_printf;
|
||||
RzList *nodes;
|
||||
HtPP *ht;
|
||||
} RzConfig;
|
||||
|
|
@ -76,7 +75,6 @@ RZ_API RzConfig *rz_config_new(void *user);
|
|||
RZ_API RzConfig *rz_config_clone(RzConfig *cfg);
|
||||
RZ_API void rz_config_free(RzConfig *cfg);
|
||||
RZ_API void rz_config_lock(RzConfig *cfg, int l);
|
||||
RZ_API bool rz_config_eval(RzConfig *cfg, const char *str, bool many);
|
||||
RZ_API void rz_config_bump(RzConfig *cfg, const char *key);
|
||||
RZ_API RzConfigNode *rz_config_set_i(RzConfig *cfg, const char *name, const ut64 i);
|
||||
RZ_API RzConfigNode *rz_config_set_b(RzConfig *cfg, const char *name, bool value);
|
||||
|
|
@ -89,13 +87,13 @@ RZ_API bool rz_config_get_b(RzConfig *cfg, const char *name);
|
|||
RZ_API const char *rz_config_get(RzConfig *cfg, const char *name);
|
||||
RZ_API const char *rz_config_desc(RzConfig *cfg, const char *name, const char *desc);
|
||||
RZ_API const char *rz_config_node_desc(RzConfigNode *node, const char *desc);
|
||||
RZ_API void rz_config_list(RzConfig *cfg, const char *str, int rad);
|
||||
RZ_API RzConfigNode *rz_config_node_get(RzConfig *cfg, const char *name);
|
||||
RZ_API RzConfigNode *rz_config_node_new(const char *name, const char *value);
|
||||
RZ_API void rz_config_node_free(void *n);
|
||||
RZ_API void rz_config_node_value_format_i(char *buf, size_t buf_size, const ut64 i, RZ_NULLABLE RzConfigNode *node);
|
||||
RZ_API bool rz_config_toggle(RzConfig *cfg, const char *name);
|
||||
RZ_API bool rz_config_readonly(RzConfig *cfg, const char *key);
|
||||
RZ_API bool rz_config_eval(RzConfig *cfg, const char *str);
|
||||
|
||||
RZ_API void rz_config_set_sort_column(char *column);
|
||||
RZ_API bool rz_config_set_setter(RzConfig *cfg, const char *key, RzConfigCallback cb);
|
||||
|
|
|
|||
|
|
@ -431,6 +431,8 @@ RZ_API RzCore *rz_core_ncast(ut64 p);
|
|||
RZ_API RzCore *rz_core_cast(void *p);
|
||||
RZ_API bool rz_core_bin_load_structs(RZ_NONNULL RzCore *core, RZ_NONNULL const char *file);
|
||||
RZ_API int rz_core_config_init(RzCore *core);
|
||||
RZ_API bool rz_core_config_eval_and_print(RzCore *core, const char *str, bool many);
|
||||
RZ_API void rz_core_config_print_all(RzConfig *cfg, const char *str, RzCmdStateOutput *state);
|
||||
RZ_API void rz_core_parse_rizinrc(RzCore *r);
|
||||
RZ_API int rz_core_prompt(RzCore *core, int sync);
|
||||
RZ_API int rz_core_prompt_exec(RzCore *core);
|
||||
|
|
|
|||
|
|
@ -519,7 +519,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
|
|||
if (!strcmp(opt.arg, "q")) {
|
||||
rz_core_cmd0(r, "eq");
|
||||
} else {
|
||||
rz_config_eval(r->config, opt.arg, false);
|
||||
rz_config_eval(r->config, opt.arg);
|
||||
rz_list_append(evals, (void *)opt.arg);
|
||||
}
|
||||
break;
|
||||
|
|
@ -1198,7 +1198,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
|
|||
rz_core_seek(r, mapaddr, true);
|
||||
}
|
||||
rz_list_foreach (evals, iter, cmdn) {
|
||||
rz_config_eval(r->config, cmdn, false);
|
||||
rz_config_eval(r->config, cmdn);
|
||||
rz_cons_flush();
|
||||
}
|
||||
if (asmarch) {
|
||||
|
|
@ -1272,7 +1272,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
|
|||
}
|
||||
|
||||
rz_list_foreach (evals, iter, cmdn) {
|
||||
rz_config_eval(r->config, cmdn, false);
|
||||
rz_config_eval(r->config, cmdn);
|
||||
rz_cons_flush();
|
||||
}
|
||||
|
||||
|
|
@ -1296,7 +1296,7 @@ RZ_API int rz_main_rizin(int argc, const char **argv) {
|
|||
rz_core_block_read(r);
|
||||
|
||||
rz_list_foreach (evals, iter, cmdn) {
|
||||
rz_config_eval(r->config, cmdn, false);
|
||||
rz_config_eval(r->config, cmdn);
|
||||
rz_cons_flush();
|
||||
}
|
||||
if (asmarch) {
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ NAME=e-dot
|
|||
FILE==
|
||||
CMDS=e zoom.
|
||||
EXPECT=<<EOF
|
||||
zoom.byte = h
|
||||
zoom.from = 0
|
||||
zoom.in = io.map
|
||||
zoom.maxsz = 512
|
||||
zoom.to = 0
|
||||
zoom.byte=h
|
||||
zoom.from=0
|
||||
zoom.in=io.map
|
||||
zoom.maxsz=512
|
||||
zoom.to=0
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
@ -82,13 +82,13 @@ RUN
|
|||
NAME=multiple assignments
|
||||
FILE==
|
||||
CMDS=<<EOF
|
||||
"e scr.highlight= scr.highlight.grep =scr.rainbow =true "
|
||||
e scr.highlight=" scr.highlight.grep =scr.rainbow =true"
|
||||
e scr.highlight
|
||||
e scr.highlight.grep
|
||||
e scr.rainbow
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
scr.highlight.grep =scr.rainbow =true
|
||||
scr.highlight.grep =scr.rainbow =true
|
||||
false
|
||||
false
|
||||
EOF
|
||||
|
|
@ -106,3 +106,33 @@ scr.highlight = "e cmd.prompt = "e scr.highlight = cmd.prompt ="e scr.rainbow =
|
|||
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=el commands test
|
||||
FILE=bins/elf/analysis/hello-linux-x86_64
|
||||
CMDS=<<EOF
|
||||
elj zoom
|
||||
elJ zoom
|
||||
el* zoom
|
||||
ell zoom
|
||||
elq zoom
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
{"zoom.byte":"h","zoom.from":0,"zoom.in":"io.map","zoom.maxsz":512,"zoom.to":0}
|
||||
[{"name":"zoom.byte","value":"h","type":"str","desc":"Zoom callback to calculate each byte (See pz? for help)","ro":false},{"name":"zoom.from","value":0,"type":"int","desc":"Zoom start address","ro":false},{"name":"zoom.in","value":"io.map","type":"str","desc":"Specify boundaries for zoom","ro":false,"options":["raw","block","bin.section","bin.sections","bin.sections.rwx","bin.sections.r","bin.sections.rw","bin.sections.rx","bin.sections.wx","bin.sections.x","io.map","io.maps","io.maps.rwx","io.maps.r","io.maps.rw","io.maps.rx","io.maps.wx","io.maps.x","dbg.stack","dbg.heap","dbg.map","dbg.maps","dbg.maps.rwx","dbg.maps.r","dbg.maps.rw","dbg.maps.rx","dbg.maps.wx","dbg.maps.x","analysis.fcn","analysis.bb"]},{"name":"zoom.maxsz","value":512,"type":"int","desc":"Zoom max size of block","ro":false},{"name":"zoom.to","value":0,"type":"int","desc":"Zoom end address","ro":false}]
|
||||
e zoom.byte=h
|
||||
e zoom.from=0
|
||||
e zoom.in=io.map
|
||||
e zoom.maxsz=512
|
||||
e zoom.to=0
|
||||
zoom.byte = h ; Zoom callback to calculate each byte (See pz? for help)
|
||||
zoom.from = 0 ; Zoom start address
|
||||
zoom.in = io.map ; Specify boundaries for zoom [raw, block, bin.section, bin.sections, bin.sections.rwx, bin.sections.r, bin.sections.rw, bin.sections.rx, bin.sections.wx, bin.sections.x, io.map, io.maps, io.maps.rwx, io.maps.r, io.maps.rw, io.maps.rx, io.maps.wx, io.maps.x, dbg.stack, dbg.heap, dbg.map, dbg.maps, dbg.maps.rwx, dbg.maps.r, dbg.maps.rw, dbg.maps.rx, dbg.maps.wx, dbg.maps.x, analysis.fcn, analysis.bb]
|
||||
zoom.maxsz = 512 ; Zoom max size of block
|
||||
zoom.to = 0 ; Zoom end address
|
||||
zoom.byte=h
|
||||
zoom.from=0
|
||||
zoom.in=io.map
|
||||
zoom.maxsz=512
|
||||
zoom.to=0
|
||||
EOF
|
||||
RUN
|
||||
|
|
@ -30,9 +30,9 @@ EOF
|
|||
RUN
|
||||
|
||||
NAME="/e /t\wst\d\d\d\s\w\w/i" - oldshell
|
||||
ARGS=-ecfg.oldshell=true
|
||||
FILE=malloc://1024
|
||||
CMDS=<<EOF
|
||||
cfg.oldshell=true
|
||||
w "test123 ab"
|
||||
w "Test123 ab" @444
|
||||
?e
|
||||
|
|
@ -42,8 +42,8 @@ b 777
|
|||
EOF
|
||||
EXPECT=<<EOF
|
||||
|
||||
0x00000001 hit0_0 ""test123 ab""
|
||||
0x000001bd hit0_1 ""Test123 ab""
|
||||
0x00000000 hit0_0 "test123 ab"
|
||||
0x000001bc hit0_1 "Test123 ab"
|
||||
EOF
|
||||
RUN
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue