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:
Aswin C 2021-09-09 17:16:08 +05:30 committed by Anton Kochkov
parent 69e6345ca5
commit edf71880a6
12 changed files with 222 additions and 499 deletions

View file

@ -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;
}

View file

@ -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 */
{

View file

@ -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 },

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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;
}

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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

View file

@ -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