Make root a argv RCmdDesc ##newshell (#17326)

This commit is contained in:
Riccardo Schirone 2020-09-15 15:27:10 +02:00 committed by GitHub
parent 456b0fdf09
commit 75a80741ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 829 additions and 192 deletions

View File

@ -99,7 +99,6 @@
#include <r_types.h>
#include <r_lib.h>
#include <r_cmd.h>
#include <r_sign.h>
#include <signal.h>

View File

@ -1902,8 +1902,9 @@ R_API void r_cons_breakword(R_NULLABLE const char *s) {
R_API void r_cons_cmd_help(const char *help[], bool use_color) {
RCons *cons = r_cons_singleton ();
const char *pal_args_color = use_color ? cons->context->pal.args : "",
*pal_help_color = use_color ? cons->context->pal.help : "",
*pal_reset = use_color ? cons->context->pal.reset : "";
*pal_help_color = use_color ? cons->context->pal.help : "",
*pal_input_color = use_color ? cons->context->pal.input : "",
*pal_reset = use_color ? cons->context->pal.reset : "";
int i, max_length = 0;
const char *usage_str = "Usage:";
@ -1929,8 +1930,8 @@ R_API void r_cons_cmd_help(const char *help[], bool use_color) {
// these are the normal lines
int str_length = strlen (help[i]) + strlen (help[i + 1]);
int padding = (str_length < max_length)? (max_length - str_length): 0;
r_cons_printf ("| %s%s%s%*s %s%s%s\n",
help[i], pal_args_color, help[i + 1],
r_cons_printf ("| %s%s%s%s%*s %s%s%s\n",
pal_input_color, help[i], pal_args_color, help[i + 1],
padding, "", pal_help_color, help[i + 2], pal_reset);
}
}

View File

@ -6,7 +6,7 @@ R2DEPS=r_config r_cons r_io r_util r_flag r_asm
R2DEPS+=r_debug r_hash r_bin r_lang r_io r_anal r_parse r_bp r_egg
R2DEPS+=r_reg r_search r_syscall r_socket r_fs r_magic r_crypto
OBJS=core.o cmd.o cfile.o cconfig.o visual.o cio.o yank.o libs.o agraph.o
OBJS=core.o cmd.o cmd_helps.o cfile.o cconfig.o visual.o cio.o yank.o libs.o agraph.o
OBJS+=fortune.o hack.o vasm.o patch.o cbin.o corelog.o rtr.o cmd_api.o
OBJS+=carg.o canal.o project.o gdiff.o casm.o disasm.o cplugin.o
OBJS+=vmenus.o vmenus_graph.o vmenus_zigns.o zdiff.o citem.o

View File

@ -23,6 +23,7 @@
#include <sys/types.h>
#include <ctype.h>
#include <stdarg.h>
#include "cmd_helps.h"
#if __UNIX__
#include <sys/utsname.h>
#endif
@ -96,6 +97,7 @@ static int bb_cmpaddr(const void *_a, const void *_b) {
}
static void cmd_debug_reg(RCore *core, const char *str);
#include "cmd_quit.c"
#include "cmd_hash.c"
#include "cmd_debug.c"
@ -4675,30 +4677,6 @@ DEFINE_IS_TS_FCN_AND_SYMBOL(concatenation)
DEFINE_IS_TS_FCN_AND_SYMBOL(grep_specifier)
DEFINE_IS_TS_FCN_AND_SYMBOL(commands)
static RCmdStatus int2cmdstatus(int v) {
if (v == R_CORE_CMD_EXIT) {
return R_CMD_STATUS_EXIT;
} else if (v < 0) {
return R_CMD_STATUS_ERROR;
} else {
return R_CMD_STATUS_OK;
}
}
static int cmdstatus2int(RCmdStatus s) {
switch (s) {
case R_CMD_STATUS_OK:
return 0;
case R_CMD_STATUS_ERROR:
case R_CMD_STATUS_WRONG_ARGS:
case R_CMD_STATUS_INVALID:
return -1;
case R_CMD_STATUS_EXIT:
default:
return R_CORE_CMD_EXIT;
}
}
static struct tsr2cmd_edit *create_cmd_edit(struct tsr2cmd_state *state, TSNode arg, char *new_text) {
struct tsr2cmd_edit *e = R_NEW0 (struct tsr2cmd_edit);
ut32 command_start = ts_node_start_byte (state->substitute_cmd);
@ -5041,7 +5019,7 @@ err:
}
DEFINE_HANDLE_TS_FCN_AND_SYMBOL(legacy_quoted_command) {
return int2cmdstatus(run_cmd_depth (state->core, node_string));
return r_cmd_int2status(run_cmd_depth (state->core, node_string));
}
DEFINE_HANDLE_TS_FCN_AND_SYMBOL(repeat_command) {
@ -6505,7 +6483,7 @@ DEFINE_HANDLE_TS_FCN_AND_SYMBOL(pipe_command) {
char *first_str = ts_node_sub_string (first_cmd, state->input);
char *second_str = ts_node_sub_string (second_cmd, state->input);
int value = state->core->num->value;
RCmdStatus res = int2cmdstatus (r_core_cmd_pipe (state->core, first_str, second_str));
RCmdStatus res = r_cmd_int2status (r_core_cmd_pipe (state->core, first_str, second_str));
state->core->num->value = value;
free (first_str);
free (second_str);
@ -6734,7 +6712,7 @@ static int run_cmd_depth(RCore *core, char *cmd) {
R_API int r_core_cmd(RCore *core, const char *cstr, int log) {
if (core->use_tree_sitter_r2cmd) {
return cmdstatus2int(core_cmd_tsr2cmd (core, cstr, false, log));
return r_cmd_status2int(core_cmd_tsr2cmd (core, cstr, false, log));
}
int ret = false, i;
@ -7081,56 +7059,59 @@ R_API void r_core_cmd_init(RCore *core) {
const char *description;
RCmdCb cb;
void (*descriptor_init)(RCore *core, RCmdDesc *parent);
const RCmdDescHelp *help;
RCmdDescType type;
RCmdArgvCb argv_cb;
} cmds[] = {
{"!", "run system command", cmd_system},
{"_", "print last output", cmd_last},
{"#", "calculate hash", cmd_hash},
{"$", "alias", cmd_alias},
{"%", "short version of 'env' command", cmd_env},
{"&", "tasks", cmd_tasks},
{"(", "macro", cmd_macro, cmd_macro_init},
{"*", "pointer read/write", cmd_pointer},
{"-", "open cfg.editor and run script", cmd_stdin},
{".", "interpret", cmd_interpret},
{"/", "search kw, pattern aes", cmd_search, cmd_search_init},
{"=", "io pipe", cmd_rap},
{"?", "help message", cmd_help, cmd_help_init},
{"\\", "alias for =!", cmd_rap_run},
{"'", "alias for =!", cmd_rap_run},
{"0", "alias for s 0x", cmd_ox},
{"a", "analysis", cmd_anal, cmd_anal_init},
{"b", "change block size", cmd_bsize},
{"c", "compare memory", cmd_cmp, cmd_cmp_init},
{"C", "code metadata", cmd_meta, cmd_meta_init},
{"d", "debugger operations", cmd_debug, cmd_debug_init},
{"e", "evaluate configuration variable", cmd_eval, cmd_eval_init},
{"f", "get/set flags", cmd_flag, cmd_flag_init},
{"g", "egg manipulation", cmd_egg, cmd_egg_init},
{"i", "get file info", cmd_info, cmd_info_init},
{"k", "perform sdb query", cmd_kuery},
{"l", "list files and directories", cmd_ls},
{"j", "join the contents of the two files", cmd_join},
{"h", "show the top n number of line in file", cmd_head},
{"L", "manage dynamically loaded plugins", cmd_plugins},
{"m", "mount filesystem", cmd_mount, cmd_mount_init},
{"o", "open or map file", cmd_open, cmd_open_init},
{"p", "print current block", cmd_print, cmd_print_init},
{"P", "project", cmd_project, cmd_project_init},
{"q", "exit program session", cmd_quit, cmd_quit_init},
{"Q", "alias for q!", cmd_Quit},
{":", "long commands starting with :", cmd_colon},
{"r", "change file size", cmd_resize},
{"s", "seek to an offset", cmd_seek, cmd_seek_init},
{"t", "type information (cparse)", cmd_type, cmd_type_init},
{"T", "Text log utility", cmd_log, cmd_log_init},
{"u", "uname/undo", cmd_undo},
{"<", "pipe into RCons.readChar", cmd_pipein},
{"V", "enter visual mode", cmd_visual},
{"v", "enter visual mode", cmd_panels},
{"w", "write bytes", cmd_write, cmd_write_init},
{"x", "alias for px", cmd_hexdump},
{"y", "yank bytes", cmd_yank},
{"z", "zignatures", cmd_zign, cmd_zign_init},
{"!", "run system command", cmd_system, NULL, &system_help},
{"_", "print last output", cmd_last, NULL, &underscore_help},
{"#", "calculate hash", cmd_hash, NULL, &hash_help},
{"$", "alias", cmd_alias, NULL, &alias_help},
{"%", "short version of 'env' command", cmd_env, NULL, &env_help},
{"&", "tasks", cmd_tasks, NULL, &tasks_help},
{"(", "macro", cmd_macro, cmd_macro_init, &macro_help},
{"*", "pointer read/write", cmd_pointer, NULL, &pointer_help},
{"-", "open cfg.editor and run script", cmd_stdin, NULL, &stdin_help},
{".", "interpret", cmd_interpret, NULL, &interpret_help},
{"/", "search kw, pattern aes", cmd_search, cmd_search_init, &search_help},
{"=", "io pipe", cmd_rap, NULL, &rap_help},
{"?", "help message", cmd_help, cmd_help_init, &help_help},
{"\\", "alias for =!", cmd_rap_run, NULL, &rap_run_help},
{"'", "alias for =!", cmd_rap_run, NULL, &rap_run_help},
{"0", "alias for s 0x", cmd_ox, NULL, &zero_help},
{"a", "analysis", cmd_anal, cmd_anal_init, &anal_help},
{"b", "change block size", cmd_bsize, NULL, &b_help},
{"c", "compare memory", cmd_cmp, cmd_cmp_init, &c_help},
{"C", "code metadata", cmd_meta, cmd_meta_init, &C_help},
{"d", "debugger operations", cmd_debug, cmd_debug_init, &d_help},
{"e", "evaluate configuration variable", cmd_eval, cmd_eval_init, &e_help},
{"f", "get/set flags", cmd_flag, cmd_flag_init, &f_help},
{"g", "egg manipulation", cmd_egg, cmd_egg_init, &g_help},
{"i", "get file info", cmd_info, cmd_info_init, &i_help},
{"k", "perform sdb query", cmd_kuery, NULL, &k_help},
{"l", "list files and directories", cmd_ls, NULL, &l_help},
{"j", "join the contents of the two files", cmd_join, NULL, &j_help},
{"h", "show the top n number of line in file", cmd_head, NULL, &h_help},
{"L", "manage dynamically loaded plugins", cmd_plugins, NULL, &L_help},
{"m", "mount filesystem", cmd_mount, cmd_mount_init, &m_help},
{"o", "open or map file", cmd_open, cmd_open_init, &o_help},
{"p", "print current block", cmd_print, cmd_print_init, &p_help},
{"P", "project", cmd_project, cmd_project_init, &P_help},
{"q", "exit program session", cmd_quit, cmd_quit_init, &q_help},
{"Q", "alias for q!", cmd_Quit, NULL, &Q_help},
{":", "long commands starting with :", cmd_colon, NULL, &colon_help},
{"r", "change file size", cmd_resize, NULL, &r_help},
{"s", "seek to an offset", cmd_seek, cmd_seek_init, &s_help},
{"t", "type information (cparse)", cmd_type, cmd_type_init, &t_help},
{"T", "Text log utility", cmd_log, cmd_log_init, &T_help},
{"u", "uname/undo", cmd_undo, NULL, &u_help},
{"<", "pipe into RCons.readChar", cmd_pipein, NULL, &pipein_help},
{"V", "enter visual mode", cmd_visual, NULL, &V_help},
{"v", "enter visual mode", cmd_panels, NULL, &v_help},
{"w", "write bytes", cmd_write, cmd_write_init, &w_help, R_CMD_DESC_TYPE_ARGV, w_handler},
{"x", "alias for px", cmd_hexdump, NULL, &x_help},
{"y", "yank bytes", cmd_yank, NULL, &y_help},
{"z", "zignatures", cmd_zign, cmd_zign_init, &z_help},
};
core->rcmd = r_cmd_new ();
@ -7141,11 +7122,22 @@ R_API void r_core_cmd_init(RCore *core) {
core->rcmd->macro.cb_printf = (PrintfCallback)r_cons_printf;
r_cmd_set_data (core->rcmd, core);
core->cmd_descriptors = r_list_newf (free);
int i;
RCmdDesc *root = r_cmd_get_root (core->rcmd);
size_t i;
for (i = 0; i < R_ARRAY_SIZE (cmds); i++) {
r_cmd_add (core->rcmd, cmds[i].cmd, cmds[i].cb);
RCmdDesc *cd;
switch (cmds[i].type) {
case R_CMD_DESC_TYPE_OLDINPUT:
cd = r_cmd_desc_oldinput_new (core->rcmd, root, cmds[i].cmd, cmds[i].cb, cmds[i].help);
break;
case R_CMD_DESC_TYPE_ARGV:
cd = r_cmd_desc_argv_new (core->rcmd, root, cmds[i].cmd, cmds[i].argv_cb, cmds[i].help);
break;
}
if (cmds[i].descriptor_init) {
RCmdDesc *cd = r_cmd_get_desc (core->rcmd, cmds[i].cmd);
cmds[i].descriptor_init (core, cd);
}
}

View File

@ -10,9 +10,12 @@
static const RCmdDescHelp not_defined_help = {
.usage = "Usage not defined",
.summary = "Help summary not defined",
.args_str = "",
.description = "Help description not defined.",
.examples = NULL,
};
static const RCmdDescHelp root_help = {
.usage = "[.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...",
.description = "",
};
static int value = 0;
@ -99,8 +102,7 @@ R_API RCmd *r_cmd_new(void) {
}
cmd->nullcallback = cmd->data = NULL;
cmd->ht_cmds = ht_pp_new0 ();
cmd->root_cmd_desc = create_cmd_desc (cmd, NULL, R_CMD_DESC_TYPE_ARGV, "", NULL);
cmd->root_cmd_desc->help = NULL;
cmd->root_cmd_desc = create_cmd_desc (cmd, NULL, R_CMD_DESC_TYPE_ARGV, "", &root_help);
r_core_plugin_init (cmd);
r_cmd_macro_init (&cmd->macro);
r_cmd_alias_init (cmd);
@ -281,7 +283,6 @@ R_API int r_cmd_add(RCmd *c, const char *cmd, RCmdCb cb) {
}
strncpy (item->cmd, cmd, sizeof (item->cmd)-1);
item->callback = cb;
r_cmd_desc_oldinput_new (c, c->root_cmd_desc, cmd, cb, NULL);
return true;
}
@ -402,17 +403,19 @@ static void fill_usage_strbuf(RStrBuf *sb, RCmdDesc *cd, bool use_color) {
*pal_help_color = use_color? cons->context->pal.help: "",
*pal_reset = use_color? cons->context->pal.reset: "";
r_strbuf_appendf (sb, "%sUsage:%s ", pal_label_color, pal_reset);
r_strbuf_appendf (sb, "%sUsage: %s", pal_label_color, pal_reset);
if (cd->help->usage) {
r_strbuf_appendf (sb, "%s%s%s", cd->help->usage, pal_args_color, pal_reset);
} else {
r_strbuf_appendf (sb, "%s %s%s%s", cd->name, pal_args_color, cd->help->args_str, pal_reset);
const char *cd_args_str = cd->help->args_str? cd->help->args_str: "";
r_strbuf_appendf (sb, "%s%s%s%s", cd->name, pal_args_color, cd_args_str, pal_reset);
}
if (cd->help->group_summary) {
r_strbuf_appendf (sb, " %s# %s%s\n", pal_help_color, cd->help->group_summary, pal_reset);
} else {
r_strbuf_appendf (sb, " %s# %s%s\n", pal_help_color, cd->help->summary, pal_reset);
r_strbuf_appendf (sb, " %s# %s%s", pal_help_color, cd->help->group_summary, pal_reset);
} else if (cd->help->summary) {
r_strbuf_appendf (sb, " %s# %s%s", pal_help_color, cd->help->summary, pal_reset);
}
r_strbuf_append (sb, "\n");
}
static size_t update_max_len(RCmdDesc *cd, size_t max_len) {
@ -433,16 +436,14 @@ static void print_child_help(RStrBuf *sb, RCmdDesc *cd, size_t max_len, bool use
RCons *cons = r_cons_singleton ();
const char *pal_args_color = use_color? cons->context->pal.args: "",
*pal_help_color = use_color? cons->context->pal.help: "",
*pal_input_color = use_color? cons->context->pal.input: "",
*pal_reset = use_color? cons->context->pal.reset: "";
r_strbuf_appendf (sb, "| %s %s%s %*s%s# %s%s\n", cd->name, pal_args_color,
cd_args_str, padding, "", pal_help_color, cd_summary, pal_reset);
r_strbuf_appendf (sb, "| %s%s%s%s %*s%s# %s%s\n", pal_input_color, cd->name,
pal_args_color, cd_args_str, padding, "", pal_help_color, cd_summary, pal_reset);
}
static char *inner_get_help(RCmd *cmd, RCmdDesc *cd, bool use_color) {
if (!cd->help->args_str || !cd->help->summary) {
return NULL;
}
RStrBuf *sb = r_strbuf_new (NULL);
fill_usage_strbuf (sb, cd, use_color);
@ -468,10 +469,6 @@ static char *inner_get_help(RCmd *cmd, RCmdDesc *cd, bool use_color) {
}
static char *argv_get_help(RCmd *cmd, RCmdDesc *cd, RCmdParsedArgs *a, size_t detail, bool use_color) {
if (!cd->help->args_str || !cd->help->summary) {
return NULL;
}
RCons *cons = r_cons_singleton ();
const char *pal_help_color = use_color? cons->context->pal.help: "",
*pal_input_color = use_color? cons->context->pal.input: "",

390
libr/core/cmd_helps.c Normal file
View File

@ -0,0 +1,390 @@
#include "cmd_helps.h"
// root helps
const RCmdDescHelp system_help = {
.summary = "run given command as in system(3)",
};
const RCmdDescHelp underscore_help = {
.summary = "Print last output",
};
const RCmdDescHelp hash_help = {
.summary = "Hashbang to run an rlang script",
};
const RCmdDescHelp alias_help = {
.summary = "Alias commands and strings",
};
const RCmdDescHelp env_help = {
.summary = "get/set environment variable",
};
const RCmdDescHelp tasks_help = {
.summary = "Manage tasks (WARNING: Experimental. Use with caution!)",
};
const RCmdDescHelp macro_help = {
.summary = "manage scripting macros",
};
const RCmdDescHelp pointer_help = {
.summary = "alias for 'env' command",
};
const RCmdDescHelp stdin_help = {
.summary = "",
};
const RCmdDescHelp interpret_help = {
.summary = "Define macro or load r2, cparse or rlang file",
};
const RCmdDescHelp search_help = {
.summary = "search for bytes, regexps, patterns, ..",
};
const RCmdDescHelp rap_help = {
.summary = "connect with other instances of r2",
};
const RCmdDescHelp help_help = {
.summary = "Help or evaluate math expression",
};
const RCmdDescHelp rap_run_help = {
.summary = "alias for =!",
};
const RCmdDescHelp zero_help = {
.summary = "alias for `s 0x...`",
};
const RCmdDescHelp anal_help = {
.summary = "analysis commands",
};
const RCmdDescHelp b_help = {
.summary = "display or change the block size",
};
const RCmdDescHelp c_help = {
.summary = "compare block with given data",
};
const RCmdDescHelp C_help = {
.summary = "code metadata (comments, format, hints, ..)",
};
const RCmdDescHelp d_help = {
.summary = "debugger commands",
};
const RCmdDescHelp e_help = {
.summary = "list/get/set config evaluable vars",
};
const RCmdDescHelp f_help = {
.summary = "add flag at current address",
};
const RCmdDescHelp g_help = {
.summary = "generate shellcodes with r_egg",
};
const RCmdDescHelp i_help = {
.summary = "get info about opened file from r_bin",
};
const RCmdDescHelp k_help = {
.summary = "run sdb-query",
};
const RCmdDescHelp l_help = {
.summary = "list files and directories",
};
const RCmdDescHelp j_help = {
.summary = "join the contents of the two files",
};
const RCmdDescHelp h_help = {
.summary = "show the top n number of line in file",
};
const RCmdDescHelp L_help = {
.summary = "list, unload, load r2 plugins",
};
const RCmdDescHelp m_help = {
.summary = "mountpoints commands",
};
const RCmdDescHelp o_help = {
.summary = "open file at optional address",
};
const RCmdDescHelp p_help = {
.summary = "print commands",
};
const RCmdDescHelp P_help = {
.summary = "project management utilities",
};
const RCmdDescHelp q_help = {
.summary = "quit program with a return value",
};
const RCmdDescHelp Q_help = {
.summary = "quick quit",
};
const RCmdDescHelp colon_help = {
.summary = "long commands (experimental)",
};
const RCmdDescHelp r_help = {
.summary = "resize file",
};
const RCmdDescHelp s_help = {
.summary = "seek to address",
};
const RCmdDescHelp t_help = {
.summary = "types, noreturn, signatures, C parser and more",
};
const RCmdDescHelp T_help = {
.summary = "Text log utility (used to chat, sync, log, ...)",
};
const RCmdDescHelp u_help = {
.summary = "uname/undo seek/write",
};
const RCmdDescHelp pipein_help = {
.summary = "push escaped string into the RCons.readChar buffer",
};
const RCmdDescHelp V_help = {
.summary = "enter visual mode",
};
const RCmdDescHelp v_help = {
.summary = "enter visual panels mode",
};
const RCmdDescHelp w_help = {
.args_str = " <string>",
.summary = "write string",
.group_summary = "write commands",
};
const RCmdDescHelp x_help = {
.summary = "alias for 'px' (print hexadecimal)",
};
const RCmdDescHelp y_help = {
.summary = "Yank/paste bytes from/to memory",
};
const RCmdDescHelp z_help = {
.summary = "zignatures management",
};
// w0 helps
const RCmdDescHelp w0_help = {
.summary = "Write 'len' bytes with value 0x00",
.args_str = " [len]",
.description = "Fill len bytes starting from the current offset with the value 0.",
};
// w[1248][+-] helps
const RCmdDescExample w_incdec_help_examples[] = {
{ .example = "w1+", .comment = "Add 1 to the byte at the current offset." },
{ .example = "w2-", .comment = "Subtract 1 to the word at the current offset." },
{ .example = "w4+ 0xdeadbeef", .comment = "Add 0xdeadbeef to the dword at the current offset." },
{ .example = "w8- 10", .comment = "Subtract 10 to the qword at the current offset." },
{ 0 },
};
const RCmdDescHelp w1_incdec_help = {
.summary = "Increment/decrement a byte",
.usage = "w1[+-] [n]",
.args_str = " [n]",
.description = "Increment/decrement a byte at the current offset by 1 or n, if specified",
.examples = w_incdec_help_examples,
};
const RCmdDescHelp w2_incdec_help = {
.summary = "Increment/decrement a word",
.usage = "w2[+-] [n]",
.args_str = " [n]",
.description = "Increment/decrement a word at the current offset by 1 or n, if specified",
.examples = w_incdec_help_examples,
};
const RCmdDescHelp w4_incdec_help = {
.summary = "Increment/decrement a dword",
.usage = "w4[+-] [n]",
.args_str = " [n]",
.description = "Increment/decrement a dword at the current offset by 1 or n, if specified",
.examples = w_incdec_help_examples,
};
const RCmdDescHelp w8_incdec_help = {
.summary = "Increment/decrement a qword",
.usage = "w8[+-] [n]",
.args_str = " [n]",
.description = "Increment/decrement a qword at the current offset by 1 or n, if specified",
.examples = w_incdec_help_examples,
};
// wB helps
const RCmdDescExample wB_help_examples[] = {
{ .example = "wB 0x20", .comment = "Sets the 5th bit at current offset, leaving all other bits intact." },
{ 0 },
};
const RCmdDescHelp wB_help = {
.summary = "Set bits with given value",
.args_str = " [value]",
.group_summary = "Set or unset bits with given value",
.description = "Set the bits that are set in the value passed as arguments. 0 bits in the value argument are ignored, while the others are set at the current offset",
.examples = wB_help_examples,
};
const RCmdDescHelp wB_minus_help = {
.summary = "Unset bits with given value",
.args_str = " [value]",
.description = "Unset the bits that are set in the value passed as arguments. 0 bits in the value argument are ignored, while the others are unset at the current offset"
};
// wv helps
const RCmdDescExample wv_help_examples[] = {
{ .example = "wv 0xdeadbeef", .comment = "Write the value 0xdeadbeef at current offset" },
{ 0 },
};
const RCmdDescHelp wv_help = {
.usage = "wv[size] [value]",
.summary = "Write value as 4 - bytes / 8 - bytes based on value",
.args_str = " [value]",
.description = "Write the number passed as argument at the current offset as a 4 - bytes value or 8 - bytes value if the input is bigger than UT32_MAX, respecting the cfg.bigendian variable",
.group_summary = "Write value of given size",
.examples = wv_help_examples,
};
const RCmdDescHelp wv1_help = {
.summary = "Write value of 1 byte",
.args_str = " [value]",
.description = "Write the number passed as argument at the current offset as 1 - byte, respecting the cfg.bigendian variable",
};
const RCmdDescHelp wv2_help = {
.summary = "Write value of 2 bytes",
.args_str = " [value]",
.description = "Write the number passed as argument at the current offset as 2 - bytes, respecting the cfg.bigendian variable",
};
const RCmdDescHelp wv4_help = {
.summary = "Write value of 4 bytes",
.args_str = " [value]",
.description = "Write the number passed as argument at the current offset as 4 - bytes, respecting the cfg.bigendian variable",
};
const RCmdDescHelp wv8_help = {
.summary = "Write value of 8 byte",
.args_str = " [value]",
.description = "Write the number passed as argument at the current offset as 8 - bytes, respecting the cfg.bigendian variable",
};
const RCmdDescHelp w6_help = {
.args_str = " <base64>|<hexstring>",
.summary = "write base64 [d]ecoded or [e]ncoded string",
};
const RCmdDescHelp wh_help = {
.args_str = " <command>",
.summary = "whereis/which shell command",
};
const RCmdDescHelp we_help = {
.summary = "extend write operations (insert bytes instead of replacing)",
};
const RCmdDescHelp wp_help = {
.args_str = " -|<file>",
.summary = "apply radare patch file. See wp? fmi",
};
const RCmdDescHelp wu_help = {
.summary = "Apply unified hex patch (see output of cu)",
};
const RCmdDescHelp wr_help = {
.args_str = " <num>",
.summary = "write <num> random bytes",
};
const RCmdDescHelp wA_help = {
.args_str = " <type> <value>",
.summary = "alter/modify opcode at current seek (see wA?)",
};
const RCmdDescHelp wc_help = {
.summary = "write cache commands",
};
const RCmdDescHelp wz_help = {
.args_str = " <string>",
.summary = "write zero terminated string (like w + \x00)",
};
const RCmdDescHelp wt_help = {
.summary = "write to file (from current seek, blocksize or sz bytes)",
};
const RCmdDescHelp wf_help = {
.summary = "write data from file, socket, offset",
};
const RCmdDescHelp ww_help = {
.args_str = " <string>",
.summary = "write wide string",
};
const RCmdDescHelp wx_help = {
.args_str = " <hexstring>",
.summary = "write two intel nops (from wxfile or wxseek)",
};
const RCmdDescHelp wa_help = {
.summary = "write opcode, separated by ';' (use '\"' around the command)",
};
const RCmdDescHelp wb_help = {
.args_str = " <hexstring>",
.summary = "fill current block with cyclic hexstring",
};
const RCmdDescHelp wm_help = {
.args_str = " <hexstring>",
.summary = "set binary mask hexpair to be used as cyclic write mask",
};
const RCmdDescHelp wo_help = {
.summary = "write in block with operation. 'wo?' fmi",
};
const RCmdDescHelp wd_help = {
.summary = "duplicate N bytes from offset at current seek (memcpy) (see y?)",
};
const RCmdDescHelp ws_help = {
.summary = "write 1 byte for length and then the string",
};

98
libr/core/cmd_helps.h Normal file
View File

@ -0,0 +1,98 @@
#ifndef R_CMD_HELPS_H_
#define R_CMD_HELPS_H_
#include <r_cmd.h>
extern const RCmdDescHelp system_help;
extern const RCmdDescHelp underscore_help;
extern const RCmdDescHelp hash_help;
extern const RCmdDescHelp alias_help;
extern const RCmdDescHelp env_help;
extern const RCmdDescHelp tasks_help;
extern const RCmdDescHelp macro_help;
extern const RCmdDescHelp pointer_help;
extern const RCmdDescHelp stdin_help;
extern const RCmdDescHelp interpret_help;
extern const RCmdDescHelp search_help;
extern const RCmdDescHelp rap_help;
extern const RCmdDescHelp help_help;
extern const RCmdDescHelp rap_run_help;
extern const RCmdDescHelp zero_help;
extern const RCmdDescHelp anal_help;
extern const RCmdDescHelp b_help;
extern const RCmdDescHelp c_help;
extern const RCmdDescHelp C_help;
extern const RCmdDescHelp d_help;
extern const RCmdDescHelp e_help;
extern const RCmdDescHelp f_help;
extern const RCmdDescHelp g_help;
extern const RCmdDescHelp i_help;
extern const RCmdDescHelp k_help;
extern const RCmdDescHelp l_help;
extern const RCmdDescHelp j_help;
extern const RCmdDescHelp h_help;
extern const RCmdDescHelp L_help;
extern const RCmdDescHelp m_help;
extern const RCmdDescHelp o_help;
extern const RCmdDescHelp p_help;
extern const RCmdDescHelp P_help;
extern const RCmdDescHelp q_help;
extern const RCmdDescHelp Q_help;
extern const RCmdDescHelp colon_help;
extern const RCmdDescHelp r_help;
extern const RCmdDescHelp s_help;
extern const RCmdDescHelp t_help;
extern const RCmdDescHelp T_help;
extern const RCmdDescHelp u_help;
extern const RCmdDescHelp pipein_help;
extern const RCmdDescHelp V_help;
extern const RCmdDescHelp v_help;
extern const RCmdDescHelp w_help;
extern const RCmdDescHelp x_help;
extern const RCmdDescHelp y_help;
extern const RCmdDescHelp z_help;
// w0 helps
extern const RCmdDescHelp w0_help;
// w[1248][+-] helps
extern const RCmdDescHelp w1_incdec_help;
extern const RCmdDescHelp w2_incdec_help;
extern const RCmdDescHelp w4_incdec_help;
extern const RCmdDescHelp w8_incdec_help;
// wB helps
extern const RCmdDescHelp wB_help;
extern const RCmdDescHelp wB_minus_help;
// wv helps
extern const RCmdDescHelp wv_help;
extern const RCmdDescHelp wv1_help;
extern const RCmdDescHelp wv2_help;
extern const RCmdDescHelp wv4_help;
extern const RCmdDescHelp wv8_help;
extern const RCmdDescHelp w6_help;
extern const RCmdDescHelp wh_help;
extern const RCmdDescHelp we_help;
extern const RCmdDescHelp wp_help;
extern const RCmdDescHelp wu_help;
extern const RCmdDescHelp wr_help;
extern const RCmdDescHelp wA_help;
extern const RCmdDescHelp wc_help;
extern const RCmdDescHelp wz_help;
extern const RCmdDescHelp wt_help;
extern const RCmdDescHelp wf_help;
extern const RCmdDescHelp ww_help;
extern const RCmdDescHelp wx_help;
extern const RCmdDescHelp wa_help;
extern const RCmdDescHelp wb_help;
extern const RCmdDescHelp wm_help;
extern const RCmdDescHelp wo_help;
extern const RCmdDescHelp wd_help;
extern const RCmdDescHelp ws_help;
#endif

View File

@ -5,6 +5,7 @@
#include "r_cons.h"
#include "r_core.h"
#include "r_io.h"
#include "cmd_helps.h"
static const char *help_msg_w[] = {
"Usage:","w[x] [str] [<file] [<<EOF] [@addr]","",
@ -299,7 +300,8 @@ static void cmd_write_inc(RCore *core, int size, st64 num) {
}
}
static void cmd_write_op (RCore *core, const char *input) {
static int wo_handler_old(void *data, const char *input) {
RCore *core = (RCore *)data;
ut8 *buf;
int len;
int value;
@ -307,7 +309,7 @@ static void cmd_write_op (RCore *core, const char *input) {
case 'e':
if (input[1]!=' ') {
r_cons_printf ("Usage: 'woe from-to step'\n");
return;
return -1;
}
/* fallthru */
case 'a':
@ -446,6 +448,7 @@ static void cmd_write_op (RCore *core, const char *input) {
r_core_cmd_help (core, help_msg_wo);
break;
}
return 0;
}
#define WSEEK(x,y) if (wseek)r_core_seek_delta (x,y)
@ -563,24 +566,24 @@ static RCmdStatus common_wv_handler(RCore *core, int argc, const char **argv, in
return R_CMD_STATUS_OK;
}
static RCmdStatus wv_handler(void *user, int argc, const char **argv) {
return common_wv_handler (user, argc, argv, 0);
static RCmdStatus wv_handler(RCore *core, int argc, const char **argv) {
return common_wv_handler (core, argc, argv, 0);
}
static RCmdStatus wv1_handler(void *user, int argc, const char **argv) {
return common_wv_handler (user, argc, argv, 1);
static RCmdStatus wv1_handler(RCore *core, int argc, const char **argv) {
return common_wv_handler (core, argc, argv, 1);
}
static RCmdStatus wv2_handler(void *user, int argc, const char **argv) {
return common_wv_handler (user, argc, argv, 2);
static RCmdStatus wv2_handler(RCore *core, int argc, const char **argv) {
return common_wv_handler (core, argc, argv, 2);
}
static RCmdStatus wv4_handler(void *user, int argc, const char **argv) {
return common_wv_handler (user, argc, argv, 4);
static RCmdStatus wv4_handler(RCore *core, int argc, const char **argv) {
return common_wv_handler (core, argc, argv, 4);
}
static RCmdStatus wv8_handler(void *user, int argc, const char **argv) {
return common_wv_handler (user, argc, argv, 8);
static RCmdStatus wv8_handler(RCore *core, int argc, const char **argv) {
return common_wv_handler (core, argc, argv, 8);
}
static bool cmd_wff(RCore *core, const char *input) {
@ -749,14 +752,15 @@ static bool cmd_wfs(RCore *core, const char *input) {
return true;
}
static bool cmd_wf(RCore *core, const char *input) {
static int wf_handler_old(void *data, const char *input) {
RCore *core = (RCore *)data;
if (!core || !*input) {
return false;
return -1;
}
if (input[0] == '?') {
eprintf ("Usage: wf [file] ([size] ([offset]))\n");
r_core_cmd_help (core, help_msg_wf);
return false;
return -1;
}
if (input[0] == 's') { // "wfs"
return cmd_wfs (core, input + 1);
@ -778,7 +782,7 @@ static bool cmd_wf(RCore *core, const char *input) {
ioMemcpy (core, core->offset, addr, len);
free (args);
r_core_block_read (core);
return true;
return 0;
}
static void cmd_write_pcache(RCore *core, const char *input) {
@ -860,6 +864,22 @@ static int wB_handler_old(void *data, const char *input) {
return 0;
}
static RCmdStatus wB_handler(RCore *core, int argc, const char **argv) {
if (argc != 2) {
return R_CMD_STATUS_WRONG_ARGS;
}
cmd_write_bits (core, 1, r_num_math (core->num, argv[1]));
return R_CMD_STATUS_OK;
}
static RCmdStatus wB_minus_handler(RCore *core, int argc, const char **argv) {
if (argc != 2) {
return R_CMD_STATUS_WRONG_ARGS;
}
cmd_write_bits (core, 0, r_num_math (core->num, argv[1]));
return R_CMD_STATUS_OK;
}
static int w0_handler_common(RCore *core, ut64 len) {
int res = 0;
if (len > 0) {
@ -885,6 +905,14 @@ static int w0_handler_old(void *data, const char *input) {
return w0_handler_common (core, len);
}
static RCmdStatus w0_handler(RCore *core, int argc, const char **argv) {
if (argc != 2) {
return R_CMD_STATUS_WRONG_ARGS;
}
ut64 len = r_num_math (core->num, argv[1]);
return r_cmd_int2status (w0_handler_common (core, len));
}
static int w_incdec_handler_old(void *data, const char *input, int inc) {
RCore *core = (RCore *)data;
st64 num = 1;
@ -904,6 +932,35 @@ static int w_incdec_handler_old(void *data, const char *input, int inc) {
return 0;
}
static RCmdStatus w_incdec_handler(RCore *core, int argc, const char **argv, int inc_size) {
if (argc > 2) {
return R_CMD_STATUS_WRONG_ARGS;
}
st64 num = argc > 1? r_num_math (core->num, argv[1]): 1;
const char *command = argv[0];
if (command[strlen (command) - 1] == '-') {
num *= -1;
}
cmd_write_inc (core, inc_size, num);
return R_CMD_STATUS_OK;
}
static RCmdStatus w1_incdec_handler(RCore *core, int argc, const char **argv) {
return w_incdec_handler (core, argc, argv, 1);
}
static RCmdStatus w2_incdec_handler(RCore *core, int argc, const char **argv) {
return w_incdec_handler (core, argc, argv, 2);
}
static RCmdStatus w4_incdec_handler(RCore *core, int argc, const char **argv) {
return w_incdec_handler (core, argc, argv, 4);
}
static RCmdStatus w8_incdec_handler(RCore *core, int argc, const char **argv) {
return w_incdec_handler (core, argc, argv, 8);
}
static int w6_handler_old(void *data, const char *input) {
RCore *core = (RCore *)data;
int wseek = r_config_get_i (core->config, "cfg.wseek");
@ -1342,8 +1399,7 @@ static int wc_handler_old(void *data, const char *input) {
return 0;
}
static int w_handler_old(void *data, const char *input) {
RCore *core = (RCore *)data;
static void w_handler_common(RCore *core, const char *input) {
int wseek = r_config_get_i (core->config, "cfg.wseek");
char *str = strdup (input);
/* write string */
@ -1351,15 +1407,26 @@ static int w_handler_old(void *data, const char *input) {
if (!r_core_write_at (core, core->offset, (const ut8 *)str, len)) {
cmd_write_fail (core);
}
#if 0
r_io_use_desc (core->io, core->file->desc);
r_io_write_at (core->io, core->offset, (const ut8*)str, len);
#endif
WSEEK (core, len);
r_core_block_read (core);
}
static int w_handler_old(void *data, const char *input) {
RCore *core = (RCore *)data;
w_handler_common (core, input);
return 0;
}
static RCmdStatus w_handler(RCore *core, int argc, const char **argv) {
if (argc < 2) {
return R_CMD_STATUS_WRONG_ARGS;
}
char *s = r_str_array_join (argv + 1, argc - 1, " ");
w_handler_common (core, s);
free (s);
return R_CMD_STATUS_OK;
}
static int wz_handler_old(void *data, const char *input) {
RCore *core = (RCore *)data;
int wseek = r_config_get_i (core->config, "cfg.wseek");
@ -1958,7 +2025,7 @@ static int cmd_write(void *data, const char *input) {
wt_handler_old (core, input + 1);
break;
case 'f': // "wf"
cmd_wf (core, input + 1);
wf_handler_old (core, input + 1);
break;
case 'w': // "ww"
ww_handler_old (core, input + 1);
@ -1979,7 +2046,7 @@ static int cmd_write(void *data, const char *input) {
cmd_write_value (core, input + 1);
break;
case 'o': // "wo"
cmd_write_op (core, input + 1);
wo_handler_old (core, input + 1);
break;
case 'd': // "wd"
wd_handler_old (core, input + 1);
@ -1995,41 +2062,6 @@ static int cmd_write(void *data, const char *input) {
return 0;
}
static const RCmdDescExample wv_help_examples[] = {
{ .example = "wv 0xdeadbeef", .comment = "Write the value 0xdeadbeef at current offset" },
{ 0 },
};
static const RCmdDescHelp wv_help = {
.usage = "wv[size] [value]",
.summary = "Write value as 4 - bytes / 8 - bytes based on value",
.args_str = "[value]",
.description = "Write the number passed as argument at the current offset as a 4 - bytes value or 8 - bytes value if the input is bigger than UT32_MAX, respecting the cfg.bigendian variable",
.group_summary = "Write value of given size",
.examples = wv_help_examples,
};
static const RCmdDescHelp wv1_help = {
.summary = "Write value of 1 byte",
.args_str = "[value]",
.description = "Write the number passed as argument at the current offset as 1 - byte, respecting the cfg.bigendian variable",
};
static const RCmdDescHelp wv2_help = {
.summary = "Write value of 2 bytes",
.args_str = "[value]",
.description = "Write the number passed as argument at the current offset as 2 - bytes, respecting the cfg.bigendian variable",
};
static const RCmdDescHelp wv4_help = {
.summary = "Write value of 4 bytes",
.args_str = "[value]",
.description = "Write the number passed as argument at the current offset as 4 - bytes, respecting the cfg.bigendian variable",
};
static const RCmdDescHelp wv8_help = {
.summary = "Write value of 8 byte",
.args_str = "[value]",
.description = "Write the number passed as argument at the current offset as 8 - bytes, respecting the cfg.bigendian variable",
};
static void cmd_write_init(RCore *core, RCmdDesc *parent) {
DEFINE_CMD_DESCRIPTOR (core, w);
DEFINE_CMD_DESCRIPTOR (core, wa);
@ -2043,18 +2075,48 @@ static void cmd_write_init(RCore *core, RCmdDesc *parent) {
DEFINE_CMD_DESCRIPTOR (core, wv);
DEFINE_CMD_DESCRIPTOR (core, wx);
RCmdDesc *wv_cd = r_cmd_desc_argv_new (core->rcmd, parent, "wv", wv_handler, &wv_help);
r_return_if_fail (wv_cd);
DEFINE_CMD_ARGV_DESC (core, wB, parent);
DEFINE_CMD_ARGV_DESC_SPECIAL (core, wB-, wB_minus, wB_cd);
RCmdDesc *wv1_cd = r_cmd_desc_argv_new (core->rcmd, wv_cd, "wv1", wv1_handler, &wv1_help);
r_return_if_fail (wv1_cd);
DEFINE_CMD_ARGV_DESC (core, wv, parent);
DEFINE_CMD_ARGV_DESC (core, wv1, wv_cd);
DEFINE_CMD_ARGV_DESC (core, wv2, wv_cd);
DEFINE_CMD_ARGV_DESC (core, wv4, wv_cd);
DEFINE_CMD_ARGV_DESC (core, wv8, wv_cd);
RCmdDesc *wv2_cd = r_cmd_desc_argv_new (core->rcmd, wv_cd, "wv2", wv2_handler, &wv2_help);
r_return_if_fail (wv2_cd);
DEFINE_CMD_ARGV_DESC (core, w0, parent);
RCmdDesc *wv4_cd = r_cmd_desc_argv_new (core->rcmd, wv_cd, "wv4", wv4_handler, &wv4_help);
r_return_if_fail (wv4_cd);
DEFINE_CMD_ARGV_DESC_GROUP (core, w[1248][+-], w_incdec, parent);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w1, w1, w_incdec_cd, NULL, &w1_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w1+, w1_inc, w1_cd, w1_incdec_handler, &w1_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w1-, w1_dec, w1_cd, w1_incdec_handler, &w1_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w2, w2, w_incdec_cd, NULL, &w2_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w2+, w2_inc, w2_cd, w2_incdec_handler, &w2_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w2-, w2_dec, w2_cd, w2_incdec_handler, &w2_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w4, w4, w_incdec_cd, NULL, &w4_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w4+, w4_inc, w4_cd, w4_incdec_handler, &w4_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w4-, w4_dec, w4_cd, w4_incdec_handler, &w4_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w8, w8, w_incdec_cd, NULL, &w8_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w8+, w8_inc, w8_cd, w8_incdec_handler, &w8_incdec_help);
DEFINE_CMD_ARGV_DESC_DETAIL (core, w8-, w8_dec, w8_cd, w8_incdec_handler, &w8_incdec_help);
RCmdDesc *wv8_cd = r_cmd_desc_argv_new (core->rcmd, wv_cd, "wv8", wv8_handler, &wv8_help);
r_return_if_fail (wv8_cd);
DEFINE_CMD_OLDINPUT_DESC (core, w6, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wh, parent);
DEFINE_CMD_OLDINPUT_DESC (core, we, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wp, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wu, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wr, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wA, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wc, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wz, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wt, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wf, parent);
DEFINE_CMD_OLDINPUT_DESC (core, ww, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wx, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wa, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wb, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wm, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wo, parent);
DEFINE_CMD_OLDINPUT_DESC (core, wd, parent);
DEFINE_CMD_OLDINPUT_DESC (core, ws, parent);
}

View File

@ -12,6 +12,7 @@ r_core_sources = [
'cmd.c',
#'cmd_anal.c',
'cmd_api.c',
'cmd_helps.c',
#'cmd_cmp.c',
#'cmd_debug.c',
#'cmd_egg.c',

View File

@ -9,6 +9,8 @@
extern "C" {
#endif
typedef struct r_core_t RCore;
//R_LIB_VERSION_HEADER (r_cmd);
#define MACRO_LIMIT 1024
@ -24,7 +26,7 @@ typedef enum r_cmd_status_t {
} RCmdStatus;
typedef int (*RCmdCb) (void *user, const char *input);
typedef RCmdStatus (*RCmdArgvCb) (void *user, int argc, const char **argv);
typedef RCmdStatus (*RCmdArgvCb) (RCore *core, int argc, const char **argv);
typedef int (*RCmdNullCb) (void *user);
typedef struct r_cmd_parsed_args_t {
@ -78,18 +80,61 @@ typedef struct r_cmd_desc_example_t {
const char *comment;
} RCmdDescExample;
/**
* Define how the command looks like in the help.
*/
typedef struct r_cmd_desc_help_t {
const char *usage;
/**
* Short-sentence explaining what the command does.
* This is shown, for example, when the list of sub-commands is printed
* and each sub-command has a very short description on the right,
* explaining what it does.
*/
const char *summary;
const char *group_summary;
const char *args_str;
/**
* Long description of what the command does. It can be as long as you
* want and it should explain well how the command behaves.
* This is shown, for example, when `??` is appended on command or `?`
* is appended and the command has no children to show. In that case,
* the short summary is extended with this longer description.
*
* Optional.
*/
const char *description;
/**
* String used to identify the arguments. This usually comes together
* with the summary.
* TODO: explain how to differentiate between required and optional arguments
*/
const char *args_str;
/**
* String that overrides the name+args_str usually used to describe the
* command.
*
* Optional.
*/
const char *usage;
/**
* When a command is used both as a parent command and as a subcommand
* (e.g. `w` is both the parent of `wv`, `ws`, etc. and it's also the
* command `w`), this is the summary used for the parent level, while
* summary becomes the text used for the subcommand.
*
* Optional.
*/
const char *group_summary;
/**
* List of examples used to better explain how to use the command. This
* is shown together with the long description.
*
* Optional.
*/
const RCmdDescExample *examples;
} RCmdDescHelp;
typedef enum {
// for old handlers that parse their own input and accept a single string
R_CMD_DESC_TYPE_OLDINPUT,
R_CMD_DESC_TYPE_OLDINPUT = 0,
// for handlers that accept argc/argv
R_CMD_DESC_TYPE_ARGV,
} RCmdDescType;
@ -147,6 +192,19 @@ typedef struct r_core_plugin_t {
RCmdCb fini;
} RCorePlugin;
#define DEFINE_CMD_ARGV_DESC_DETAIL(core, name, c_name, parent, handler, help) \
RCmdDesc *c_name##_cd = r_cmd_desc_argv_new (core->rcmd, parent, #name, handler, help); \
r_warn_if_fail (c_name##_cd)
#define DEFINE_CMD_ARGV_DESC_SPECIAL(core, name, c_name, parent) \
DEFINE_CMD_ARGV_DESC_DETAIL (core, name, c_name, parent, c_name##_handler, &c_name##_help)
#define DEFINE_CMD_ARGV_DESC_GROUP(core, name, c_name, parent) \
DEFINE_CMD_ARGV_DESC_DETAIL (core, name, c_name, parent, NULL, NULL)
#define DEFINE_CMD_ARGV_DESC(core, name, parent) \
DEFINE_CMD_ARGV_DESC_SPECIAL (core, name, name, parent)
#define DEFINE_CMD_OLDINPUT_DESC(core, name, parent) \
RCmdDesc *name##_cd = r_cmd_desc_oldinput_new (core->rcmd, parent, #name, name##_handler_old, &name##_help); \
r_warn_if_fail (name##_cd)
#ifdef R_API
R_API int r_core_plugin_init(RCmd *cmd);
R_API int r_core_plugin_add(RCmd *cmd, RCorePlugin *plugin);
@ -164,6 +222,30 @@ R_API RCmdDesc *r_cmd_get_root(RCmd *cmd);
R_API RCmdDesc *r_cmd_get_desc(RCmd *cmd, const char *cmd_identifier);
R_API char *r_cmd_get_help(RCmd *cmd, RCmdParsedArgs *args, bool use_color);
static inline RCmdStatus r_cmd_int2status(int v) {
if (v == -2) {
return R_CMD_STATUS_EXIT;
} else if (v < 0) {
return R_CMD_STATUS_ERROR;
} else {
return R_CMD_STATUS_OK;
}
}
static inline int r_cmd_status2int(RCmdStatus s) {
switch (s) {
case R_CMD_STATUS_OK:
return 0;
case R_CMD_STATUS_ERROR:
case R_CMD_STATUS_WRONG_ARGS:
case R_CMD_STATUS_INVALID:
return -1;
case R_CMD_STATUS_EXIT:
default:
return -2;
}
}
/* 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);

View File

@ -194,6 +194,7 @@ R_API char *r_qrcode_gen(const ut8 *text, int len, bool utf8, bool inverted);
R_API char *r_str_from_ut64(ut64 val);
R_API void r_str_stripLine(char *str, const char *key);
R_API char *r_str_list_join(RList *str, const char *sep);
R_API char *r_str_array_join(const char **a, size_t n, const char *sep);
R_API const char *r_str_sep(const char *base, const char *sep);
R_API const char *r_str_rsep(const char *base, const char *p, const char *sep);

View File

@ -3451,6 +3451,21 @@ R_API char *r_str_list_join(RList *str, const char *sep) {
return r_strbuf_drain (sb);
}
R_API char *r_str_array_join(const char **a, size_t n, const char *sep) {
RStrBuf *sb = r_strbuf_new ("");
size_t i;
if (n > 0) {
r_strbuf_append (sb, a[0]);
}
for (i = 1; i < n; i++) {
r_strbuf_append (sb, sep);
r_strbuf_append (sb, a[i]);
}
return r_strbuf_drain (sb);
}
/* return the number of arguments expected as extra arguments */
R_API int r_str_fmtargs(const char *fmt) {
int n = 0;

View File

@ -229,10 +229,9 @@ RUN
NAME="base help"
FILE=-
CMDS=<<EOF
?~print
?~print~?
EOF
EXPECT=<<EOF
| p[?] [len] print current block with format and length
| x[?] [len] alias for 'px' (print hexadecimal)
2
EOF
RUN

View File

@ -40,10 +40,10 @@ FILE=-
ARGS=-e cfg.bigendian=false
CMDS=<<EOF
wx 0022
w1+1
w1+ 1
pv2
w2-1
w2-1
w2- 1
w2- 1
pv2
EOF
EXPECT=<<EOF

View File

@ -78,7 +78,7 @@ bool test_parsed_args_newargs(void) {
mu_end;
}
static RCmdStatus afl_argv_handler(void *user, int argc, const char **argv) {
static RCmdStatus afl_argv_handler(RCore *core, int argc, const char **argv) {
return R_CMD_STATUS_OK;
}
@ -125,11 +125,11 @@ bool test_cmd_descriptor_oldinput(void) {
mu_end;
}
static RCmdStatus ap_handler(void *user, int argc, const char **argv) {
static RCmdStatus ap_handler(RCore *core, int argc, const char **argv) {
return R_CMD_STATUS_OK;
}
static RCmdStatus aeir_handler(void *user, int argc, const char **argv) {
static RCmdStatus aeir_handler(RCore *core, int argc, const char **argv) {
return R_CMD_STATUS_OK;
}
@ -183,14 +183,14 @@ bool test_cmd_get_desc(void) {
mu_end;
}
static RCmdStatus pd_handler(void *user, int argc, const char **argv) {
static RCmdStatus pd_handler(RCore *core, int argc, const char **argv) {
mu_assert_eq (argc, 2, "pd_handler called with 2 arguments (name and arg)");
mu_assert_streq (argv[0], "pd", "pd is argv[0]");
mu_assert_streq (argv[1], "10", "10 is argv[1]");
return R_CMD_STATUS_OK;
}
static RCmdStatus p_handler_argv(void *user, int argc, const char **argv) {
static RCmdStatus p_handler_argv(RCore *core, int argc, const char **argv) {
return R_CMD_STATUS_OK;
}
@ -267,7 +267,7 @@ bool test_cmd_help(void) {
.summary = "pd summary",
.usage = NULL,
.group_summary = NULL,
.args_str = "<num>",
.args_str = " <num>",
.description = "pd long description",
.examples = pd_help_examples,
};
@ -276,7 +276,7 @@ bool test_cmd_help(void) {
.summary = "px summary",
.usage = "px-usage",
.group_summary = NULL,
.args_str = "<verylongarg_str_num>",
.args_str = " <verylongarg_str_num>",
.description = "px long description",
.examples = NULL,
};
@ -339,7 +339,7 @@ bool test_cmd_group_help(void) {
.summary = "pd summary",
.usage = NULL,
.group_summary = NULL,
.args_str = "<num>",
.args_str = " <num>",
.description = "pd long description",
.examples = NULL,
};