diff --git a/doc/indent-example.c b/doc/indent-example.c index de9cd2163a..baebd4e4da 100644 --- a/doc/indent-example.c +++ b/doc/indent-example.c @@ -10,7 +10,7 @@ typedef struct r_core_rtr_host_t2 { RSocket *fd; } RCoreRtrHost2; -static const char *help_msg_aa[] = { +static RCoreHelpMessage help_msg_aa = { "Usage:", "aa[0*?]", " # see also 'af' and 'afna'", "aa", " ", "alias for 'af@@ sym.*;af@entry0;afva'", //;.afna @@ fcn.*'", "aa*", "", "analyze all flags starting with sym. (af @@ sym.*)", diff --git a/libr/cons/grep.c b/libr/cons/grep.c index 39a9dd8665..04a8003c3d 100644 --- a/libr/cons/grep.c +++ b/libr/cons/grep.c @@ -19,7 +19,7 @@ static char *strchr_ns(char *s, const char ch) { return p; } -static const char *help_detail_tilde[] = { +static RCoreHelpMessage help_detail_tilde = { "Usage: [command]~[modifier][word,word][endmodifier][[column]][:line]\n" "modifier:", "", "", " &", "", "all words must match to grep the line", diff --git a/libr/cons/help.c b/libr/cons/help.c index 3d86eb1d11..ab5173bb0f 100644 --- a/libr/cons/help.c +++ b/libr/cons/help.c @@ -2,7 +2,7 @@ #include -R_API void r_cons_cmd_help_json(const char * const help[]) { +R_API void r_cons_cmd_help_json(RCoreHelpMessage help) { int i, max_length = 0; const char * const usage_str = "Usage:"; const char * help_cmd = NULL; @@ -56,7 +56,7 @@ R_API void r_cons_cmd_help_json(const char * const help[]) { } /* Print a coloured help message */ -R_API void r_cons_cmd_help(const char * const help[], bool use_color) { +R_API void r_cons_cmd_help(RCoreHelpMessage help, bool use_color) { RCons *cons = r_cons_singleton (); const char *pal_input_color = use_color ? cons->context->pal.input : ""; const char *pal_args_color = use_color ? cons->context->pal.args : ""; @@ -129,7 +129,7 @@ static void print_match(const char * const *match, bool use_color) { * If exact is false, will match any command that contains the search text. * For example, ("pd", 'r', false) matches both `pdr` and `pdr.`. */ -R_API void r_cons_cmd_help_match(const char * const help[], bool use_color, R_BORROW R_NONNULL char *cmd, char spec, bool exact) { +R_API void r_cons_cmd_help_match(RCoreHelpMessage help, bool use_color, R_BORROW R_NONNULL char *cmd, char spec, bool exact) { size_t i; if (spec) { diff --git a/libr/core/agraph.c b/libr/core/agraph.c index acb45bbdfe..80ca3874b8 100644 --- a/libr/core/agraph.c +++ b/libr/core/agraph.c @@ -4192,7 +4192,7 @@ static void nextword(RCore *core, RAGraph *g, const char *word) { nextword (core, g, word); } -static const char *help_msg_visual_graph[] = { +static RCoreHelpMessage help_msg_visual_graph = { ":e cmd.gprompt=agft", "show tinygraph in one side", "@", "toggle graph.layout between 0 and 1", "+/-/0", "zoom in/out/default", diff --git a/libr/core/canal.c b/libr/core/canal.c index 7c576a4685..b93eebfd5f 100644 --- a/libr/core/canal.c +++ b/libr/core/canal.c @@ -3302,7 +3302,7 @@ static int fcn_list_legacy(RCore *core, RList *fcns) { return 0; } -static const char *help_msg_aflm[] = { +static RCoreHelpMessage help_msg_aflm = { "Usage:", "aflm", "[q.j] List functions in verbose mode", "aflm", "", "list functions and what they call in makefile-like format", "aflm.", "", "only print the summary for the current function (see pds)", diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index a6ae271998..7aa0afa3df 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -1491,8 +1491,18 @@ static bool cb_dirsrc(void *user, void *data) { static bool cb_cfgsanbox_grain(void *user, void *data) { RConfigNode *node = (RConfigNode*) data; if (strstr (node->value, "?")) { - eprintf ("Usage: comma separated grain types to be masked out by the sandbox.\n"); - eprintf ("all, none, disk, files, exec, socket, exec\n"); + static RCoreHelpMessage help_msg_grain = { + "Usage:", "e cfg.sandbox.grain=arg[,arg...]", "set grain types to mask out", + "Grain types:", "", "", + "", "all", "", + "", "none", "", + "", "disk", "", + "", "files", "", + "", "exec", "", + "", "socket", "", + NULL + }; + r_core_cmd_help ((RCore *)user, help_msg_grain); return false; } int gt = R_SANDBOX_GRAIN_NONE; @@ -2388,7 +2398,7 @@ static bool cb_pager(void *user, void *data) { RCore *core = (RCore *) user; RConfigNode *node = (RConfigNode *) data; if (*node->value == '?') { - eprintf ("Usage: scr.pager must be '..' for internal less, or the path to a program in $PATH\n"); + eprintf ("scr.pager must be '..' for internal less, or the path to a program in $PATH\n"); return false; } /* Let cons know we have a new pager. */ diff --git a/libr/core/cmd.c b/libr/core/cmd.c index 6794f47022..f737bd2eed 100644 --- a/libr/core/cmd.c +++ b/libr/core/cmd.c @@ -146,7 +146,7 @@ static RCoreHelpMessage help_msg_star = { NULL }; -static RCoreHelpMessage cmd_table_help = { +static RCoreHelpMessage help_msg_comma = { "Usage:", ",[,.-/*jhr] [file]", "# load table data", ",", "", "display table", ", ", "[table-query]", "filter and print table. See ,? for more details", @@ -295,8 +295,9 @@ static RCoreHelpMessage help_msg_r = { "rasm2", " [...]", "run rasm2's main", "ravc2", " [...]", "run ravc2's main", "rax2", " [...]", "run rax2's main", - "rb", "oldbase @ newbase", "rebase all flags, bin.info, breakpoints and analysis", + "rb", " oldbase @ newbase", "rebase all flags, bin.info, breakpoints and analysis", "rm" ," [file]", "remove file", + "rmrf", " [file|dir]", "recursive remove", "rh" ,"", "show size in human format", "r2" ," [file]", "launch r2 (same for rax2, rasm2, ...)", "reset" ,"", "reset console settings (clear --hard)", @@ -337,7 +338,7 @@ static RCoreHelpMessage help_msg_uc = { NULL }; -static const char *help_msg_y[] = { +static RCoreHelpMessage help_msg_y = { "Usage:", "y[fptxy] [len] [[@]addr]", " # See wd? for memcpy, same as 'yf'.", "y!", "", "open cfg.editor to edit the clipboard", "y", " 16 0x200", "copy 16 bytes into clipboard from 0x200", @@ -403,16 +404,16 @@ static RCoreHelpMessage help_msg_v = { NULL }; -R_API void r_core_cmd_help(const RCore *core, const char * const help[]) { +R_API void r_core_cmd_help(const RCore *core, RCoreHelpMessage help) { // r_cons_cmd_help_json (help); r_cons_cmd_help (help, core->print->flags & R_PRINT_FLAGS_COLOR); } -R_API void r_core_cmd_help_match(const RCore *core, const char * const help[], R_BORROW R_NONNULL char *cmd, bool exact) { +R_API void r_core_cmd_help_match(const RCore *core, RCoreHelpMessage help, R_BORROW R_NONNULL char *cmd, bool exact) { r_cons_cmd_help_match (help, core->print->flags & R_PRINT_FLAGS_COLOR, cmd, 0, exact); } -R_API void r_core_cmd_help_match_spec(const RCore *core, const char * const help[], R_BORROW R_NONNULL char *cmd, char spec, bool exact) { +R_API void r_core_cmd_help_match_spec(const RCore *core, RCoreHelpMessage help, R_BORROW R_NONNULL char *cmd, char spec, bool exact) { r_cons_cmd_help_match (help, core->print->flags & R_PRINT_FLAGS_COLOR, cmd, spec, exact); } @@ -613,7 +614,7 @@ static int cmd_uniq(void *data, const char *input) { // "uniq" } switch (*input) { case '?': // "uniq?" - eprintf ("Usage: uniq # uniq to list unique strings in file\n"); + r_core_cmd_help_match (core, help_msg_u, "uniq", true); break; default: // "uniq" if (!arg) { @@ -639,6 +640,10 @@ static int cmd_head(void *data, const char *_input) { // "head" char *input = strdup (_input); char *arg = strchr (input, ' '); char *tmp, *count; + static RCoreHelpMessage help_msg_h = { + "head", " [n] [file]", "Print first n lines in file (default n=5)", + NULL + }; if (arg) { arg = (char *)r_str_trim_head_ro (arg + 1); // contains "count filename" count = strchr (arg, ' '); @@ -651,7 +656,7 @@ static int cmd_head(void *data, const char *_input) { // "head" } switch (*input) { case '?': // "head?" - eprintf ("Usage: head [file] # to list first n lines in file\n"); + r_core_cmd_help (core, help_msg_h); break; default: // "head" if (!arg) { @@ -939,7 +944,7 @@ static void cmd_remote(RCore *core, const char *input, bool retry) { return; } if (*input == '?') { - r_cons_printf ("Usage: =r localhost:9999\n"); + r_core_cmd_help_match (core, help_msg_equal, "=r", true); return; } char *host = strdup (input); @@ -1172,12 +1177,12 @@ static int cmd_yank(void *data, const char *input) { } free (out); } else { - eprintf ("Usage: ywx [hexpairs]\n"); + r_core_cmd_help_match (core, help_msg_y, "ywx", true); } // r_core_yank_write_hex (core, input + 2); break; default: - eprintf ("Usage: ywx [hexpairs]\n"); + r_core_cmd_help_match (core, help_msg_y, "ywx", true); break; } break; @@ -2067,7 +2072,7 @@ static int cmd_table(void *data, const char *input) { break; case '.': // ",." if (R_STR_ISEMPTY (input + 1)) { - eprintf ("Usage: ,. [file | $alias]\n"); + r_core_cmd_help_match (core, help_msg_comma, ",.", true); } else { const char *file = r_str_trim_head_ro (input + 1); if (*file == '$' && !file[1]) { @@ -2117,11 +2122,11 @@ static int cmd_table(void *data, const char *input) { } break; case '?': - r_core_cmd_help (core, cmd_table_help); + r_core_cmd_help (core, help_msg_comma); r_cons_printf ("%s\n", r_table_help ()); break; default: - r_core_cmd_help (core, cmd_table_help); + r_core_cmd_help (core, help_msg_comma); break; } return 0; @@ -2197,7 +2202,7 @@ static int cmd_interpret(void *data, const char *input) { break; case '-': // ".-" if (input[1] == '?') { - r_cons_printf ("Usage: '-' '.-' '. -' do the same\n"); + r_core_cmd_help_match (core, help_msg_dot, ".-", true); } else { r_core_run_script (core, "-"); } @@ -2474,7 +2479,7 @@ static int cmd_kuery(void *data, const char *input) { } free (fn); } else { - eprintf ("Usage: ko [file] [namespace]\n"); + r_core_cmd_help_match (core, help_msg_k, "ko", true); } break; case 'd': // "kd" @@ -2499,7 +2504,7 @@ static int cmd_kuery(void *data, const char *input) { } free (fn); } else { - eprintf ("Usage: kd [file] [namespace]\n"); + r_core_cmd_help_match (core, help_msg_k, "kd", true); } break; case '?': @@ -2569,7 +2574,7 @@ static int cmd_bsize(void *data, const char *input) { R_LOG_ERROR ("bf: cannot find flag named '%s'", input + 2); } } else { - eprintf ("Usage: bf [flagname]\n"); + r_core_cmd_help_match (core, help_msg_b, "bf", true); } break; case 'j': { // "bj" @@ -2661,7 +2666,7 @@ static bool cmd_r2cmd(RCore *core, const char *_input) { static int cmd_rebase(RCore *core, const char *input) { ut64 addr = r_num_math (core->num, input); if (!addr) { - r_cons_printf ("Usage: rb oldbase @ newbase\n"); + r_core_cmd_help_match (core, help_msg_r, "rb", true); return 0; } // old base = addr @@ -2703,7 +2708,7 @@ static int cmd_resize(void *data, const char *input) { const char *file = r_str_trim_head_ro (input + 3); return r_file_rm_rf (file); } - eprintf ("Usage rr \n"); + r_core_cmd_help_match (core, help_msg_r, "rmrf", true); return false; } if (input[1] == ' ') { @@ -2714,7 +2719,7 @@ static int cmd_resize(void *data, const char *input) { r_file_rm (file); } } else { - eprintf ("Usage: rm [file] # removes a file\n"); + r_core_cmd_help_match (core, help_msg_r, "rm", false); } return true; case '\0': @@ -3166,12 +3171,16 @@ static void cmd_autocomplete(RCore *core, const char *input) { } static int cmd_last(void *data, const char *input) { + static RCoreHelpMessage help_msg_last = { + "_", "", "print last output", + NULL + }; switch (*input) { case 0: r_cons_last (); break; default: - r_cons_printf ("Usage: _ print last output\n"); + r_core_cmd_help ((RCore *)data, help_msg_last); } return 0; } @@ -3193,7 +3202,8 @@ static int cmd_system(void *data, const char *input) { break; case '=': //!= if (input[1] == '?') { - r_cons_printf ("Usage: !=[!] - enable/disable remote commands\n"); + r_core_cmd_help_match (core, help_msg_exclamation, "!=!", true); + r_core_cmd_help_match (core, help_msg_exclamation, "=!=", true); } else { if (!r_sandbox_enable (0)) { R_FREE (core->cmdremote); @@ -4710,7 +4720,7 @@ repeat_arroba: } is_arch_set = set_tmp_arch (core, ptr + 2, &tmpasm); } else { - eprintf ("Usage: pd 10 @a:arm:32\n"); + r_core_cmd_help_match (core, help_msg_at, "@a:", true); } break; case 's': // "@s:" // wtf syntax @@ -4831,9 +4841,7 @@ next_arroba: char *range = ptr + 2; char *p = strchr (range, ' '); if (!p) { - eprintf ("Usage: / ABCD @{0x1000 0x3000}\n"); - eprintf ("Run command and define the following vars:\n"); - eprintf (" (anal|diff|graph|search|zoom).{from,to}\n"); + r_core_cmd_help_match (core, help_msg_at, "@{", true); free (tmpeval); free (tmpasm); free (tmpbits); @@ -5246,7 +5254,8 @@ R_API int r_core_cmd_foreach3(RCore *core, const char *cmd, char *each) { // "@@ ch = 'G'; // @@@SS = @@@G } char *glob = (each[0] && each[1] == ':') - ? r_str_trim_dup (each + 2): NULL; + ? r_str_trim_dup (each + 2) + : NULL; RList *list = foreach3list (core, ch, glob); @@ -5265,7 +5274,7 @@ R_API int r_core_cmd_foreach3(RCore *core, const char *cmd, char *each) { // "@@ free (arg); } } else { - eprintf ("Usage: @@@c:command # same as @@@=`command`\n"); + r_core_cmd_help (core, help_msg_at_at_at); } break; case 'C': diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index 793c729398..1c10b10a64 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -6,21 +6,21 @@ #define MAX_SCAN_SIZE 0x7ffffff // should be 1 unless it makes the CI sad -static const char *help_msg_af_plus[] = { +static RCoreHelpMessage help_msg_af_plus = { "Usage:", "af+", " [addr] ([name] ([type] [diff]))", "af+", "$$", "add a raw function element. See afb+ to add basic blocks to it", "af+", "$$ main", "add new function in current offset with 'main' as name", NULL }; -static const char *help_msg_aex[] = { +static RCoreHelpMessage help_msg_aex = { "Usage:", "aex", "[a] [9090]", "aex", " 90", "decode the given hexpairs and execute them", "aexa", " mov rax, 33", "assemble instruction and execute it", NULL }; -static const char *help_msg_a[] = { +static RCoreHelpMessage help_msg_a = { "Usage:", "a", "[abdefFghoprxstc] [...]", "a", "", "alias for aai - analysis information", "a*", "", "same as afl*;ah*;ax*", @@ -51,19 +51,19 @@ static const char *help_msg_a[] = { NULL }; -static const char *help_msg_afna[] = { +static RCoreHelpMessage help_msg_afna = { "Usage:", "afna", " # construct a function name and rename the function for the current offset.", "", "", "Based on flags or methods calls found inside that function.", NULL }; -static const char *help_msg_afu[] = { +static RCoreHelpMessage help_msg_afu = { "Usage:", "afu", "[addr] # resize and analyze function from current address until addr.", "afu", " 0x100004093", "resize and analyze function from current address until 0x100004093", NULL }; -static const char *help_msg_aae[] = { +static RCoreHelpMessage help_msg_aae = { "Usage:", "aae", "[pf] ([addr]) # analyze all kind of stuff using esil", "aaep", "", "same as aepa@@@i - define anal pins by import flag names", "aaep", "a", "run 'aep ret0@@@i' and then 'aaep' - all unknown imports are faked to return 0", @@ -73,14 +73,14 @@ static const char *help_msg_aae[] = { NULL }; -static const char *help_msg_aav[] = { +static RCoreHelpMessage help_msg_aav = { "Usage:", "aav", "[sat] # find values referencing a specific section or map", "aav", "", "find absolute reference values", "aavr", "", "find relative reference values (address + 4 byte signed int)", NULL }; -static const char *help_msg_aan[] = { +static RCoreHelpMessage help_msg_aan = { "Usage:", "aan", "[rg] # automatically name functions.", "aan", "", "autoname all functions", "aang", "", "autoname all golang functions", @@ -88,19 +88,19 @@ static const char *help_msg_aan[] = { NULL }; -static const char *help_msg_afm[] = { +static RCoreHelpMessage help_msg_afm = { "Usage:", "afm", "[name] # merge two functions.", "afm", " sym.func.100003d74", "merge current function into 0x100003d74", NULL }; -static const char *help_msg_aF[] = { +static RCoreHelpMessage help_msg_aF = { "Usage:", "aF", " # analyze a function, but using anal.depth=1", "aF", "", "check af? for more options and information.", NULL }; -static const char *help_msg_an[] = { +static RCoreHelpMessage help_msg_an = { "Usage:", "an", " # analyze name for the current address", "an", "", "show flag/function/symbol name", "an*", "", "same as above but in r2 commands", @@ -108,13 +108,13 @@ static const char *help_msg_an[] = { NULL }; -static const char *help_msg_a8[] = { +static RCoreHelpMessage help_msg_a8 = { "Usage:", "a8", "[hexpairs] # analyze the byte array given as input", "a8 ", "5548", "analyzes 5548 byte array", NULL }; -static const char *help_msg_ap[] = { +static RCoreHelpMessage help_msg_ap = { "Usage:", "ap[?]", " # analyze prelude in current offset", "ap", "", "check if current offset contains a function prelude", "apl", "", "list available function preludes defined by the arch plugin", @@ -126,7 +126,7 @@ static const char *help_msg_ap[] = { NULL }; -static const char *help_msg_avg[] = { +static RCoreHelpMessage help_msg_avg = { "Usage:", "avg", " # analyze variable global", "avg", "", "use ESIL emulation to find out arguments of a call (uses 'abte')", "avg", " [type] [name]", "add global", @@ -134,14 +134,14 @@ static const char *help_msg_avg[] = { NULL }; -static const char *help_msg_aC[] = { +static RCoreHelpMessage help_msg_aC = { "Usage:", "aC[fej] [addr-of-call]", " # analyze call args", "aCe", "", "use ESIL emulation to find out arguments of a call (uses 'abte')", "aCf", "", "same as .aCe* $$ @@=`pdr~call`", NULL }; -static const char *help_msg_aaf[] = { +static RCoreHelpMessage help_msg_aaf = { "Usage:", "aaf[efrt?]", " # analyse all functionsee also 'af' and 'afna'", "aaf", "", "same as afr@@c:isq", "aafe", " ", "same as aef@@F", @@ -152,7 +152,7 @@ static const char *help_msg_aaf[] = { NULL }; -static const char *help_msg_aaa[] = { +static RCoreHelpMessage help_msg_aaa = { "Usage:", "aa[a[a[a]]]", " # automatically analyze the whole program", "a", " ", "show code analysis statistics", "aa", " ", "alias for 'af@@ sym.*;af@entry0;afva'", @@ -162,7 +162,7 @@ static const char *help_msg_aaa[] = { NULL }; -static const char *help_msg_aa[] = { +static RCoreHelpMessage help_msg_aa = { "Usage:", "aa[0*?]", " # see also 'af' and 'afna'", "aa", " ", "alias for 'af@@ sym.*;af@entry0;afva'", //;.afna @@ fcn.*'", "aaa", "[?]", "autoname functions after aa (see afna)", @@ -192,7 +192,7 @@ static const char *help_msg_aa[] = { NULL }; -static const char *help_msg_afls[] = { +static RCoreHelpMessage help_msg_afls = { "Usage:", "afls", "[afls] # sort function list", "afls", "", "same as aflsa", "aflsa", "", "sort by address (same as afls)", @@ -211,7 +211,7 @@ static const RCoreHelpMessage help_msg_aflx = { NULL }; -static const char *help_msg_ai[] = { +static RCoreHelpMessage help_msg_ai = { "Usage:", "ai", "[j*] [sz] # analysis/address information/imports", "ai", " @addr", "show address information", "aia", "", "show architecture specific information instruction size and alignment details", @@ -221,7 +221,7 @@ static const char *help_msg_ai[] = { NULL }; -static const char *help_msg_aar[] = { +static RCoreHelpMessage help_msg_aar = { "Usage:", "aar", "[j*] [sz] # search and analyze xrefs", "aar", " [sz]", "analyze xrefs in current section or sz bytes of code", "aarr", "", "analyze all function reference graph to find more functions (EXPERIMENTAL)", @@ -230,7 +230,7 @@ static const char *help_msg_aar[] = { NULL }; -static const char *help_msg_ab[] = { +static RCoreHelpMessage help_msg_ab = { "Usage:", "ab", "# analyze basic block", "ab", " [addr]", "show basic block information at given address", "ab.", "", "same as: ab $$", @@ -247,7 +247,7 @@ static const char *help_msg_ab[] = { NULL }; -static const char *help_msg_abl[] = { +static RCoreHelpMessage help_msg_abl = { "Usage:", "abl", "analyzed basicblocks listing", "abl", "", "list all program-wide basic blocks analyzed", "abl,", " [table-query]", "render the list using a table", @@ -257,7 +257,7 @@ static const char *help_msg_abl[] = { NULL }; -static const char *help_msg_abt[] = { +static RCoreHelpMessage help_msg_abt = { "Usage:", "abt", "[addr] [num] # find num paths from current offset to addr", "abt", " [addr] [num]", "find num paths from current offset to addr", "abte", " [addr]", "emulate from beginning of function to the given address", @@ -265,7 +265,7 @@ static const char *help_msg_abt[] = { NULL }; -static const char *help_msg_ac[] = { +static RCoreHelpMessage help_msg_ac = { "Usage:", "ac", "anal classes commands", "acl", "[j*]", "list all classes", "acll", "[j] (class_name)", "list all or single class detailed", @@ -286,7 +286,7 @@ static const char *help_msg_ac[] = { NULL }; -static const char *help_msg_ad[] = { +static RCoreHelpMessage help_msg_ad = { "Usage:", "ad", "[kt] [...]", "ad", " [N] [D]", "analyze N data words at D depth", "ad4", " [N] [D]", "analyze N data words at D depth (asm.bits=32)", @@ -298,7 +298,7 @@ static const char *help_msg_ad[] = { NULL }; -static const char *help_msg_aes[] = { +static RCoreHelpMessage help_msg_aes = { "Usage:", "aes[pbosu]", "esil stepping utilities", "aesp", " [X] [N]", "evaluate N instr from offset X", "aesb", "", "step back", @@ -308,10 +308,11 @@ static const char *help_msg_aes[] = { "aesu", " [addr]", "step until given address", "aesue", " [esil]", "step until esil expression match", "aesuo", " [optype]", "step until given opcode type", + "aesB", " [addr] [N] @ [from-addr]", "step over every N instructions", NULL }; -static const char *help_msg_aei[] = { +static RCoreHelpMessage help_msg_aei = { "Usage:", "aei", "[smp] [...]", "aei", "", "initialize ESIL VM state (aei- to deinitialize)", "aeis", " argc [argv] [envp]", "initialize entrypoint stack environment", @@ -320,7 +321,7 @@ static const char *help_msg_aei[] = { NULL }; -static const char *help_msg_ae[] = { +static RCoreHelpMessage help_msg_ae = { "Usage:", "ae[idesr?] [arg]", "ESIL code emulation", "ae", " [expr]", "evaluate ESIL expression", "ae?", "", "show this help", @@ -347,7 +348,7 @@ static const char *help_msg_ae[] = { NULL }; -static const char *help_detail_ae[] = { +static RCoreHelpMessage help_detail_ae = { "Examples:", "ESIL", " examples and documentation", "=", "", "assign updating internal flags", ":=", "", "assign without updating internal flags", @@ -433,7 +434,7 @@ static const char *help_detail_ae[] = { NULL }; -static const char *help_msg_aea[] = { +static RCoreHelpMessage help_msg_aea = { "Examples:", "aea", " show regs and memory accesses used in a range", "aea", " [ops]", "show regs/memory accesses used in N instructions", "aea*", " [ops]", "create mem.* flags for memory accesses", @@ -457,7 +458,7 @@ static const char *help_msg_aea[] = { NULL }; -static const char *help_msg_aec[] = { +static RCoreHelpMessage help_msg_aec = { "Examples:", "aec", " continue until ^c", "aec", "", "continue until exception", "aecs", "", "continue until syscall", @@ -467,13 +468,13 @@ static const char *help_msg_aec[] = { NULL }; -static const char *help_msg_aeC[] = { +static RCoreHelpMessage help_msg_aeC = { "Examples:", "aeC", " arg0 arg1 ... @ calladdr", "aeC", " 1 2 @ sym._add", "Call sym._add(1,2)", NULL }; -static const char *help_msg_aeg[] = { +static RCoreHelpMessage help_msg_aeg = { "Usage:", "aeg[fniv]", " [...]", "aeg", "", "analyze current instruction as an esil graph", "aegb", "", "data flow graph for current basic block (aeg `pieq $Fi`)", @@ -483,7 +484,7 @@ static const char *help_msg_aeg[] = { NULL }; -static const char *help_msg_aep[] = { +static RCoreHelpMessage help_msg_aep = { "Usage:", "aep[-*c] ", " [...] manage esil pins, run r2 commands instead of esil", "aepc", " [addr]", "change program counter for esil", "aep*", "", "list pins in r2 commands", @@ -499,7 +500,7 @@ static const char *help_msg_aep[] = { NULL }; -static const char *help_msg_aek[] = { +static RCoreHelpMessage help_msg_aek = { "Usage:", "aek ", " [...]", "aek", "", "dump the esil.stats database contents", "aek ", "sdb.query", "evaluate sdb query on esil.stats db", @@ -507,14 +508,14 @@ static const char *help_msg_aek[] = { NULL }; -static const char *help_msg_aets[] = { +static RCoreHelpMessage help_msg_aets = { "Usage:", "aets ", " [...]", "aets+", "", "start ESIL trace session", "aets-", "", "stop ESIL trace session", NULL }; -static const char *help_msg_af[] = { +static RCoreHelpMessage help_msg_af = { "Usage:", "af", "", "af", " ([name]) ([addr])", "analyze functions (start at addr or $$)", "af+", " addr name [type] [diff]", "hand craft a function (requires afb+)", @@ -547,7 +548,7 @@ static const char *help_msg_af[] = { NULL }; -static const char *help_msg_afb[] = { +static RCoreHelpMessage help_msg_afb = { "Usage:", "afb", " list basic blocks of given function", ".afbr-", "", "set breakpoint on every return address of the function", ".afbr-*", "", "remove breakpoint on every return address of the function", @@ -566,7 +567,7 @@ static const char *help_msg_afb[] = { NULL }; -static const char *help_msg_afc[] = { +static RCoreHelpMessage help_msg_afc = { "Usage:", "afc[agl?]", "# see also tcc command to manage all calling conventions", "afc", " ccname", "manually set calling convention for current function", "afc", "", "show calling convention for the Current function (same as tcc)", @@ -581,7 +582,7 @@ static const char *help_msg_afc[] = { NULL }; -static const char *help_msg_afC[] = { +static RCoreHelpMessage help_msg_afC = { "Usage:", "afC", " [addr]", "afC", "", "function cycles cost", "afCc", "", "cyclomatic complexity", @@ -589,7 +590,7 @@ static const char *help_msg_afC[] = { NULL }; -static const char *help_msg_afi[] = { +static RCoreHelpMessage help_msg_afi = { "Usage:", "afi[jlp*]", " ", "afi", "", "show information of the function", "afi.", "", "show function name in current offset", @@ -603,7 +604,7 @@ static const char *help_msg_afi[] = { NULL }; -static const char *help_msg_afis[] = { +static RCoreHelpMessage help_msg_afis = { "Usage:", "afis[ft]", "", "afis", "", "enumerate unique opcodes in function", "afisa", "[fo]", "enumerate all the meta of all the functions", @@ -613,7 +614,7 @@ static const char *help_msg_afis[] = { NULL }; -static const char *help_msg_afl[] = { +static RCoreHelpMessage help_msg_afl = { "Usage:", "afl", " List all functions", "afl", "", "list functions", "afl.", "", "display function in current offset (see afi.)", @@ -632,7 +633,7 @@ static const char *help_msg_afl[] = { NULL }; -static const char *help_msg_afll[] = { +static RCoreHelpMessage help_msg_afll = { "Usage:", "", " List functions in verbose mode", "", "", "", "Table fields:", "", "", @@ -655,7 +656,7 @@ static const char *help_msg_afll[] = { NULL }; -static const char *help_msg_afn[] = { +static RCoreHelpMessage help_msg_afn = { "Usage:", "afn[sa]", " Analyze function names", "afn", " [name]", "rename the function", "afn", " base64:encodedname", "rename the function", @@ -666,7 +667,7 @@ static const char *help_msg_afn[] = { NULL }; -static const char *help_msg_afs[] = { +static RCoreHelpMessage help_msg_afs = { "Usage:", "afs[r]", " Analyze function signatures", "afs", "[!] ([fcnsign])", "get/set function signature at current address (afs! uses cfg.editor)", "afs*", " ([signame])", "get function signature in flags", @@ -675,13 +676,13 @@ static const char *help_msg_afs[] = { NULL }; -static const char *help_msg_aft[] = { +static RCoreHelpMessage help_msg_aft = { "Usage:", "aft", "", "aft", "", "type matching analysis for current function", NULL }; -static const char *help_msg_afv[] = { +static RCoreHelpMessage help_msg_afv = { "Usage:", "afv[rbs]"," Function variables manipulation", "afv*", "", "output r2 command to add args/locals to flagspace", "afv-", "([name])", "remove all or given var", @@ -700,7 +701,7 @@ static const char *help_msg_afv[] = { NULL }; -static const char *help_msg_aeim[] = { +static RCoreHelpMessage help_msg_aeim = { "Usage:", "aeim", " [addr] [size] [name] - initialize the ESIL VM stack", "aeim", "", "initialize esil memory with default values from esil.stack.* evals", "aeim", " 0x10000", "same as aeim@e:esil.stack.addr=0x10000", @@ -708,7 +709,7 @@ static const char *help_msg_aeim[] = { NULL }; -static const char *help_msg_afvb[] = { +static RCoreHelpMessage help_msg_afvb = { "Usage:", "afvb", " [idx] [name] ([type])", "afvb", "", "list base pointer based arguments, locals", "afvb*", "", "same as afvb but in r2 commands", @@ -720,7 +721,7 @@ static const char *help_msg_afvb[] = { NULL }; -static const char *help_msg_afvr[] = { +static RCoreHelpMessage help_msg_afvr = { "Usage:", "afvr", " [reg] [type] [name]", "afvr", "", "list register based arguments", "afvr*", "", "same as afvr but in r2 commands", @@ -732,7 +733,7 @@ static const char *help_msg_afvr[] = { NULL }; -static const char *help_msg_afvs[] = { +static RCoreHelpMessage help_msg_afvs = { "Usage:", "afvs", " [idx] [type] [name]", "afvs", "", "list stack based arguments and locals", "afvs*", "", "same as afvs but in r2 commands", @@ -744,7 +745,7 @@ static const char *help_msg_afvs[] = { NULL }; -static const char *help_msg_ag[] = { +static RCoreHelpMessage help_msg_ag = { "Usage:", "ag [addr]", "", "Graph commands:", "", "", "aga", "[format]", "data references graph", @@ -778,7 +779,7 @@ static const char *help_msg_ag[] = { NULL }; -static const char *help_msg_age[] = { +static RCoreHelpMessage help_msg_age = { "Usage:", "age [title1] [title2]", "", "Examples:", "", "", "age", " title1 title2", "add an edge from the node with \"title1\" as title to the one with title \"title2\"", @@ -791,7 +792,7 @@ static const char *help_msg_age[] = { NULL }; -static const char *help_msg_agn[] = { +static RCoreHelpMessage help_msg_agn = { "Usage:", "agn [title] [body]", "", "Examples:", "", "", "agn", " title1 body1", "add a node with title \"title1\" and body \"body1\"", @@ -802,7 +803,7 @@ static const char *help_msg_agn[] = { NULL }; -static const char *help_msg_ah[] = { +static RCoreHelpMessage help_msg_ah = { "Usage:", "ah[lba-]", "analysis Hints", "ah?", "", "show this help", "ah?", " offset", "show hint of given offset", @@ -832,7 +833,7 @@ static const char *help_msg_ah[] = { NULL }; -static const char *help_msg_ahs[] = { +static RCoreHelpMessage help_msg_ahs = { "Usage:", "ahs [size] [@ addr]", " Define opcode size hint", "ahs", " 16", "Hint the analysis to make the instruction 16 bytes in size", "ahs-", "", "Unset the instruction size hint in the current offset", @@ -841,7 +842,7 @@ static const char *help_msg_ahs[] = { NULL }; -static const char *help_msg_aho[] = { +static RCoreHelpMessage help_msg_aho = { "Usage:", "aho [optype] [@ addr]", " Define opcode type hint", "aho", " nop", "change the opcode type in current address to be considered a NOP", "aho", "", "show the current opcode hint if any", @@ -850,7 +851,7 @@ static const char *help_msg_aho[] = { NULL }; -static const char *help_msg_ahb[] = { +static RCoreHelpMessage help_msg_ahb = { "Usage:", "ahb [8|16|32|64] [@ addr]", " Define asm.bits hint at given address", "ahb", " 16", "set asm.bits=16 in the given address", "ahb", "", "get asm.bits used in given addr (current seek)", @@ -859,13 +860,13 @@ static const char *help_msg_ahb[] = { NULL }; -static const char *help_msg_ahr[] = { +static RCoreHelpMessage help_msg_ahr = { "Usage:", "ahr addr", " Set instruction as return type (similar to 'aho ret'?)", "ahr", " $$", "current instruction may be considered as the end of a function", NULL }; -static const char *help_msg_ahi[] = { +static RCoreHelpMessage help_msg_ahi = { "Usage:", "ahi [2|8|10|10u|16|bodhipSs] [@ offset]", " Define numeric base", "ahi", " ", "set numeric base (2, 8, 10, 16)", "ahi", " 10|d", "set base to signed decimal (10), sign bit should depend on receiver size", @@ -881,7 +882,7 @@ static const char *help_msg_ahi[] = { NULL }; -static const char *help_msg_aht[] = { +static RCoreHelpMessage help_msg_aht = { "Usage:", "aht[s] [addr|type]", "mark immediate as type offset (moved to aho)", "ahts", " ", "list all matching structure offsets", "aht", " ", "change immediate to structure offset", @@ -889,14 +890,14 @@ static const char *help_msg_aht[] = { NULL }; -static const char *help_msg_aot[] = { +static RCoreHelpMessage help_msg_aot = { "Usage:", "aot[l]", "list opcode types", "aot", "", "show type of the current instruction", "aotl", "", "list all possible opcode types (See /atl)", NULL }; -static const char *help_msg_aom[] = { +static RCoreHelpMessage help_msg_aom = { "Usage:", "aom[ljd] [arg]", "list opcode mnemonics", "aom", "", "show instruction mnemonic", "aom.", "", "show instruction mnemonic in current address", @@ -906,7 +907,7 @@ static const char *help_msg_aom[] = { NULL }; -static const char *help_msg_ao[] = { +static RCoreHelpMessage help_msg_ao = { "Usage:", "ao[e?] [len]", "analyze Opcodes", "ao", " 5", "display opcode analysis of 5 opcodes", "ao*", "", "display opcode in r commands", @@ -925,7 +926,7 @@ static const char *help_msg_ao[] = { NULL }; -static const char *help_msg_ar[] = { +static RCoreHelpMessage help_msg_ar = { "Usage: ar", "", "# Analysis Registers", "ar", "", "show 'gpr' registers", "ar.", ">$snapshot", "show r2 commands to set register values to the current state", @@ -959,7 +960,7 @@ static const char *help_msg_ar[] = { NULL }; -static const char *help_msg_ara[] = { +static RCoreHelpMessage help_msg_ara = { "Usage:", "ara[+-s]", "register Arena Push/Pop/Swap", "ara", "", "show all register arenas allocated", "ara", "+", "push a new register arena for each type", @@ -968,13 +969,13 @@ static const char *help_msg_ara[] = { NULL }; -static const char *help_msg_arw[] = { +static RCoreHelpMessage help_msg_arw = { "Usage:", "arw ", "# Set contents of the register arena", "arw", " ", "set contents of the register arena", NULL }; -static const char *help_msg_as[] = { +static RCoreHelpMessage help_msg_as = { "Usage: as[ljk?]", "", "syscall name <-> number utility", "as", "", "show current syscall and arguments", "as", " 4", "show syscall 4 based on asm.os and current regs/mem", @@ -987,7 +988,7 @@ static const char *help_msg_as[] = { NULL }; -static const char *help_msg_av[] = { +static RCoreHelpMessage help_msg_av = { "Usage:", "av[?jr*]", " C++ vtables and RTTI", "av", "", "search for vtables in data sections and show results", "avj", "", "like av, but as json", @@ -999,7 +1000,7 @@ static const char *help_msg_av[] = { NULL }; -static const char *help_msg_ax[] = { +static RCoreHelpMessage help_msg_ax = { "Usage:", "ax[?d-l*]", " # see also 'afx?'", "ax", " addr [at]", "add code ref pointing to addr (from curseek)", "ax", "", "list refs", @@ -1028,7 +1029,7 @@ static const char *help_msg_ax[] = { NULL }; -static const char *help_msg_axl[]= { +static RCoreHelpMessage help_msg_axl= { "Usage:", "axl[jcq]", "show global xrefs", "axl", "", "list all xrefs", "axlj", "", "list xrefs in json format", @@ -1037,14 +1038,14 @@ static const char *help_msg_axl[]= { NULL }; -static const char *help_msg_axv[]= { +static RCoreHelpMessage help_msg_axv= { "Usage:", "axv[?j]", "show xrefs to local variables in current function", "axv", " ([addr])", "optionally you can specify address instead of current seek", "axvj", " ([addr])", "show in json", NULL }; -static const char *help_msg_axt[]= { +static RCoreHelpMessage help_msg_axt= { "Usage:", "axt[?gq*]", "find data/code references to this address", "axtj", " [addr]", "find data/code references to this address and print in json format", "axtg", " [addr]", "display commands to generate graphs according to the xrefs", @@ -1054,7 +1055,7 @@ static const char *help_msg_axt[]= { NULL }; -static const char *help_msg_axf[]= { +static RCoreHelpMessage help_msg_axf= { "Usage:", "axf[?gq*]", "find data/code references from this address", "axfj", " [addr]", "find data/code references to this address and print in json format", "axfg", " [addr]", "display commands to generate graphs according to the xrefs", @@ -1314,7 +1315,7 @@ static void find_refs(RCore *core, const char *glob) { glob = "str."; } if (*glob == '?') { - eprintf ("Usage: axF [flag-str-filter]\n"); + r_core_cmd_help_match (core, help_msg_ax, "axF", true); return; } R_LOG_WARN ("Finding references of flags matching '%s'", glob); @@ -3978,7 +3979,7 @@ static void cmd_afbc(RCore *core, const char *input) { return; } if (*ptr == '?') { - eprintf ("Usage: afbc red @ addrOfBlock\n"); + r_core_cmd_help_match (core, help_msg_afb, "afbc", true); } else if (!*ptr) { RAnalBlock *bb = r_anal_get_block_at (core->anal, core->offset); if (bb && (bb->color.r || bb->color.g || bb->color.b)) { @@ -4432,7 +4433,7 @@ static int cmd_af(RCore *core, const char *input) { case 'o': // "afo" switch (input[2]) { case '?': - eprintf ("Usage: afo[?sj] ([name|offset])\n"); + r_core_cmd_help_match (core, help_msg_af, "afo", true); break; case 'j': { @@ -4505,8 +4506,6 @@ static int cmd_af(RCore *core, const char *input) { break; case 'l': // "afil" if (input[3] == '?') { - // TODO #7967 help refactor - help_msg_afll[1] = "afil"; r_core_cmd_help (core, help_msg_afll); break; } @@ -4694,8 +4693,6 @@ static int cmd_af(RCore *core, const char *input) { break; case 'l': // "afll" if (input[3] == '?') { - // TODO #7967 help refactor - help_msg_afll[1] = "afll"; r_core_cmd_help (core, help_msg_afll); break; } @@ -4885,7 +4882,7 @@ static int cmd_af(RCore *core, const char *input) { sdb_free (db); } } else { - eprintf ("Usage: afco [dbpath] - open calling conventions defined in local file.\n"); + r_core_cmd_help_match (core, help_msg_afc, "afco", true); } free (dbpath); break; @@ -5000,7 +4997,7 @@ static int cmd_af(RCore *core, const char *input) { R_LOG_ERROR ("afB: Cannot find function to set bits at 0x%08"PFMT64x, core->offset); } } else { - eprintf ("Usage: afB [bits] # bits can be: 0, 8, 16, 32 or 64. when using 0, disables the hint\n"); + r_core_cmd_help_match (core, help_msg_af, "afB", true); } break; case 'b': // "afb" @@ -5094,7 +5091,7 @@ static int cmd_af(RCore *core, const char *input) { off = r_num_math (core->num, p); } if (*name == '?') { - eprintf ("Usage: afn newname [off] # set new name to given function\n"); + r_core_cmd_help_match (core, help_msg_afn, "afn", true); } else { if (r_str_startswith (name, "base64:")) { char *res = (char *)r_base64_decode_dyn (name + 7, -1); @@ -5653,7 +5650,7 @@ void cmd_anal_reg(RCore *core, const char *str) { break; case '?': { // "ars?" // TODO #7967 help refactor: dup from drp - const char *help_msg[] = { + RCoreHelpMessage help_msg = { "Usage:", "drs", " # Register states commands", "drs", "", "list register stack", "drs+", "", "push register state", @@ -7378,7 +7375,7 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) { reg_name_roll_set (core, "PC", r_num_math (core->num, input + 3)); r_core_cmd0 (core, ".ar*"); } else { - eprintf ("Usage: aepc [address] # same as 'ar PC=..'\n"); + r_core_cmd_help_match (core, help_msg_aep, "aepc", true); } break; case 'k': @@ -7473,14 +7470,12 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) { r_core_cmd0 (core, ".ar*"); break; case 'B': // "aesB" - { n = strchr (input + 2, ' '); - char *n2 = NULL; if (n) { n = (char *)r_str_trim_head_ro (n + 1); } if (n) { - n2 = strchr (n, ' '); + char *n2 = strchr (n, ' '); if (n2) { *n2++ = 0; } @@ -7488,15 +7483,14 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) { ut64 nth = n2? r_num_math (core->num, n2): 1; cmd_aespc (core, core->offset, off, (int)nth); } else { - eprintf ("Usage: aesB [until-addr] [nth-opcodes] @ [from-addr]\n"); - } + r_core_cmd_help_match (core, help_msg_aes, "aesB", true); } break; case 'u': // "aesu" until_expr = NULL; until_addr = UT64_MAX; if (r_str_endswith (input, "?")) { - r_core_cmd0 (core, "aes?~aesu"); + r_core_cmd_help_match (core, help_msg_aes, "aesu", true); } else switch (input[2]) { case 'e': // "aesue" until_expr = input + 3; @@ -7549,7 +7543,7 @@ static void cmd_anal_esil(RCore *core, const char *input, bool verbose) { r_anal_op_free (op); r_core_cmd0 (core, ".ar*"); } else { - eprintf ("Usage: aesou [addr] # step over until given address\n"); + r_core_cmd_help_match (core, help_msg_aes, "aesou", true); } break; case 'p': //"aesp" @@ -9764,7 +9758,7 @@ static void cmd_anal_hint(RCore *core, const char *input) { } else if (input[1] == '-') { r_anal_hint_unset_syntax (core->anal, core->offset); } else { - eprintf ("Usage: ahS att\n"); + r_core_cmd_help_match (core, help_msg_ah, "ahS", true); } break; case 'd': // "ahd" set opcode string @@ -9773,7 +9767,7 @@ static void cmd_anal_hint(RCore *core, const char *input) { } else if (input[1] == '-') { r_anal_hint_unset_opcode (core->anal, core->offset); } else { - eprintf ("Usage: ahd popall\n"); + r_core_cmd_help_match (core, help_msg_ah, "ahd", true); } break; case 'e': // "ahe" set ESIL string @@ -9782,7 +9776,7 @@ static void cmd_anal_hint(RCore *core, const char *input) { } else if (input[1] == '-') { r_anal_hint_unset_esil (core->anal, core->offset); } else { - eprintf ("Usage: ahe r0,pc,=\n"); + r_core_cmd_help_match (core, help_msg_ah, "ahe", true); } break; #if 0 @@ -12170,7 +12164,7 @@ static int cmd_anal_all(RCore *core, const char *input) { if (!input[1] || input[1] == ' ' || input[1] == 'a') { r_core_anal_inflags (core, input + 1); } else { - eprintf ("Usage: aaF[a] - analyze functions in flag bounds (aaFa uses af/a2f instead of af+/afb+)\n"); + r_core_cmd_help_match (core, help_msg_aa, "aaF", false); } break; case 'n': // "aan" diff --git a/libr/core/cmd_cmp.c b/libr/core/cmd_cmp.c index ba6a8d84f4..21a632a8f3 100644 --- a/libr/core/cmd_cmp.c +++ b/libr/core/cmd_cmp.c @@ -2,7 +2,7 @@ #include "r_core.h" -static const char *help_message_ci[] = { +static RCoreHelpMessage help_message_ci = { "Usage: ci", "[sil] ([obid])", "Compare two bin objects", "cis", " 0", "compare symbols with current `ob 1` with given obid (0)", "cii", " 0", "compare imports", @@ -10,17 +10,18 @@ static const char *help_message_ci[] = { NULL }; -static const char *help_msg_cmp[] = { +static RCoreHelpMessage help_msg_cmp = { "Usage: cmp", " [file] [file]", "Compare two ($alias) files, and change $? value", "cmp", " ls ls.old", "compare contents of given files", "cmp", " $a $b", "same as above but using alias files", NULL }; -static const char *help_msg_c[] = { +static RCoreHelpMessage help_msg_c = { "Usage:", "c[?dfx] [argument]", " # Compare", "c", " [string]", "compare a plain with escaped chars string", - "c*", " [string]", "same as above, but printing r2 commands instead", + "c*", " [string]", "same as c, but printing r2 commands instead", + "cj", " [string]", "same as c, with JSON output", "c1", " [addr]", "compare byte at addr with current offset", "c2", "[*] [value]", "compare word at offset with given value", "c4", "[*] [value]", "compare doubleword at offset with given value", @@ -34,7 +35,7 @@ static const char *help_msg_c[] = { // "cc", " [offset]", "code bindiff current block against offset" // "cD", " [file]", "like above, but using radiff -b", "cf", " [file]", "compare contents of file at current seek", - "cg", "[?] [o] [file]", "graphdiff current file and [file]", + "cg", "[fo?] [file]", "graphdiff current file and [file]", "ci", "[?] [obid] ([obid2])", "compare two bin-objects (symbols, imports, ...)", "cl|cls|clear", "", "clear screen, (clear0 to goto 0, 0 only)", "cmp", " [file] [file]", "compare two files", @@ -49,6 +50,27 @@ static const char *help_msg_c[] = { NULL }; +static RCoreHelpMessage help_msg_cu = { + "Usage: cu", " [offset]", "# Prints unified comparison to make hexpatches", + "cu", " $$+1 > p", "compare hexpairs from current seek and +1", + "cu1", " $$+1 > p", "compare bytes from current seek and +1", + "cu2", " $$+1 > p", "compare words (half, 16bit) from current seek and +1", + "cu4", " $$+1 > p", "compare dwords from current seek and +1", + "cu8", " $$+1 > p", "compare qwords from current seek and +1", + "cud", " $$+1 > p", "compare disasm current seek and +1", + "wu", " p", "apply unified hex patch (see output of cu)", + "curl", " [http-url]", "", + NULL +}; + +static RCoreHelpMessage help_msg_cg = { + "Usage: cg", "", "Graph compare", + "cg", " [file]", "diff ratio among functions (columns: off-A, match-ratio, off-B)", + "cgf", " [fcn]", "compare functions (curseek vs fcn)", + "cgo", "", "opcode-bytes code graph diff", + NULL +}; + R_API void r_core_cmpwatch_free(RCoreCmpWatcher *w) { free (w->ndata); free (w->odata); @@ -428,7 +450,7 @@ static void nowatchers(ut64 addr) { /* Returns 0 if operation succeeded, 1 otherwise */ static int cmd_cmp_watcher(RCore *core, const char *input) { - static const char *help_msg_cw[] = { + static RCoreHelpMessage help_msg_cw = { "Usage: cw", "[args]", "Manage compare watchers; See if and how memory changes", "cw??", "", "Show more info about watchers", "cw ", "addr sz cmd", "Add a compare watcher", @@ -701,7 +723,7 @@ static int cmd_cmp_disasm(RCore *core, const char *input, int mode) { static int cmd_cp(void *data, const char *input) { RCore *core = (RCore *)data; bool use_corefile; - const char *help_msg_cp[] = { + RCoreHelpMessage help_msg_cp = { "cp", " src dst", "Standard file copy", "cp", ".[ext]", "Copy current file to .ext", NULL @@ -978,7 +1000,7 @@ static void cmd_curl(RCore *core, const char *arg) { if (r_sys_getenv_asbool ("R2_CURL")) { r_sys_cmdf ("curl %s", arg); } else { - if (strstr (arg, "http") && strstr (arg, "://")) { + if (r_str_startswith (arg, "http://") || r_str_startswith (arg, "https://")) { int len; char *s = r_socket_http_get (arg, NULL, &len); if (s) { @@ -986,7 +1008,7 @@ static void cmd_curl(RCore *core, const char *arg) { free (s); } } else { - eprintf ("Usage: curl [http-url]\n"); + r_core_cmd_help_match (core, help_msg_cu, "curl", true); } } } @@ -1079,9 +1101,9 @@ static int cmd_cmp(void *data, const char *input) { case 'w': return cmd_cmp_watcher (core, input + 1); break; - case '*': // c*" + case '*': // "c*" if (!input[2]) { - eprintf ("Usage: cx* 00..22'\n"); + r_core_cmd_help_match (core, help_msg_c, "c*", true); return 0; } @@ -1097,7 +1119,7 @@ static int cmd_cmp(void *data, const char *input) { } case 'j': // "cj" if (input[1] != ' ') { - eprintf ("Usage: cj [string]\n"); + r_core_cmd_help_match (core, help_msg_c, "cj", true); } else { char *str = strdup (input + 2); int len = r_str_unescape (str); @@ -1113,14 +1135,14 @@ static int cmd_cmp(void *data, const char *input) { break; case '*': if (input[2] != ' ') { - eprintf ("Usage: cx* 00..22'\n"); + r_core_cmd_help_match (core, help_msg_c, "cx*", true); return 0; } mode = '*'; input += 3; break; default: - eprintf ("Usage: cx 00..22'\n"); + r_core_cmd_help_match (core, help_msg_c, "cx", true); return 0; } if (!(filled = (char *) malloc (strlen (input) + 1))) { @@ -1266,7 +1288,7 @@ static int cmd_cmp(void *data, const char *input) { } case 'c': // "cc" if (input[1] == '?') { // "cc?" - r_core_cmd0 (core, "c?~cc"); + r_core_cmd_help_match (core, help_msg_c, "cc", false); } else if (input[1] == 'd') { // "ccd" if (input[2] == 'd') { // "ccdd" cmd_cmp_disasm (core, input + 3, 'd'); @@ -1305,37 +1327,29 @@ static int cmd_cmp(void *data, const char *input) { RCore *core2; char *file2 = NULL; switch (input[1]) { - case 'o': // "cgo" + case 'o': // "cgo" file2 = (char *) r_str_trim_head_ro (input + 2); if (*file2) { r_anal_diff_setup (core->anal, true, -1, -1); } else { - eprintf ("Usage: cgo [file]\n"); + r_core_cmd_help_match (core, help_msg_cg, "cgo", true); return false; } break; - case 'f': // "cgf" + case 'f': // "cgf" R_LOG_TODO ("agf is experimental"); r_anal_diff_setup (core->anal, true, -1, -1); r_core_gdiff_fcn (core, core->offset, r_num_math (core->num, input + 2)); return false; - case ' ': + case ' ': // "cg " file2 = (char *) r_str_trim_head_ro (input + 2); r_anal_diff_setup (core->anal, false, -1, -1); break; - default: { - const char *help_message[] = { - "Usage: cg", "", "Graph code commands", - "cg", "", "diff ratio among functions (columns: off-A, match-ratio, off-B)", - "cgf", "[fcn]", "compare functions (curseek vs fcn)", - "cgo", "", "opcode-bytes code graph diff", - NULL - }; - r_core_cmd_help (core, help_message); + default: + r_core_cmd_help (core, help_msg_cg); return false; } - } if (r_file_size (file2) <= 0) { R_LOG_ERROR ("Cannot compare with file %s", file2); @@ -1394,18 +1408,7 @@ static int cmd_cmp(void *data, const char *input) { cmd_cmp_disasm (core, input + 2, 'u'); break; default: { - const char *help_msg[] = { - "Usage: cu", " [offset]", "# Prints unified comparison to make hexpatches", - "cu", " $$+1 > p", "compare hexpairs from current seek and +1", - "cu1", " $$+1 > p", "compare bytes from current seek and +1", - "cu2", " $$+1 > p", "compare words (half, 16bit) from current seek and +1", - "cu4", " $$+1 > p", "compare dwords from current seek and +1", - "cu8", " $$+1 > p", "compare qwords from current seek and +1", - "cud", " $$+1 > p", "compare disasm current seek and +1", - "wu", " p", "apply unified hex patch (see output of cu)", - NULL - }; - r_core_cmd_help (core, help_msg); + r_core_cmd_help (core, help_msg_cu); } } break; @@ -1469,12 +1472,7 @@ static int cmd_cmp(void *data, const char *input) { r_core_return_value (core, 1); // fallthrough case '?': - eprintf ("Usage: cv[1248] [num]\n" - "Show offset if current value equals to the one specified\n" - " /v 18312 # serch for a known value\n" - " dc\n" - " cv4 18312 @@ hit*\n" - " dc\n"); + r_core_cmd_help_match (core, help_msg_c, "cv", true); break; } } @@ -1490,8 +1488,7 @@ static int cmd_cmp(void *data, const char *input) { default: sz = '4'; break; // default } } else if (sz == '?') { - eprintf ("Usage: cV[1248] [addr] @ addr2\n" - "compare n bytes from one address to current one and return in $? 0 or 1\n"); + r_core_cmd_help_match (core, help_msg_c, "cV", true); } sz -= '0'; if (sz > 0) { diff --git a/libr/core/cmd_debug.c b/libr/core/cmd_debug.c index 9c934981ec..64956ea18f 100644 --- a/libr/core/cmd_debug.c +++ b/libr/core/cmd_debug.c @@ -20,7 +20,7 @@ void cmd_anal_reg (RCore *core, const char *str); -static const char *help_msg_d[] = { +static RCoreHelpMessage help_msg_d = { "Usage:", "d", " # Debug commands", "d:", "[?] [cmd]", "run custom debug plugin command", "db", "[?]", "breakpoints commands", @@ -29,6 +29,7 @@ static const char *help_msg_d[] = { "dd", "[?][*+-tsdfrw]", "manage file descriptors for child process", "de", "[-sc] [perm] [rm] [e]", "debug with ESIL (see de?)", "dg", " ", "generate a core-file (WIP)", + "dh", " [plugin-name]", "select a new debug handler plugin (see dbh)", "dH", " [handler]", "transplant process to a new handler", "di", "[?]", "show debugger backend information (See dh)", "dk", "[?]", "list, send, get, set, signal handlers of child", @@ -48,10 +49,11 @@ static const char *help_msg_d[] = { "dWi", "", "identify window under cursor", #endif "dx", "[?][aers]", "execute code in the child process", + "date", " [-b]", "use -b for beat time", NULL }; -static const char *help_msg_db[] = { +static RCoreHelpMessage help_msg_db = { "Usage: db", "", " # Breakpoints commands", "db", "", "list breakpoints", "db*", "", "list breakpoints in r commands", @@ -99,7 +101,7 @@ static const char *help_msg_db[] = { NULL }; -static const char *help_msg_dbt[] = { +static RCoreHelpMessage help_msg_dbt = { "Usage: dbt", "", " # Backtrace commands", "dbt", "", "display backtrace based on dbg.btdepth and dbg.btalgo", "dbt*", "", "display backtrace in flags", @@ -113,19 +115,19 @@ static const char *help_msg_dbt[] = { NULL }; -static const char *help_msg_drr[] = { +static RCoreHelpMessage help_msg_drr = { "Usage: drr", ""," # Show references to registers (see pxr?)", "drr", "", "periscope register values", "drrj", "", "same, but output in JSON", NULL }; -static const char *help_msg_dbw[] = { +static RCoreHelpMessage help_msg_dbw = { "Usage: dbw", " "," # Add watchpoint", NULL }; -static const char *help_msg_dc[] = { +static RCoreHelpMessage help_msg_dc = { "Usage: dc", "", "Execution continuation commands", "dc", "", "continue execution of all children", "dc", " ", "continue execution of pid", @@ -149,7 +151,7 @@ static const char *help_msg_dc[] = { NULL }; -static const char *help_msg_dcs[] = { +static RCoreHelpMessage help_msg_dcs = { "Usage:", "dcs", " Continue until syscall", "dcs", "", "continue until next syscall", "dcs [str]", "", "continue until next call to the 'str' syscall", @@ -157,7 +159,7 @@ static const char *help_msg_dcs[] = { NULL }; -static const char *help_msg_dcu[] = { +static RCoreHelpMessage help_msg_dcu = { "Usage:", "dcu", " Continue until address", "dcu.", "", "alias for dcu $$ (continue until current address)", "dcu", " address", "continue until address", @@ -166,7 +168,7 @@ static const char *help_msg_dcu[] = { NULL }; -static const char *help_msg_dd[] = { +static RCoreHelpMessage help_msg_dd = { "Usage: dd", "", "Manage file descriptors for child process (* to show r2 commands)", "dd", "[*]", "list file descriptors", "dd", "[*] ", "open file as read-only (r--); addr = use as char* for path", @@ -181,25 +183,25 @@ static const char *help_msg_dd[] = { NULL }; -static const char *help_msg_de[] = { +static RCoreHelpMessage help_msg_de = { "Usage:", "de", "[-sc] [perm] [rm] [expr]", "de", "", "list esil watchpoints", "de-*", "", "delete all esil watchpoints", - "de", " [perm] [rm] [addr|reg|from..to]", "stop on condition", + "de ", "[perm] [rm] [addr|reg|from..to]", "stop on condition", "dec", "", "continue execution until matching expression", "des", "[?] [N]", "step-in N instructions with esildebug", "desu", " [addr]", "esildebug until specific address", NULL }; -static const char *help_msg_des[] = { +static RCoreHelpMessage help_msg_des = { "Usage:", "des", "[u] [arg]", "des", " [N]", "step-in N instructions with esildebug", "desu", " [addr]", "esildebug until specific address", NULL }; -static const char *help_msg_di[] = { +static RCoreHelpMessage help_msg_di = { "Usage: di", "", "Debugger target information", "di", "", "show debugger target information", "di*", "", "same as above, but in r2 commands", @@ -210,7 +212,7 @@ static const char *help_msg_di[] = { NULL }; -static const char *help_msg_dk[] = { +static RCoreHelpMessage help_msg_dk = { "Usage: dk", "", "Signal commands", "dk", "", "list all signal handlers of child process", "dk", " ", "send KILL signal to child", @@ -222,7 +224,7 @@ static const char *help_msg_dk[] = { NULL }; -static const char *help_msg_dko[] = { +static RCoreHelpMessage help_msg_dko = { "Usage:", "dko", " # Signal handling commands", "dko", "", "list existing signal handling", "dko", " [signal]", "clear handling for a signal", @@ -230,7 +232,7 @@ static const char *help_msg_dko[] = { NULL }; -static const char *help_msg_dm[] = { +static RCoreHelpMessage help_msg_dm = { "Usage:", "dm", " # Memory maps commands", "dm", "", "list memory maps of target process", "dm", " address size", "allocate bytes at
(anywhere if address is -1) in child process", @@ -238,7 +240,7 @@ static const char *help_msg_dm[] = { "dm.", "", "show map name of current address", "dm*", "", "list memmaps in radare commands", "dm-", " address", "deallocate memory map of
", - "dmd", "[a] [file]", "dump current (all) debug map region to a file (from-to.dmp) (see Sd)", + "dmd", "[aw] [file]", "dump current (all or writable) debug map region to a file (from-to.dmp) (see Sd)", "dmh", "[?]", "show map of heap", "dmi", " [addr|libname] [symname]", "list symbols of target lib", "dmi*", " [addr|libname] [symname]", "list symbols of target lib in radare commands", @@ -259,7 +261,7 @@ static const char *help_msg_dm[] = { NULL }; -static const char *help_msg_dmi[] = { +static RCoreHelpMessage help_msg_dmi = { "Usage: dmi", "", " # List/load Symbols", "dmi", "[j|q|*] [libname] [symname]", "list symbols of target lib", "dmia", "[j|q|*] [libname]", "list all info of target lib", @@ -269,7 +271,7 @@ static const char *help_msg_dmi[] = { NULL }; -static const char *help_msg_dmm[] = { +static RCoreHelpMessage help_msg_dmm = { "Usage:", "dmm", " # Module memory maps commands", "dmm", "", "list modules of target process", "dmm*", "", "list modules of target process (r2 commands)", @@ -278,20 +280,37 @@ static const char *help_msg_dmm[] = { NULL }; -static const char *help_msg_dxe[] = { +static RCoreHelpMessage help_msg_dms = { + "Usage:", "dms", " # Memory map snapshots", + "dms", "", "list memory snapshots", + "dms", " addr", "take snapshot with given id of map at address", + "dms", "-id", "delete memory snapshot", + "dms.", "", "take snapshot of current map", + "dms-", "", "revert to previous snapshot", + "dms+", "", "re-apply snapshot", + "dms*", "", "list snapshots in r2 commands", + "dmsj", "", "list snapshots in JSON", + "dmsC", " id comment", "add comment for given snapshot", + "dmsd", " id", "hexdiff given snapshot. See `ccc`.", + "dmsw", "", "snapshot of the writable maps", + "dmsa", "", "full snapshot of all `dm` maps", + NULL +}; + +static RCoreHelpMessage help_msg_dxe = { "Usage:", "dxe", " egg-program # see ragg2 and the 'g' command for more details", "dxe", " sym.imp.puts(\"foo\")", "call puts with a string argument", NULL }; -static const char *help_msg_dmp[] = { +static RCoreHelpMessage help_msg_dmp = { "Usage:", "dmp", " Change page permissions", "dmp", " [addr] [size] [perms]", "change permissions", "dmp", " [perms]", "change dbg.map permissions", NULL }; -static const char *help_msg_do[] = { +static RCoreHelpMessage help_msg_do = { "Usage:", "do", " # Debug (re)open commands", "do", "", "open process (reload, alias for 'oo')", "dor", " [rarun2]", "comma separated list of k=v rarun2 profile options (e dbg.profile)", @@ -303,7 +322,7 @@ static const char *help_msg_do[] = { NULL }; -static const char *help_msg_dp[] = { +static RCoreHelpMessage help_msg_dp = { "Usage:", "dp", " # Process commands", "dp", "", "list current pid and children", "dp", " ", "list children of pid", @@ -329,7 +348,7 @@ static const char *help_msg_dp[] = { NULL }; -static const char *help_msg_dr[] = { +static RCoreHelpMessage help_msg_dr = { "Usage: dr", "", "Registers commands", "dr", "", "show 'gpr' registers", "dr", " =", "set register value", @@ -363,7 +382,7 @@ static const char *help_msg_dr[] = { NULL }; -static const char *help_msg_drp[] = { +static RCoreHelpMessage help_msg_drp = { "Usage:", "drp", " # Register profile commands", "drp", "", "show the current register profile", "drp", " [regprofile-file]", "set the current register profile", @@ -374,10 +393,12 @@ static const char *help_msg_drp[] = { "drp.", "", "show the current fake size", "drpj", "", "show the current register profile (JSON)", "drps", " [new fake size]", "set the fake size", + "drpg", "", "show register profile comments", + "NOTE:", "", "this help will show arp if you run drp? when cfg.debug=0", NULL }; -static const char *help_msg_drs[] = { +static RCoreHelpMessage help_msg_drs = { "Usage:", "drs", "register states commands", "drs", "", "list register stack", "drs", "+", "push register state", @@ -385,7 +406,7 @@ static const char *help_msg_drs[] = { NULL }; -static const char *help_msg_drt[] = { +static RCoreHelpMessage help_msg_drt = { "Usage:", "drt", " [type] [size] # debug register types", "drt", "", "list all available register types", "drt", " [size]", "show all regs in the profile of size", @@ -399,7 +420,7 @@ static const char *help_msg_drt[] = { NULL }; -static const char *help_msg_drx[] = { +static RCoreHelpMessage help_msg_drx = { "Usage: drx", "", "Hardware breakpoints commands", "drx", "", "list all (x86?) hardware breakpoints", "drx", "
", "modify hardware breakpoint", @@ -407,7 +428,7 @@ static const char *help_msg_drx[] = { NULL }; -static const char *help_msg_drv[] = { +static RCoreHelpMessage help_msg_drv = { "Usage: drv", " [reg] [idx] [wordsize] [= value]", "Show multimedia packed registers", "drv", "", "show XMM registers", "drv", " xmm0", "show all packings of xmm0", @@ -429,7 +450,7 @@ static const char *help_msg_drv[] = { NULL }; -static const char *help_msg_ds[] = { +static RCoreHelpMessage help_msg_ds = { "Usage: ds", "", "Step commands", "ds", "", "step one instruction", "ds", " ", "step instructions", @@ -445,9 +466,9 @@ static const char *help_msg_ds[] = { NULL }; -static const char *help_msg_dsu[] = { +static RCoreHelpMessage help_msg_dsu = { "Usage: dsu", "", "Step until commands", - "dsu", "
", "step until
", + "dsu ", "
", "step until
", "dsui", " ", "step until an instruction disasm matches", "dsuir", " ", "like dsui, but using a regexp", "dsuo", " [ ...]", "step until an instr matches one of the s.", @@ -456,7 +477,7 @@ static const char *help_msg_dsu[] = { NULL }; -static const char *help_msg_dt[] = { +static RCoreHelpMessage help_msg_dt = { "Usage: dt", "", "Trace commands", "dt", "", "list all traces ", "dt", " [addr]", "show trace info at address", @@ -466,7 +487,7 @@ static const char *help_msg_dt[] = { "dt-", "", "reset traces (instruction/calls)", "dt=", "", "show ascii-art color bars with the debug trace ranges", "dta", " 0x804020 ...", "only trace given addresses", - "dtc[?][addr]|([from] [to] [addr])", "", "trace call/ret", + "dtc", "[?][addr]|([from] [to] [addr])", "trace call/ret", "dtd", "[qi] [nth-start]", "list all traced disassembled (quiet, instructions)", "dte", "[?]", "show esil trace logs", "dtg", "", "graph call/ret trace", @@ -477,8 +498,8 @@ static const char *help_msg_dt[] = { NULL }; -static const char *help_msg_dte[] = { - "Usage:", "dte", " Show esil trace logs", +static RCoreHelpMessage help_msg_dte = { + "Usage: dte", "", "Show esil trace logs", "dte", "", "esil trace log for a single instruction", "dte", " [idx]", "show commands for that index log", "dte", "-*", "delete all esil traces", @@ -487,8 +508,8 @@ static const char *help_msg_dte[] = { NULL }; -static const char *help_msg_dts[] = { - "Usage:", "dts[*]", "", +static RCoreHelpMessage help_msg_dts = { + "Usage:", "dts[*]", "Trace sessions", "dts+", "", "start trace session", "dts-", "", "stop trace session", "dtst", " [dir] ", "save trace sessions to disk", @@ -497,7 +518,7 @@ static const char *help_msg_dts[] = { NULL }; -static const char *help_msg_dx[] = { +static RCoreHelpMessage help_msg_dx = { "Usage: dx", "[aers]", " Debug execution commands", "dx", " ", "execute opcodes", "dxa", " ", "assemble code and execute", @@ -512,8 +533,8 @@ static const char *help_msg_dx[] = { NULL }; -static const char *help_msg_dL[] = { - "Usage: dL", "", " # List or set debugger handler", +static RCoreHelpMessage help_msg_dL = { + "Usage: dL", "", " List or set debugger handler", "dL", "", "list debugger handlers", "dLq", "", "list debugger handlers in quiet mode", "dLj", "", "list debugger handlers in json mode", @@ -858,7 +879,7 @@ static bool step_until_optype(RCore *core, const char *_optypes) { RList *optypes_list = NULL; RListIter *iter; char *optype = NULL; - char *optypes = strdup (r_str_trim_head_ro ((char *) _optypes)); + char *optypes = strdup (r_str_trim_head_ro (_optypes)); RAnalOp op; ut8 buf[32]; ut64 pc; @@ -872,7 +893,7 @@ static bool step_until_optype(RCore *core, const char *_optypes) { st64 maxsteps = r_config_get_i (core->config, "esil.maxsteps"); ut64 countsteps = 0; if (R_STR_ISEMPTY (optypes)) { - R_LOG_ERROR ("Missing optypes. Usage example: 'dsuo ucall ujmp'"); + r_core_cmd_help_match (core, help_msg_dsu, "dsuo", true); res = false; goto end; } @@ -1520,24 +1541,6 @@ static int __r_debug_snap_diff(RCore *core, int idx) { return 0; } -const char* help_msg_dms[] = { - "Usage:", "dms", " # Memory map snapshots", - "dms", "", "list memory snapshots", - "dms", " addr", "take snapshot with given id of map at address", - "dms", "-id", "delete memory snapshot", - "dms.", "", "take snapshot of current map", - "dms-", "", "revert to previous snapshot", - "dms+", "", "re-apply snapshot", - "dms*", "", "list snapshots in r2 commands", - "dmsj", "", "list snapshots in JSON", - "dmsC", " id comment", "add comment for given snapshot", - "dmsd", " id", "hexdiff given snapshot. See `ccc`.", - "dmsw", "", "snapshot of the writable maps", - "dmsa", "", "full snapshot of all `dm` maps", - // TODO: dmsj - for json - NULL -}; - static int cmd_debug_map_snapshot(RCore *core, const char *input) { switch (*input) { case '?': @@ -1585,7 +1588,7 @@ static int cmd_debug_map(RCore *core, const char *input) { switch (input[0]) { case 's': // "dms" if (strchr (input, '?')) { - r_core_cmd_help_match_spec (core, help_msg_dm, "dms", input[0], false); + r_core_cmd_help_match (core, help_msg_dm, "dms", false); } cmd_debug_map_snapshot (core, input+1); break; @@ -1653,13 +1656,13 @@ static int cmd_debug_map(RCore *core, const char *input) { case 0: return dump_maps (core, -1, NULL); case '?': default: - eprintf ("Usage: dmd[aw] - dump (all-or-writable) debug maps\n"); + r_core_cmd_help_match (core, help_msg_dm, "dmd", true); break; } break; case 'l': // "dml" if (input[1] != ' ') { - eprintf ("Usage: dml [file]\n"); + r_core_cmd_help_match (core, help_msg_dm, "dml", true); return false; } r_debug_map_sync (core->dbg); // update process memory maps @@ -1669,13 +1672,14 @@ static int cmd_debug_map(RCore *core, const char *input) { char *buf = r_file_slurp (input + 2, &sz); //TODO: use mmap here. we need a portable implementation if (!buf) { - R_LOG_ERROR ("Cannot allocate 0x%08"PFMT64x" byte(s)", map->size); + R_LOG_ERROR ("Cannot allocate 0x%08" PFMT64x " byte(s)", map->size); return false; } r_io_write_at (core->io, map->addr, (const ut8*)buf, sz); if (sz != map->size) { - R_LOG_INFO ("File size differs from region size (%"PFMT64u" vs %"PFMT64d")", - (ut64)sz, map->size); + R_LOG_INFO ("File size differs from region size " + "(%" PFMT64u " vs %" PFMT64d ")", + (ut64)sz, map->size); } R_LOG_INFO ("Loaded %"PFMT64u" byte(s) into the map region at 0x%08"PFMT64x, (ut64)sz, map->addr); free (buf); @@ -1919,14 +1923,14 @@ static int cmd_debug_map(RCore *core, const char *input) { size = r_num_math (core->num, p); r_debug_map_alloc (core->dbg, addr, size, false); } else { - eprintf ("Usage: dm addr size\n"); + r_core_cmd_help_match (core, help_msg_dm, "dm", true); return false; } } break; case '-': // "dm-" if (input[1] != ' ') { - eprintf ("Usage: dm- [addr]\n"); + r_core_cmd_help_match (core, help_msg_dm, "dm-", true); break; } addr = r_num_math (core->num, input + 2); @@ -1949,7 +1953,7 @@ static int cmd_debug_map(RCore *core, const char *input) { size = r_num_math (core->num, p); r_debug_map_alloc (core->dbg, addr, size, true); } else { - eprintf ("Usage: dmL addr size\n"); + r_core_cmd_help_match (core, help_msg_dm, "dmL", true); return false; } } @@ -2170,6 +2174,10 @@ static void cmd_drpi(RCore *core) { } } +/* XXX "from" is irrelevant, control flow into here is determined by cfg.debug + * right now, i.e.: if cfg.debug == 1, arp -> drp, so from == 'd' despite + * entering arp, so you still get the wrong help for your input. + */ static void cmd_reg_profile(RCore *core, char from, const char *str) { // "arp" and "drp" const char *ptr; RReg *r = r_config_get_b (core->config, "cfg.debug")? core->dbg->reg: core->anal->reg; @@ -2212,7 +2220,7 @@ static void cmd_reg_profile(RCore *core, char from, const char *str) { // "arp" R_LOG_WARN ("Cannot parse gdb profile"); } } else { - eprintf ("Usage: arpg [gdb-reg-profile]\n"); + r_core_cmd_help_match (core, help_msg_drp, "drpg", true); } break; case ' ': // "drp " "arp " @@ -2303,21 +2311,38 @@ static void cmd_reg_profile(RCore *core, char from, const char *str) { // "arp" } break; case '?': // "drp?" "arp?" - default: - { - const char *from_a[] = { "arp", "arpi", "arpg", "arp.", "arpj", "arps" }; - // TODO #7967 help refactor - const char **help_msg = help_msg_drp; - if (from == 'a') { - help_msg[1] = help_msg[3] = help_msg[6] = help_msg[9] = from_a[0]; - help_msg[12] = from_a[1]; - help_msg[15] = from_a[2]; - help_msg[18] = from_a[3]; - help_msg[21] = from_a[4]; - } - r_core_cmd_help (core, help_msg); - break; + default: { + // i hate this so much + int i; + int num_strings = 0; + char **help_msg; + const char * const *p = help_msg_drp; + while (*p) { + num_strings += 3; + p = &p[3]; } + + help_msg = R_NEWS (char *, num_strings+1); + help_msg[num_strings] = NULL; + for (i = 0; i < num_strings; i++) { + help_msg[i] = strdup (help_msg_drp[i]); + } + + // see function comment + // eprintf ("%c\n", from); + if (from == 'a') { + for (i = 0; !r_str_startswith (help_msg[i], "NOTE:"); i++) { + help_msg[i] = r_str_replace (help_msg[i], "drp", "arp", true); + } + } + r_core_cmd_help (core, (const char * const *)help_msg); + + for (i = 0; i < num_strings; i++) { + free (help_msg[i]); + } + free (help_msg); + break; + } } } @@ -2501,7 +2526,6 @@ static void cmd_debug_reg(RCore *core, const char *str) { R_LOG_ERROR ("Register %s not found", name); } } else { - eprintf ("Usage: drC [register]\n"); } } break; @@ -2717,32 +2741,33 @@ static void cmd_debug_reg(RCore *core, const char *str) { r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, true); break; case ' ': { - char *s = strdup (str + 2); - char sl, n, perm; - int len; - ut64 off; + char *s = strdup (str + 2); + char sl, n, perm; + int len; + ut64 off; - sl = r_str_word_set0 (s); - if (sl == 4) { + sl = r_str_word_set0 (s); + if (sl == 4) { #define arg(x) r_str_word_get0(s,x) - n = (char)r_num_math (core->num, arg(0)); - off = r_num_math (core->num, arg(1)); - len = (int)r_num_math (core->num, arg(2)); - perm = (char)r_str_rwx (arg (3)); - if (len == -1) { - r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, false); - r_debug_drx_set (core->dbg, n, 0, 0, 0, 0); - r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, true); - } else { - r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, false); - r_debug_drx_set (core->dbg, n, off, len, perm, 0); - r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, true); - } - } else { - eprintf ("Usage: drx n [address] [length] [perm]\n"); - } - free (s); - } break; + n = (char)r_num_math (core->num, arg(0)); + off = r_num_math (core->num, arg(1)); + len = (int)r_num_math (core->num, arg(2)); + perm = (char)r_str_rwx (arg (3)); + if (len == -1) { + r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, false); + r_debug_drx_set (core->dbg, n, 0, 0, 0, 0); + r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, true); + } else { + r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, false); + r_debug_drx_set (core->dbg, n, off, len, perm, 0); + r_debug_reg_sync (core->dbg, R_REG_TYPE_DRX, true); + } + } else { + r_core_cmd_help_match (core, help_msg_dr, "drx", true); + } + free (s); + } + break; case '?': default: r_core_cmd_help (core, help_msg_drx); @@ -2914,7 +2939,7 @@ static void cmd_debug_reg(RCore *core, const char *str) { case 'f': // "drf" //r_debug_drx_list (core->dbg); if (str[1] == '?') { - eprintf ("usage: drf [fpureg] [= value]\n"); + r_core_cmd_help_match (core, help_msg_dr, "drf", true); } else if (str[1] == ' ') { char *p, *name = strdup (str + 2); char *eq = strchr (name, '='); @@ -2956,6 +2981,8 @@ static void cmd_debug_reg(RCore *core, const char *str) { } break; case 'p': // "drp" + // this is only ever reached if cdg.debug=1 + // ("from" == d) == cfg.debug cmd_reg_profile (core, 'd', str); break; case 't': { // "drt" @@ -3437,10 +3464,10 @@ static void core_cmd_dbi(RCore *core, const char *input, const ut64 idx) { R_LOG_ERROR ("Cannot set command"); } } else { - eprintf ("Usage: dbic # cmd\n"); + r_core_cmd_help_match (core, help_msg_db, "dbic", true); } } else { - eprintf ("Usage: dbic # cmd\n"); + r_core_cmd_help_match (core, help_msg_db, "dbic", true); } break; case 'e': // "dbie" @@ -3794,7 +3821,7 @@ static void r_core_cmd_bp(RCore *core, const char *input) { st64 delta = 0; char *sdelta = (char *)r_str_lchr (module, ' '); if (!sdelta) { - eprintf ("Usage: dbm [modulename] [delta]\n"); + r_core_cmd_help_match (core, help_msg_db, "dbm", true); free (module); break; } @@ -3941,7 +3968,7 @@ static void r_core_cmd_bp(RCore *core, const char *input) { break; case '?': default: - eprintf ("Usage: dh [plugin-name] # select a debug handler plugin\n"); + r_core_cmd_help_match (core, help_msg_d, "dh", true); break; } break; @@ -4195,7 +4222,6 @@ static void r_core_debug_esil(RCore *core, const char *input) { { char *line = strdup (input + 1); char *p, *q; - int done = 0; int perm = 0, dev = 0; p = strchr (line, ' '); if (p) { @@ -4208,15 +4234,11 @@ static void r_core_debug_esil(RCore *core, const char *input) { *q++ = 0; dev = p[0]; r_debug_esil_watch (core->dbg, perm, dev, q); - done = 1; + } else { + r_core_cmd_help_match (core, help_msg_de, "de ", true); } - } - if (!done) { - const char *help_de_msg[] = { - "Usage:", "de", " [perm] [reg|mem] [expr]", - NULL - }; - r_core_cmd_help (core, help_de_msg); + } else { + r_core_cmd_help_match (core, help_msg_de, "de ", true); } free (line); } @@ -4563,7 +4585,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { break; case 'b': // "dcb" if (input[2] == '?') { - eprintf ("Usage: dcb : continue back until breakpoint\n"); + r_core_cmd_help_match (core, help_msg_dc, "dcb", true); } else { if (!core->dbg->session) { R_LOG_ERROR ("Session has not started"); @@ -4575,7 +4597,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { #if R2__WINDOWS__ case 'e': // "dce" if (input[2] == '?') { - eprintf ("Usage: dce: pass windows exceptions\n"); + r_core_cmd_help_match (core, help_msg_dc, "dce", true); } else { r_reg_arena_swap (core->dbg->reg, true); r_debug_continue_pass_exception (core->dbg); @@ -4584,7 +4606,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { #endif case 'f': // "dcf" if (input[2] == '?') { - eprintf ("Usage: dcf: same as dcs vfork fork clone\n"); + r_core_cmd_help_match (core, help_msg_dc, "dcf", true); } else { // we should stop in fork and vfork syscalls //TODO: multiple syscalls not handled yet @@ -4593,7 +4615,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { break; case 'c': // "dcc" if (input[2] == '?') { - eprintf ("Usage: dcc: step into until CALL instruction is found\n"); + r_core_cmd_help_match (core, help_msg_dc, "dcc", true); } else { r_reg_arena_swap (core->dbg->reg, true); if (input[2] == 'u') { @@ -4605,7 +4627,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { break; case 'r': // "dcr" if (input[2] == '?') { - eprintf ("Usage: dcr: step over until ret instruction is found\n"); + r_core_cmd_help_match (core, help_msg_dc, "dcr", true); } else { r_reg_arena_swap (core->dbg->reg, true); r_debug_continue_until_optype (core->dbg, R_ANAL_OP_TYPE_RET, 1); @@ -4613,7 +4635,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { break; case 'k': if (input[2] == '?') { - eprintf ("Usage: dck: continue sending signal to process\n"); + r_core_cmd_help_match (core, help_msg_dc, "dck", true); } else { // select pid and r_debug_continue_kill (core->dbg, r_reg_arena_swap (core->dbg->reg, true); @@ -4652,7 +4674,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { break; case 'p': // "dcp" if (input[2] == '?') { - eprintf ("Usage: dcp: continue until program code (mapped io section)\n"); + r_core_cmd_help_match (core, help_msg_dc, "dcp", true); } else { // XXX: this is very slow RIOMap *s; @@ -4696,7 +4718,7 @@ static int cmd_debug_continue(RCore *core, const char *input) { break; case 't': if (input[2] == '?') { - eprintf ("Usage: dbt: show backtrace (see dbt.bt* variables)\n"); + r_core_cmd_help_match (core, help_msg_dc, "dct", true); } else { cmd_debug_backtrace (core, input + 2); } @@ -4771,12 +4793,19 @@ static int cmd_debug_step(RCore *core, const char *input) { step_until_eof (core); break; case 'u': // "dsu" + if (input[3] == '?') { + r_core_cmd_help_match_spec (core, help_msg_dsu, "dsu", input[2], true); + return 0; + } switch (input[2]) { case 'f': // dsuf step_until_flag (core, input + 3); break; case 'i': // dsui if (input[3] == 'r') { + if (input[4] == '?') { + r_core_cmd_help_match (core, help_msg_dsu, "dsuir", true); + } step_until_inst (core, input + 4, true); } else { step_until_inst (core, input + 3, false); @@ -5277,7 +5306,7 @@ static int cmd_debug(void *data, const char *input) { } if (!strncmp (input, "ate", 3)) { // "date" -- same as pt. if (strstr (input, "-h") || strstr (input, "?")) { - eprintf ("Usage: date [-b] # use -b for beat time\n"); + r_core_cmd_help_match (core, help_msg_d, "date", true); return 0; } bool use_beat = strstr (input, "-b"); @@ -5326,7 +5355,7 @@ static int cmd_debug(void *data, const char *input) { break; case 'c': // "dtc" if (input[2] == '?') { - r_cons_println ("Usage: dtc [addr] ([from] [to] [addr]) - trace calls in debugger"); + r_core_cmd_help_match (core, help_msg_dt, "dtc", true); } else { debug_trace_calls (core, input + 2); } @@ -5466,7 +5495,7 @@ static int cmd_debug(void *data, const char *input) { r_cons_println (s); free (s); } else { - eprintf ("Usage: dtek [query]\n"); + r_core_cmd_help_match (core, help_msg_dte, "dtek", true); } break; default: @@ -5640,7 +5669,7 @@ static int cmd_debug(void *data, const char *input) { break; case 'f': // "dif" "diff" if (input[1] == '?') { - eprintf ("Usage: dif $a $b # diff two alias files\n"); + r_core_cmd_help_match (core, help_msg_di, "dif", true); } else { char *arg = strchr (input, ' '); if (arg) { @@ -5666,7 +5695,7 @@ static int cmd_debug(void *data, const char *input) { } free (arg); } else { - eprintf ("Usage: dif $a $b # diff two alias files\n"); + r_core_cmd_help_match (core, help_msg_di, "dif", true); } } break; diff --git a/libr/core/cmd_egg.c b/libr/core/cmd_egg.c index fb8f35b93f..b69a71790a 100644 --- a/libr/core/cmd_egg.c +++ b/libr/core/cmd_egg.c @@ -2,7 +2,7 @@ #include -static const char *help_msg_g[] = { +static RCoreHelpMessage help_msg_g = { "Usage:", "g[wcilper] [arg]", "Go compile shellcodes using asm.arch/bits/os", "g", " ", "compile the shellcode", "g", " foo.r", "compile r_egg source file", diff --git a/libr/core/cmd_eval.c b/libr/core/cmd_eval.c index 5da13c6d92..f1ba6eba92 100644 --- a/libr/core/cmd_eval.c +++ b/libr/core/cmd_eval.c @@ -2,7 +2,7 @@ #include -static RCoreHelpMessage help_message_ecH = { +static RCoreHelpMessage help_msg_ecH = { "Usage ecH[iw-?]","","", "ecHi","[color]","highlight current instruction with 'color' background", "ecHw","[word] [color]","highlight 'word ' in current instruction with 'color' background", @@ -31,6 +31,7 @@ static RCoreHelpMessage help_msg_e = { "ec", "[?] [k] [color]", "set color for given key (prompt, offset, ...)", "ee", " [var]", "open cfg.editor to change the value of var", "ed", "", "open editor to change the ~/.radare2rc", + "ed-", "", "delete ~/.radare2c", "ej", "", "list config vars in JSON", "eJ", "", "list config vars in verbose JSON", "en", "", "list environment vars", @@ -439,7 +440,7 @@ static int cmd_eval(void *data, const char *input) { break; case 'n': // "en" "env" if (strchr (input, '?')) { - r_core_cmd_help_match_spec (core, help_msg_e, "en", 0, false); + r_core_cmd_help_match (core, help_msg_e, "en", false); break; } else if (!strchr (input, '=')) { const char *var = strchr (input, ' '); @@ -590,7 +591,7 @@ static int cmd_eval(void *data, const char *input) { char** argv = r_str_argv (r_str_trim_head_ro (input + delta), &argc); switch (input[2]) { case '?': - r_core_cmd_help (core, help_message_ecH); + r_core_cmd_help (core, help_msg_ecH); r_str_argv_free (argv); return false; case '-': // ecH- @@ -633,7 +634,7 @@ static int cmd_eval(void *data, const char *input) { break; case 'w': // "ecHw" if (!argc) { - eprintf ("Usage: ecHw word [color]\n"); + r_core_cmd_help_match (core, help_msg_ecH, "ecHw", true); r_str_argv_free (argv); return true; } @@ -689,11 +690,8 @@ static int cmd_eval(void *data, const char *input) { break; case 'd': // "ed" if (input[1] == '?') { - eprintf ("Usage: ed[-][?] - edit ~/.radare2rc with cfg.editor\n"); - eprintf ("NOTE: ~ is HOME and this can be changed with %%HOME=/tmp\n"); - eprintf (" ed : ${cfg.editor} ~/.radare2rc\n"); - eprintf (" ed- : rm ~/.radare2rc\n"); - } else if (input[1] == '-') { + r_core_cmd_help_match (core, help_msg_e, "ed", false); + } else if (input[1] == '-') { // "ed-" char *file = r_file_home (".radare2rc"); if (file) { r_file_rm (file); diff --git a/libr/core/cmd_flag.c b/libr/core/cmd_flag.c index d87132b2c7..91f6b81d36 100644 --- a/libr/core/cmd_flag.c +++ b/libr/core/cmd_flag.c @@ -3,13 +3,13 @@ #include #include "r_core.h" -static const char *help_msg_fR[] = { +static RCoreHelpMessage help_msg_fR = { "Usage: fR"," [from] [to] ([mask])", " # Relocate flags matching a mask asuming old and new base addresses", "fR", " entry0 `dm~:1[1]`", "rebase entrypoint", NULL }; -static const char *help_msg_fV[] = { +static RCoreHelpMessage help_msg_fV = { "Usage: fV","[*-] [nkey] [offset", " # dump/restore visual marks (mK/'K)", "fV", " a 33", "set visual mark 'a' to the offset 33", "fV", "-", "delete all visual marks", @@ -18,7 +18,7 @@ static const char *help_msg_fV[] = { NULL }; -static const char *help_msg_f[] = { +static RCoreHelpMessage help_msg_f = { "Usage: f","[?] [flagname]", " # Manage offset-name flags", "f","","list flags (will only list flags from selected flagspaces)", "f?","flagname","check if flag exists or not, See ?? and ?!", @@ -60,7 +60,7 @@ static const char *help_msg_f[] = { "fO", " [glob]", "flag as ordinals (sym.* func.* method.*)", //" fc [name] [cmt] ; set execution command for a specific flag" "fr"," [[old]] [new]","rename flag (if no new flag current seek one is used)", - "fR","[?] [f] [t] [m]","relocate all flags matching f&~m 'f'rom, 't'o, 'm'ask", + "fR","[?] [from] [to] [mask]","relocate all flags matching from&~m", "fs","[?]+-*","manage flagspaces", "ft","[?]*","flag tags, useful to find all flags matching some words", "fV","[*-] [nkey] [offset]","dump/restore visual marks (mK/'K)", @@ -70,7 +70,7 @@ static const char *help_msg_f[] = { NULL }; -static const char *help_msg_fc[] = { +static RCoreHelpMessage help_msg_fc = { "Usage: fc", " [color]", " # List colors with 'ecs'", "fc", "", "same as fc.", "fc", " color", "set color to all flags in current offset", @@ -84,13 +84,13 @@ static const char *help_msg_fc[] = { NULL }; -static const char *help_msg_feq[] = { +static RCoreHelpMessage help_msg_feq = { "Usage: f="," [glob]", " # Grep flag names using glob expression", "f=", " str*", "filter all flags starting with str", NULL }; -static const char *help_msg_ft[] = { +static RCoreHelpMessage help_msg_ft = { "Usage: ft","[?ln] ([k] [v ...])", "# Grep flag names using glob expression", "ft"," tag strcpy strlen ...","set words for the 'string' tag", "ft"," tag","get offsets of all matching flags", @@ -102,7 +102,7 @@ static const char *help_msg_ft[] = { NULL }; -static const char *help_msg_fd[] = { +static RCoreHelpMessage help_msg_fd = { "Usage: fd[d]", " [offset|flag|expression]", " # Describe flags", "fd", " $$" , "# describe flag + delta for given offset", "fd.", " $$", "# check flags in current address (no delta)", @@ -111,7 +111,7 @@ static const char *help_msg_fd[] = { NULL }; -static const char *help_msg_fs[] = { +static RCoreHelpMessage help_msg_fs = { "Usage: fs","[*] [+-][flagspace|addr]", " # Manage flagspaces", "fs","","display flagspaces", "fs*","","display flagspaces as r2 commands", @@ -132,14 +132,14 @@ static const char *help_msg_fs[] = { NULL }; -static const char *help_msg_fz[] = { +static RCoreHelpMessage help_msg_fz = { "Usage: f", "[?|-name| name] [@addr]", " # Manage flagzones", - " fz", " math", "add new flagzone named 'math'", - " fz-", "math", "remove the math flagzone", - " fz-", "*", "remove all flagzones", - " fz.", "", "show around flagzone context", - " fz:", "", "show what's in scr.flagzone for visual", - " fz*", "", "dump into r2 commands, for projects", + "fz", " math", "add new flagzone named 'math'", + "fz-", "math", "remove the math flagzone", + "fz-", "*", "remove all flagzones", + "fz.", "", "show around flagzone context", + "fz:", "", "show what's in scr.flagzone for visual", + "fz*", "", "dump into r2 commands, for projects", NULL }; @@ -879,7 +879,7 @@ rep: eprintf ("Cannot find flag '%s'\n", name); } } else { - eprintf ("Usage: fa flagname flagalias\n"); + r_core_cmd_help_match (core, help_msg_f, "fa", true); } break; case 'V': // visual marks @@ -911,7 +911,7 @@ rep: case 'R': // "fR" switch (*str) { case '\0': - eprintf ("Usage: fR [from] [to] ([mask])\n"); + r_core_cmd_help_match (core, help_msg_f, "fR", true); eprintf ("Example to relocate PIE flags on debugger:\n" " > fR entry0 `dm~:1[1]`\n"); break; @@ -935,7 +935,7 @@ rep: ret = r_flag_relocate (core->flags, from, mask, to); eprintf ("Relocated %d flags\n", ret); } else { - eprintf ("Usage: fR [from] [to] ([mask])\n"); + r_core_cmd_help_match (core, help_msg_f, "fR", true); eprintf ("Example to relocate PIE flags on debugger:\n" " > fR entry0 `dm~:1[1]`\n"); } @@ -964,7 +964,7 @@ rep: core->flags->base); break; default: - eprintf ("Usage: fb [addr] [[flags*]]\n"); + r_core_cmd_help_match (core, help_msg_f, "fb", true); break; } break; @@ -1126,10 +1126,14 @@ rep: break; case 'l': // "fl" if (input[1] == '?') { // "fl?" - eprintf ("Usage: fl[a] [flagname] [flagsize]\n"); + r_core_cmd_help_match (core, help_msg_f, "fl", false); } else if (input[1] == 'a') { // "fla" // TODO: we can optimize this if core->flags->flags is sorted by flagitem->offset - char *glob = strchr (input, ' '); + char *glob; + if (input[2] == '?') { // "fla?" + r_core_cmd_help_match (core, help_msg_f, "fla", true); + } + glob = strchr (input, ' '); if (glob) { glob++; } @@ -1218,7 +1222,7 @@ rep: r_flag_space_rename (core->flags, NULL, newname); free (newname); } else { - eprintf ("Usage: fsr [newname]\n"); + r_core_cmd_help_match (core, help_msg_fs, "fsr", true); } break; case 's': // "fss" @@ -1401,7 +1405,7 @@ rep: } free (p); } else { - eprintf ("Usage: fC [name] [comment]\n"); + r_core_cmd_help_match (core, help_msg_f, "fC", true); } break; case 'o': // "fo" diff --git a/libr/core/cmd_hash.c b/libr/core/cmd_hash.c index 7291e518d3..95e89ab812 100644 --- a/libr/core/cmd_hash.c +++ b/libr/core/cmd_hash.c @@ -2,7 +2,7 @@ #include -const char *help_msg_hash[] = { +static RCoreHelpMessage help_msg_hash = { "Usage:", "#!", "[] [num, input + 3) == -1) { - eprintf ("Usage: ?btw num|(expr) num|(expr) num|(expr)\n"); + r_core_cmd_help_match (core, help_msg_question, "?btw", true); } } else { n = r_num_math (core->num, input + 1); @@ -731,11 +732,11 @@ static int cmd_help(void *data, const char *input) { r_str_bits (out, (const ut8*)&n, sizeof (n) * 8, q + 1); r_cons_println (out); } else { - eprintf ("Usage: \"?b value bitstring\"\n"); + r_core_cmd_help_match (core, help_msg_question, "?f", true); } free (p); } else { - R_LOG_ERROR ("expected whitespace after '?f'"); + r_core_cmd_help_match (core, help_msg_question, "?f", true); } break; case 'o': // "?o" @@ -879,8 +880,7 @@ static int cmd_help(void *data, const char *input) { R_LOG_ERROR ("Division by Zero"); } if (input[1] == '?') { - r_cons_printf ("Usage: ?q [num] # Update $? without printing anything\n" - "|?q 123; ?? x # hexdump if 123 != 0"); + r_core_cmd_help_match (core, help_msg_question, "?q", true); } else { const char *space = strchr (input, ' '); if (space) { @@ -912,14 +912,7 @@ static int cmd_help(void *data, const char *input) { } switch (input[1]) { case '?': - r_cons_printf ("Usage: ?v[id][ num] # Show value\n" - "|?vx number -> show 8 digit padding in hex\n" - "|?vi1 200 -> 1 byte size value (char)\n" - "|?vi2 0xffff -> 2 byte size value (short)\n" - "|?vi4 0xffff -> 4 byte size value (int)\n" - "|?vi8 0xffff -> 8 byte size value (st64)\n" - "| No argument shows $? value\n" - "|?vi will show in decimal instead of hex\n"); + r_core_cmd_help_match (core, help_msg_question, "?v", false); break; case '\0': r_cons_printf ("%d\n", (st32)n); @@ -970,7 +963,7 @@ static int cmd_help(void *data, const char *input) { } free (s); } else { - eprintf ("Usage: ?== str1 str2\n"); + r_core_cmd_help_match (core, help_msg_question, "?==", true); } } else { if (input[1]) { // ?= diff --git a/libr/core/cmd_info.c b/libr/core/cmd_info.c index 1686020737..be5e1347fb 100644 --- a/libr/core/cmd_info.c +++ b/libr/core/cmd_info.c @@ -3,7 +3,7 @@ #include #include "../bin/format/pdb/pdb_downloader.h" -static const char *help_msg_i[] = { +static RCoreHelpMessage help_msg_i = { "Usage: i", "", "Get info from opened file (see rabin2's manpage)", "Output mode:", "", "", "'*'", "", "output in radare commands", @@ -66,7 +66,7 @@ static const char *help_msg_i[] = { }; // TODO: this command needs a refactoring -static const char *help_msg_id[] = { +static RCoreHelpMessage help_msg_id = { "Usage: idp", "", "Debug information", "id", "", "show DWARF source lines information", "idp", " [file.pdb]", "load pdb file information", @@ -618,8 +618,7 @@ static int cmd_info(void *data, const char *input) { break; case '?': default: - eprintf ("Usage: ik [sdb-query]\n"); - eprintf ("Usage: ik* # load all header information\n"); + r_core_cmd_help_match (core, help_msg_i, "ik", false); } goto done; } @@ -1256,9 +1255,8 @@ static int cmd_info(void *data, const char *input) { case 'c': // "ic" // XXX this is dupe of cbin.c:bin_classes() if (input[1] == '?') { - eprintf ("Usage: ic[glbjqc**] [class-index or name]\n"); + r_core_cmd_help_match (core, help_msg_i, "ic", false); } else if (input[1] == ',') { // "ic," - // ic, cmd_ic_comma (core, input); } else if (input[1] == 'g') { // "icg" RBinClass *cls; @@ -1497,7 +1495,7 @@ static int cmd_info(void *data, const char *input) { break; case 'D': // "iD" if (input[1] != ' ' || !demangle (core, input + 2)) { - eprintf ("Usage: iD lang symbolname\n"); + r_core_cmd_help_match (core, help_msg_i, "iD", true); } return 0; case 'a': // "ia" diff --git a/libr/core/cmd_log.c b/libr/core/cmd_log.c index e4f346eac7..a6ee9d0731 100644 --- a/libr/core/cmd_log.c +++ b/libr/core/cmd_log.c @@ -6,7 +6,7 @@ bool ranal2_list(RCore *core, const char *arch, int fmt); -static const char *help_msg_La[] = { +static RCoreHelpMessage help_msg_La = { "Usage:", "La[qj]", " # asm/anal plugin list", "La", "", "List asm/anal pluginsh (See rasm2 -L)", "Laq", "", "Only list the plugin name", @@ -15,7 +15,7 @@ static const char *help_msg_La[] = { }; // TODO #7967 help refactor: move to another place -static const char *help_msg_L[] = { +static RCoreHelpMessage help_msg_L = { "Usage:", "L[acio]", "[-name][ file]", "L", "", "show this help", "L", " blah."R_LIB_EXT, "load plugin file", @@ -40,7 +40,7 @@ static const char *help_msg_L[] = { NULL }; -static const char *help_msg_T[] = { +static RCoreHelpMessage help_msg_T = { "Usage:", "T", "[-][ num|msg] # text-log utility with timestamps", "T", "", "list all Text log messages", "T", " message", "add new log message", @@ -283,7 +283,10 @@ static int cmd_log(void *data, const char *input) { R_LOG_ERROR ("File not found"); } } else { - eprintf ("Usage: less [filename]\n"); + static RCoreHelpMessage help_msg_less = { + "less", " [filename]", "view file with pagination", + }; + r_core_cmd_help (core, help_msg_less); } } break; diff --git a/libr/core/cmd_macro.c b/libr/core/cmd_macro.c index 95d93262a1..897dafe10b 100644 --- a/libr/core/cmd_macro.c +++ b/libr/core/cmd_macro.c @@ -3,7 +3,7 @@ #include "r_cmd.h" #include "r_core.h" -static const char *help_msg_lparen[] = { +static RCoreHelpMessage help_msg_lparen = { "Usage:", "(foo args;cmd1;cmd2;..)", "Aliases", "(foo args;..;..)", "", "define a macro", "(foo args;..;..)()", "", "define and call a macro", diff --git a/libr/core/cmd_meta.c b/libr/core/cmd_meta.c index 1abe1f8742..418ff9956e 100644 --- a/libr/core/cmd_meta.c +++ b/libr/core/cmd_meta.c @@ -10,7 +10,7 @@ static R_TH_LOCAL int filter_format = 0; static R_TH_LOCAL size_t filter_count = 0; static R_TH_LOCAL Sdb *fscache = NULL; -static const char *help_msg_C[] = { +static RCoreHelpMessage help_msg_C = { "Usage:", "C[-LCvsdfm*?][*?] [...]", " # Metadata management", "C", "", "list meta info in human friendly form", "C*", "", "list meta info in r2 commands", @@ -41,7 +41,7 @@ static const char *help_msg_C[] = { NULL }; -static const char *help_msg_CC[] = { +static RCoreHelpMessage help_msg_CC = { "Usage:", "CC[-+!*au] [base64:..|str] @ addr", "", "CC!", "", "edit comment using cfg.editor (vim, ..)", "CC", " [text]", "append comment at current address", @@ -60,7 +60,7 @@ static const char *help_msg_CC[] = { }; // IMHO 'code-line' should be universal concept, instead of dbginfo/dwarf/... -static const char *help_msg_CL[] = { +static RCoreHelpMessage help_msg_CL = { "Usage: CL", ".j-", "@addr - manage code-line references (loaded via bin.dbginfo and shown when asm.dwarf)", "CL", "", "list all code line information (virtual address <-> source file:line)", "CLj", "", "same as above but in JSON format (See dir.source to change the path to find the referenced lines)", @@ -74,7 +74,7 @@ static const char *help_msg_CL[] = { NULL }; -static const char *help_msg_Ct[] = { +static RCoreHelpMessage help_msg_Ct = { "Usage: Ct", "[.|-] [@ addr]", " # Manage comments for variable types", "Ct", "", "list all variable type comments", "Ct", " comment-text [@ addr]", "place comment at current or specified address", @@ -83,7 +83,7 @@ static const char *help_msg_Ct[] = { NULL }; -static const char *help_msg_CS[] = { +static RCoreHelpMessage help_msg_CS = { "Usage: CS","[*] [+-][metaspace|addr]", " # Manage metaspaces", "CS","","display metaspaces", "CS"," *","select all metaspaces", @@ -97,7 +97,7 @@ static const char *help_msg_CS[] = { NULL }; -static const char *help_msg_Cs[] = { +static RCoreHelpMessage help_msg_Cs = { "Usage:", "Cs[ga-*.] [size] [@addr]", "", "NOTE:", " size", "1 unit in bytes == width in bytes of smallest possible char in encoding,", "", "", " so ascii/latin1/utf8 = 1, utf16le = 2", @@ -115,7 +115,7 @@ static const char *help_msg_Cs[] = { NULL }; -static const char *help_msg_Cvb[] = { +static RCoreHelpMessage help_msg_Cvb = { "Usage:", "Cvb", "[name] [comment]", "Cvb?", "", "show this help", "Cvb", "", "list all base pointer args/vars comments in human friendly format", @@ -127,7 +127,7 @@ static const char *help_msg_Cvb[] = { NULL }; -static const char *help_msg_Cvr[] = { +static RCoreHelpMessage help_msg_Cvr = { "Usage:", "Cvr", "[name] [comment]", "Cvr?", "", "show this help", "Cvr", "", "list all register based args comments in human friendly format", @@ -139,7 +139,7 @@ static const char *help_msg_Cvr[] = { NULL }; -static const char *help_msg_Cvs[] = { +static RCoreHelpMessage help_msg_Cvs = { "Usage:", "Cvs", "[name] [comment]", "Cvs!", "[name]", "edit comment using cfg editor", "Cvs", "", "list all stack based args/vars comments in human friendly format", @@ -634,8 +634,7 @@ static int cmd_meta_comment(RCore *core, const char *input) { if (s) { s = strdup (s + 1); } else { - eprintf ("Usage: CCa [address] [comment]\n"); - eprintf ("Usage: CCa-[address]\n"); + r_core_cmd_help_match (core, help_msg_CC, "CCa", true); return false; } p = strchr (s, ' '); @@ -650,7 +649,7 @@ static int cmd_meta_comment(RCore *core, const char *input) { R_META_TYPE_COMMENT, addr, 1); } else { - eprintf ("Usage: CCa-[address]\n"); + r_core_cmd_help_match (core, help_msg_CC, "CCa", true); } free (s); return true; @@ -671,7 +670,7 @@ static int cmd_meta_comment(RCore *core, const char *input) { r_meta_set (core->anal, R_META_TYPE_COMMENT, addr, 1, p); } } else { - eprintf ("Usage: CCa [address] [comment]\n"); + r_core_cmd_help_match (core, help_msg_CC, "CCa", true); } free (s); return true; @@ -743,8 +742,8 @@ static int cmd_meta_others(RCore *core, const char *input) { case '?': switch (input[0]) { case 'f': // "Cf?" + r_core_cmd_help_match (core, help_msg_C, "Cf", true); r_cons_println ( - "Usage: Cf[-] [sz] [fmt..] [@addr]\n\n" "'sz' indicates the byte size taken up by struct.\n" "'fmt' is a 'pf?' style format string. It controls only the display format.\n\n" "You may wish to have 'sz' != sizeof (fmt) when you have a large struct\n" @@ -936,7 +935,7 @@ static int cmd_meta_others(RCore *core, const char *input) { n = -1; } } else { - eprintf ("Usage: Cf [size] [pf-format-string]\n"); + r_core_cmd_help_match (core, help_msg_C, "Cf", true); break; } } else if (type == 's') { // "Cs" @@ -1231,7 +1230,7 @@ static int cmd_meta(void *data, const char *input) { if (input[2] == ' ') { r_spaces_rename (ms, NULL, input + 2); } else { - eprintf ("Usage: CSr [newname]\n"); + r_core_cmd_help_match (core, help_msg_CS, "CSr", true); } break; case '-': // "CS-" diff --git a/libr/core/cmd_mount.c b/libr/core/cmd_mount.c index 83ffae914c..188070e6b7 100644 --- a/libr/core/cmd_mount.c +++ b/libr/core/cmd_mount.c @@ -1,6 +1,6 @@ /* radare - LGPL - Copyright 2009-2022 // pancake */ -static const char *help_msg_m[] = { +static RCoreHelpMessage help_msg_m = { "Usage:", "m[-?*dgy] [...] ", "Mountpoints management", "m", " /mnt ext2 0", "mount ext2 fs at /mnt with delta 0 on IO", "m", " /mnt", "mount fs at /mnt with autodetect fs and current offset", @@ -20,14 +20,14 @@ static const char *help_msg_m[] = { "mp", " msdos 0", "show partitions in msdos format at offset 0", "mp", "", "list all supported partition types", "ms", " /mnt", "open filesystem shell at /mnt (or fs.cwd if not defined)", - "mw", " [file] [data]", "write data into file", // TODO: add mwf + "mw", " [file] [data]", "write data into file", "mwf", " [diskfile] [r2filepath]", "write contents of local diskfile into r2fs mounted path", "my", "", "yank contents of file into clipboard", //"TODO: support multiple mountpoints and RFile IO's (need io+core refactorn", NULL }; -static const char *help_msg_mf[] = { +static RCoreHelpMessage help_msg_mf = { "Usage:", "mf[no] [...]", "search files matching name or offset", "mfn", " /foo *.c","search files by name in /foo path", "mfo", " /foo 0x5e91","search files by offset in /foo path", @@ -215,15 +215,15 @@ static int cmd_mount(void *data, const char *_input) { } break; case '-': - if (input[1] == '?') { // "mL?" - r_core_cmd_help_match_spec (core, help_msg_m, "m-", 0, true); + if (input[1] == '?') { // "m-?" + r_core_cmd_help_match (core, help_msg_m, "m-", true); } else { r_fs_umount (core->fs, input + 1); } break; case 'j': - if (input[1] == '?') { // "mL?" - r_core_cmd_help_match_spec (core, help_msg_m, "mj", 0, true); + if (input[1] == '?') { // "mj?" + r_core_cmd_help_match (core, help_msg_m, "mj", true); } else { PJ *pj = r_core_pj_new (core); pj_o (pj); @@ -266,7 +266,7 @@ static int cmd_mount(void *data, const char *_input) { break; case 'L': // "mL" list of plugins if (input[1] == '?') { // "mL?" - r_core_cmd_help_match_spec (core, help_msg_m, "mL", 0, true); + r_core_cmd_help_match (core, help_msg_m, "mL", true); } else if (input[1] == 'L') { r_list_foreach (core->fs->plugins, iter, plug) { r_cons_printf ("%s\n", plug->name); @@ -290,10 +290,9 @@ static int cmd_mount(void *data, const char *_input) { } } break; - case 'l': // "ml" case 'd': // "md" if (input[1] == '?') { // "md?" - r_core_cmd_help_match_spec (core, help_msg_m, "md", 0, true); + r_core_cmd_help_match (core, help_msg_m, "md", true); } else { cmd_mount_ls (core, input + 1); } @@ -301,7 +300,7 @@ static int cmd_mount(void *data, const char *_input) { case 'p': // "mp" input = (char *)r_str_trim_head_ro (input + 1); if (input[0] == '?') { // "mp?" - r_core_cmd_help_match_spec (core, help_msg_m, "mp", 0, true); + r_core_cmd_help_match (core, help_msg_m, "mp", true); break; } ptr = strchr (input, ' '); @@ -324,7 +323,7 @@ static int cmd_mount(void *data, const char *_input) { case 'o': // "mo" input = (char *)r_str_trim_head_ro (input + 1); if (*input == '?') { // "mo?" - r_core_cmd_help_match_spec (core, help_msg_m, "mo", 0, true); + r_core_cmd_help_match (core, help_msg_m, "mo", true); } else { file = r_fs_open (core->fs, input, false); if (file) { @@ -341,7 +340,7 @@ static int cmd_mount(void *data, const char *_input) { break; case 'i': if (input[1] == '?') { // "mi?" - r_core_cmd_help_match_spec (core, help_msg_m, "mi", 0, true); + r_core_cmd_help_match (core, help_msg_m, "mi", true); } else { input = (char *)r_str_trim_head_ro (input + 1); file = r_fs_open (core->fs, input, false); @@ -356,8 +355,8 @@ static int cmd_mount(void *data, const char *_input) { } break; case 'c': // "mc" - if (input[1] == '?') { // "mi?" - r_core_cmd_help_match_spec (core, help_msg_m, "mc", 0, true); + if (input[1] == '?') { // "mc?" + r_core_cmd_help_match (core, help_msg_m, "mc", true); } else { input = (char *)r_str_trim_head_ro (input + 1); ptr = strchr (input, ' '); @@ -379,7 +378,7 @@ static int cmd_mount(void *data, const char *_input) { break; case 'g': // "mg" if (input[1] == '?') { // "mg?" - r_core_cmd_help_match_spec (core, help_msg_m, "mg", 0, true); + r_core_cmd_help_match (core, help_msg_m, "mg", true); break; } input = (char *)r_str_trim_head_ro (input + 1); @@ -493,7 +492,7 @@ static int cmd_mount(void *data, const char *_input) { break; case 's': // "ms" if (input[1] == '?') { // "ms?" - r_core_cmd_help_match_spec (core, help_msg_m, "ms", 0, true); + r_core_cmd_help_match (core, help_msg_m, "ms", true); break; }; if (!r_config_get_b (core->config, "scr.interactive")) { @@ -521,17 +520,13 @@ static int cmd_mount(void *data, const char *_input) { } break; case 'w': // "mw" - if (input[1] == '?') { // "ms?" - r_core_cmd_help_match_spec (core, help_msg_m, "mw", 0, true); - break; - } if (input[1] == 'f') { // "mwf" char *arg0 = r_str_trim_dup (input + 1); char *arg1 = strchr (arg0, ' '); if (arg1) { *arg1++ = 0; } else { - eprintf ("Usage: mwf [local] [dest]\n"); + r_core_cmd_help_match (core, help_msg_m, "mwf", true); free (arg0); break; } @@ -563,12 +558,12 @@ static int cmd_mount(void *data, const char *_input) { } free (args); } else { - eprintf ("Usage: mw [file] ([data])\n"); + r_core_cmd_help_match (core, help_msg_m, "mw", false); } break; case 'y': - if (input[1] == '?') { // "ms?" - r_core_cmd_help_match_spec (core, help_msg_m, "my", 0, true); + if (input[1] == '?') { // "my?" + r_core_cmd_help_match (core, help_msg_m, "my", true); break; } input = (char *)r_str_trim_head_ro (input + 1); diff --git a/libr/core/cmd_open.c b/libr/core/cmd_open.c index 5e9c04229e..f2fb456564 100644 --- a/libr/core/cmd_open.c +++ b/libr/core/cmd_open.c @@ -3,39 +3,39 @@ #include #include -static const char *help_msg_o[] = { - "Usage: o","[com- ] [file] ([offset])","", +static RCoreHelpMessage help_msg_o = { + "Usage: o","[file] ([offset])","Open and close files, maps, and banks", + "o","","list opened files", "o"," [file] 0x4000 rwx", "map file at 0x4000", "o"," [file]","open [file] file in read-only", - "o","","list opened files", "o","-1","close file descriptor 1", "o*","","list opened files in r2 commands", "o+"," [file]", "open a file in read-write mode", "o++"," [file]", "create and open file in read-write mode (see ot and omr)", - "o-","!*","close all opened files", - "o--","","close all files, analysis, binfiles, flags, same as !r2 --", + "o-","[?][#!*$.]","close opened files", "o.","","show current filename (or o.q/oq to get the fd)", "o:"," [len]","open a malloc://[len] copying the bytes from current offset", "o=","","list opened files (ascii-art bars)", "oL","","list all IO plugins registered", - "oa","[?][-] [A] [B] [filename]","specify arch and bits for given file", + "oa","[-] [A] [B] [filename]","specify arch and bits for given file", "ob","[?] [lbdos] [...]","list opened binary files backed by fd", "oc"," [file]","open core file, like relaunching r2", "of","[?] [file]","open file without creating any map", "oe"," [filename]","open cfg.editor with given file", - "oj","[?]","list opened files in JSON format", + "oj","","list opened files in JSON format", "om","[?]","create, list, remove IO maps", "on","[?][n] [file] 0x4000","map raw file at 0x4000 (no r_bin involved)", "oo","[?][+bcdnm]","reopen current file (see oo?) (reload in rw or debugger)", - "op","[r|n|p|fd]", "select priorized file by fd (see ob), opn/opp/opr = next/previous/rotate", + "op","[npr] [fd]", "select priorized file by fd (see ob), opn/opp/opr = next/previous/rotate", "ot"," [file]", "same as `touch [file]`", "oq","","list all open files", "ox", " fd fdx", "exchange the descs of fd and fdx and keep the mapping", + "open", " [file]", "use system xdg-open/open on a file", NULL }; -static const char *help_msg_on[] = { - "Usage: on","[n+*] [file] ([addr] [rwx])","Open file without parsing headers", +static RCoreHelpMessage help_msg_on = { + "Usage: on[n+*]", "[file] ([addr] [rwx])","Open file without parsing headers", "on"," /bin/ls 0x4000","map raw file at 0x4000 (no r_bin involved)", "onn"," [file] ([rwx])","open file without creating any map or parsing headers with rbin)", "onnu"," [file] ([rwx])","same as onn, but unique, will return previos fd if already opened", @@ -44,24 +44,19 @@ static const char *help_msg_on[] = { NULL }; -static const char *help_msg_oa[] = { - "Usage: oa","[-][arch] [bits] ([file])", "Specify arch and bits for given file", - "oa"," arm 32","force arm32 for the current open file", - NULL -}; - -static const char *help_msg_o_[] = { - "Usage: o-","[#!*]", "", +static RCoreHelpMessage help_msg_o_dash = { + "Usage: o-[#!*$.-]", "", "close opened files", "o-*","","close all opened files", "o-!","","close all files except the current one", "o-3","","close fd=3", "o-$","","close last fd", "o-.","","close current fd", + "o--","","close all files, analysis, binfiles, flags, same as !r2 --", NULL }; -static const char *help_msg_op[] = { - "Usage:", "op[rnp] [fd]", "", +static RCoreHelpMessage help_msg_op = { + "Usage: op[rnp]", "[fd]", "", "opr", "", "open next file rotating", "opn", "", "open next file", "opp", "", "open previous file", @@ -69,43 +64,38 @@ static const char *help_msg_op[] = { NULL }; -static const char *help_msg_omn[] = { - "Usage:", "omn[.-] ([fd]) [name]", "# define a name for the given map", +static RCoreHelpMessage help_msg_omn = { + "Usage: omn[.i]", "([fd]) [name]", "Define a name for the given map", "omn", " mapaddr [name]", "set/delete name for map which spans mapaddr", "omn.", "([-|name])", "show/set/delete name for current map", "omni", " mapid [name]", "set/delete name for map with mapid", NULL }; -static const char *help_msg_omb[] = { - "Usage:", "omb[jq,+] [fd]", "Operate on memory banks", +static RCoreHelpMessage help_msg_omb = { + "Usage: omb[+-adgq]", "[fd]", "Operate on memory banks", "omb", "", "list all memory banks", "omb", " [id]", "switch to use a different bank", - "omb+", "[name]", "create a new bank with given name", + "omb+", " [name]", "create a new bank with given name", "omba", " [id]", "adds a map to the bank", - "ombd", " [id]", "deletes a map from the bank", + "ombd", " [id]", "delete a map from the bank", "omb-", "*", "delete all banks", - "omb-", "[mapid]", "delete the bank with given id", + "omb-", " [mapid]", "delete the bank with given id", "ombg", "", "associate all maps to the current bank", "ombq", "", "show current bankid", NULL }; -static const char *help_msg_o_star[] = { - "Usage:", "o* [> files.r2]", "", - "o*", "", "list opened files in r2 commands", NULL -}; - -static const char *help_msg_oba[] = { - "Usage:", "oba [addr] ([filename])", " # load bininfo and update flags", +static RCoreHelpMessage help_msg_oba = { + "Usage: oba", "[addr] ([filename])", "Load bininfo and update flags", "oba", " [addr]", "open bin info from the given address", "oba", " [addr] [baddr]", "open file and load bin info at given address", "oba", " [addr] [/abs/filename]", "open file and load bin info at given address", NULL }; -static const char *help_msg_ob[] = { - "Usage:", "ob", " # List open binary files backed by fd", +static RCoreHelpMessage help_msg_ob = { + "Usage: ob", "", "List open binary files backed by fd", "ob", " [name|bfid]", "switch to open given objid (or name)", "ob", "", "list opened binary files and objid", "ob*", "", "list opened binary files and objid (r2 commands)", @@ -128,13 +118,8 @@ static const char *help_msg_ob[] = { NULL }; -static const char *help_msg_oj[] = { - "Usage:", "oj [~{}]", " # Use ~{} to indent the JSON", - "oj", "", "list opened files in JSON format", NULL -}; - -static const char *help_msg_om[] = { - "Usage:", "om[-] [arg]", " # map opened files", +static RCoreHelpMessage help_msg_om = { + "Usage: om", "[arg]", "Map opened files", "om", " [fd]", "list all defined IO maps for a specific fd", "om", " fd vaddr [size] [paddr] [rwx] [name]", "create new io map", "om", "", "list all defined IO maps", @@ -149,12 +134,12 @@ static const char *help_msg_om[] = { "omb", " ", "list/select memory map banks", "omB", " mapid addr", "relocate map with corresponding id", "omB.", " addr", "relocate current map", - "omd", " from to @ paddr", "simplied om, takes current seek, fd and perms", + "omd", " from to @ paddr", "simplified om; takes current seek, fd and perms", "omf", " [mapid] rwx", "change flags/perms for current/given map", "omfg", "[+-]rwx", "change flags/perms for all maps (global)", "omj", "", "list all maps in json format", - "omm"," [fd]", "create default map for given fd. (omm `oq`)", - "omn", "[?] ([id]) [name]", "manage map names", + "omm"," [fd]", "create default map for given fd (omm `oq`)", + "omn", "[?] ([fd]) [name]", "manage map names", "omo", " fd", "map the given fd with lowest priority", "omp", " mapid", "prioritize map with corresponding id", "ompb", " [fd]", "prioritize maps of the bin associated with the binid", @@ -166,71 +151,36 @@ static const char *help_msg_om[] = { NULL }; -static const char *help_msg_omd[] = { - "Usage:", "omd v_begin v_end @ paddr", " # simplified om", - "omd", "0x100000 0x200000 @ 0x100", " # map B-A bytes from PA 0x100- in A", - NULL -}; - -static const char *help_msg_oo[] = { - "Usage:", "oo[-] [arg]", " # map opened files", +static RCoreHelpMessage help_msg_oo = { + "Usage: oo", "[arg]", "Map opened files", "oo", "", "reopen current file", "oo+", "", "reopen in read-write", - "oob", "[?] [baddr]", "reopen loading rbin info (change base address?)", + "oob", " [baddr]", "reopen loading rbin info (change base address?)", "ooc", "", "reopen core with current file", "ood", "[?]", "reopen in debug mode", "oom", "[?]", "reopen in malloc://", - "oon", "[?]", "reopen without loading rbin info", - "oon+", "", "reopen in read-write mode without loading rbin info", - "oonn", "", "reopen without loading rbin info, but with header flags", - "oonn+", "", "reopen in read-write mode without loading rbin info, but with", - NULL -}; - -static const char *help_msg_oo_plus[] = { - "Usage:", "oo+", " # reopen in read-write", - NULL -}; - -static const char *help_msg_oob[] = { - "Usage:", "oob", " # reopen loading rbin info", - NULL -}; - -static const char *help_msg_ood[] = { - "Usage:", "ood", " # Debug (re)open commands", - "ood", " [args]", " # reopen in debug mode (with args)", - "oodf", " [file]", " # reopen in debug mode using the given file", - "oodr", " [rarun2]", " # same as dor ..;ood", - NULL -}; - -static const char *help_msg_oon[] = { - "Usage:", "oon[+]", " # reopen without loading rbin info", "oon", "", "reopen without loading rbin info", "oon+", "", "reopen in read-write mode without loading rbin info", + "oonn", "", "reopen without loading rbin info, but with header flags", + "oonn+", "", "reopen in read-write mode without loading rbin info, but with", NULL }; -static const char *help_msg_oonn[] = { - "Usage:", "oonn", " # reopen without loading rbin info, but with header flags", - "oonn", "", "reopen without loading rbin info, but with header flags", - "oonn+", "", "reopen in read-write mode without loading rbin info, but with", +static RCoreHelpMessage help_msg_ood = { + "Usage: ood", "", "Debug (re)open commands", + "ood", " [args]", "reopen in debug mode (with args)", + "oodf", " [file]", "reopen in debug mode using the given file", + "oodr", " [rarun2]", "same as dor ..;ood", NULL }; static bool isfile(const char *filename) { - if (R_STR_ISEMPTY (filename)) { - return false; - } - // check for ./ or / - if (r_file_exists (filename)) { - return true; - } - if (r_str_startswith (filename, "./") || r_str_startswith (filename, "/")) { - return true; - } - return false; + return R_STR_ISNOTEMPTY (filename) + && ( + r_file_exists (filename) + || r_str_startswith (filename, "./") + || r_str_startswith (filename, "/") + ); } // HONOR bin.at @@ -268,7 +218,7 @@ static void cmd_open_bin(RCore *core, const char *input) { } break; case 'a': // "oba" - if ('?' == input[2]) { + if (input[2] == '?') { r_core_cmd_help (core, help_msg_oba); break; } @@ -362,7 +312,7 @@ static void cmd_open_bin(RCore *core, const char *input) { } int n = r_str_word_set0 (v); if (n < 1 || n > 2) { - eprintf ("Usage: ob [file|objid]\n"); + r_core_cmd_help_match (core, help_msg_o, "ob", true); free (v); break; } @@ -379,8 +329,12 @@ static void cmd_open_bin(RCore *core, const char *input) { break; } case 'r': // "obr" - r_core_bin_rebase (core, r_num_math (core->num, input + 3)); - r_core_cmd0 (core, ".is*"); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_ob, "obr", true); + } else { + r_core_bin_rebase (core, r_num_math (core->num, input + 3)); + r_core_cmd0 (core, ".is*"); + } break; case 'f': // "obf" if (input[2] == ' ') { @@ -756,7 +710,7 @@ static bool cmd_om(RCore *core, const char *input, int arg) { static void cmd_omd(RCore *core, const char* input) { if (*input == '?') { - r_core_cmd_help (core, help_msg_omd); + r_core_cmd_help_match (core, help_msg_om, "omd", true); return; } int fd = r_io_fd_get_current (core->io); @@ -764,26 +718,20 @@ static void cmd_omd(RCore *core, const char* input) { if (desc) { char *inp = r_str_trim_dup (input); RList *args = r_str_split_list (inp, " ", 0); - if (args) - switch (r_list_length (args)) { - case 2: - { - ut64 pa = core->offset; - ut64 va = r_num_math (core->num, r_list_get_n (args, 0)); - ut64 vb = r_num_math (core->num, r_list_get_n (args, 1)); - ut64 sz = vb - va; - RIOMap *map = NULL; - if (va < vb) { - map = r_io_map_add (core->io, fd, desc->perm, pa, va, sz); - } - if (!map) { - R_LOG_ERROR ("Cannot create map"); - } + if (args && r_list_length (args) == 2) { + ut64 pa = core->offset; + ut64 va = r_num_math (core->num, r_list_get_n (args, 0)); + ut64 vb = r_num_math (core->num, r_list_get_n (args, 1)); + ut64 sz = vb - va; + RIOMap *map = NULL; + if (va < vb) { + map = r_io_map_add (core->io, fd, desc->perm, pa, va, sz); } - break; - default: - r_core_cmd_help (core, help_msg_omd); - break; + if (!map) { + R_LOG_ERROR ("Invalid map range"); + } + } else { + r_core_cmd_help_match (core, help_msg_om, "omd", true); } r_list_free (args); r_free (inp); @@ -1752,12 +1700,11 @@ static int cmd_open(void *data, const char *input) { int argc, fd = -1; RIODesc *file; RIODesc *desc; - bool write = false; const char *ptr = NULL; char **argv = NULL; switch (*input) { - case 'a': + case 'a': // "oa" switch (input[1]) { case '*': // "oa*" { @@ -1772,54 +1719,53 @@ static int cmd_open(void *data, const char *input) { } break; case '?': // "oa?" - r_core_cmd_help (core, help_msg_oa); + r_core_cmd_help_match (core, help_msg_o, "oa", true); return 1; - case ' ': // "oa " - { - int i; - char *ptr = strdup (input+2); - const char *arch = NULL; - ut16 bits = 0; - const char *filename = NULL; - i = r_str_word_set0 (ptr); - if (i < 2) { - R_LOG_ERROR ("Missing argument"); - free (ptr); - return 0; - } - if (i == 3) { - filename = r_str_word_get0 (ptr, 2); - } - bits = r_num_math (core->num, r_str_word_get0 (ptr, 1)); - arch = r_str_word_get0 (ptr, 0); - r_core_bin_set_arch_bits (core, filename, arch, bits); - RBinFile *file = NULL; - if (filename) { - file = r_bin_file_find_by_name (core->bin, filename); - if (!file) { - R_LOG_ERROR ("Cannot find file %s", filename); - } - } else if (r_list_length (core->bin->binfiles) == 1) { - file = (RBinFile *)r_list_first (core->bin->binfiles); - } else { - R_LOG_INFO ("More than one file is opened, you must specify the filename"); - } - if (!file) { - free (ptr); - return 0; - } - if (file->o && file->o->info) { - free (file->o->info->arch); - file->o->info->arch = strdup (arch); - file->o->info->bits = bits; - r_core_bin_set_env (core, file); - } + case ' ': { // "oa " + int i; + char *ptr = strdup (input+2); + const char *arch = NULL; + ut16 bits = 0; + const char *filename = NULL; + i = r_str_word_set0 (ptr); + if (i < 2) { + R_LOG_ERROR ("Missing argument"); free (ptr); - return 1; + return 0; + } + if (i == 3) { + filename = r_str_word_get0 (ptr, 2); + } + bits = r_num_math (core->num, r_str_word_get0 (ptr, 1)); + arch = r_str_word_get0 (ptr, 0); + r_core_bin_set_arch_bits (core, filename, arch, bits); + RBinFile *file = NULL; + if (filename) { + file = r_bin_file_find_by_name (core->bin, filename); + if (!file) { + R_LOG_ERROR ("Cannot find file %s", filename); + } + } else if (r_list_length (core->bin->binfiles) == 1) { + file = (RBinFile *)r_list_first (core->bin->binfiles); + } else { + R_LOG_INFO ("More than one file is opened, you must specify the filename"); + } + if (!file) { + free (ptr); + return 0; + } + if (file->o && file->o->info) { + free (file->o->info->arch); + file->o->info->arch = strdup (arch); + file->o->info->bits = bits; + r_core_bin_set_env (core, file); + } + free (ptr); + return 1; } break; default: - r_core_cmd_help (core, help_msg_oa); + r_core_cmd_help_match (core, help_msg_o, "oa", true); return 0; } break; @@ -1837,7 +1783,6 @@ static int cmd_open(void *data, const char *input) { return 0; } if (input[1] == '+') { // "on+" - write = true; perms |= R_PERM_W; if (input[2] != ' ') { r_core_cmd_help_match (core, help_msg_on, "on+", true); @@ -1852,7 +1797,7 @@ static int cmd_open(void *data, const char *input) { } argv = r_str_argv (ptr, &argc); if (!argc) { - eprintf ("Usage: on%s file [addr] [rwx]\n", write?"+":""); + r_core_cmd_help (core, help_msg_on); r_str_argv_free (argv); return 0; } @@ -1933,9 +1878,8 @@ static int cmd_open(void *data, const char *input) { eprintf ("Unknown open tool. Cannot find xdg-open\n"); } #endif - } else { - eprintf ("Usage: open [path]\n"); + r_core_cmd_help_match (core, help_msg_o, "open", true); } } break; @@ -1946,14 +1890,13 @@ static int cmd_open(void *data, const char *input) { R_LOG_ERROR ("Cannot find file"); } break; - case ' ': - { - int fd = r_num_math (core->num, input + 1); - if (fd >= 0 || input[1] == '0') { - cmd_op (core, 0, fd); - } else { - R_LOG_ERROR ("Invalid fd number"); - } + case ' ': { + int fd = r_num_math (core->num, input + 1); + if (fd >= 0 || input[1] == '0') { + cmd_op (core, 0, fd); + } else { + R_LOG_ERROR ("Invalid fd number"); + } } break; default: @@ -1982,7 +1925,11 @@ static int cmd_open(void *data, const char *input) { ptr = input + 1; argv = r_str_argv (ptr, &argc); if (argc == 0) { - eprintf ("Usage: o (uri://)[/path/to/file] (addr)\n"); + if (perms & R_PERM_W) { + r_core_cmd_help_match (core, help_msg_o, "o+", false); + } else { + r_core_cmd_help_match (core, help_msg_o, "o", true); + } r_str_argv_free (argv); return 0; } @@ -2064,15 +2011,15 @@ static int cmd_open(void *data, const char *input) { r_id_storage_foreach (core->io->files, desc_list_cb, core->print); break; case '*': // "o*" - if ('?' == input[1]) { - r_core_cmd_help (core, help_msg_o_star); + if (input[1] == '?') { + r_core_cmd_help_match (core, help_msg_o, "o*", true); break; } r_id_storage_foreach (core->io->files, desc_list_cmds_cb, core); break; case 'j': // "oj" - if ('?' == input[1]) { - r_core_cmd_help (core, help_msg_oj); + if (input[1] == '?') { + r_core_cmd_help_match (core, help_msg_o, "oj", true); break; } PJ *pj = pj_new (); @@ -2117,13 +2064,23 @@ static int cmd_open(void *data, const char *input) { case '-': // "o-" switch (input[1]) { case '!': // "o-!" - r_core_file_close_all_but (core); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_o_dash, "o-!", true); + } else { + r_core_file_close_all_but (core); + } break; case '$': // "o-$" - R_LOG_TODO ("o-$: close last fd is not implemented"); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_o_dash, "o-$", true); + } else { + R_LOG_TODO ("o-$: close last fd is not implemented"); + } break; case '.': // "o-." - { + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_o_dash, "o-*", true); + } else { RBinFile *bf = r_bin_cur (core->bin); if (bf && bf->fd >= 0) { core->bin->cur = NULL; @@ -2135,27 +2092,35 @@ static int cmd_open(void *data, const char *input) { } break; case '*': // "o-*" - r_io_close_all (core->io); - r_bin_file_delete_all (core->bin); - break; - case '-': // "o--" - r_io_close_all (core->io); - r_bin_file_delete_all (core->bin); - r_core_cmd0 (core, "o-*;om-*"); - r_anal_purge (core->anal); - r_flag_unset_all (core->flags); - break; - default: - { - int fd = (int)r_num_math (core->num, input + 1); - if (!r_io_fd_close (core->io, fd)) { - R_LOG_ERROR ("Unable to find file descriptor %d", fd); - } + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_o_dash, "o-*", true); + } else { + r_io_close_all (core->io); + r_bin_file_delete_all (core->bin); } break; - case 0: + case '-': // "o--" + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_o_dash, "o--", true); + } else { + r_io_close_all (core->io); + r_bin_file_delete_all (core->bin); + r_core_cmd0 (core, "o-*;om-*"); + r_anal_purge (core->anal); + r_flag_unset_all (core->flags); + } + break; + case '\0': case '?': - r_core_cmd_help (core, help_msg_o_); + r_core_cmd_help (core, help_msg_o_dash); + break; + default: { + int fd = (int)r_num_math (core->num, input + 1); + if (!r_io_fd_close (core->io, fd)) { + R_LOG_ERROR ("Unable to find file descriptor %d", fd); + } + } + break; } break; case '.': // "o." @@ -2208,37 +2173,44 @@ static int cmd_open(void *data, const char *input) { r_core_file_reopen_in_malloc (core); break; case 'd': // "ood" : reopen in debugger - if (input[2] == 'r') { // "oodr" + switch (input[2]) { + case 'r': // "oodr" r_core_cmdf (core, "dor %s", input + 3); r_core_file_reopen_debug (core, ""); - } else if (input[2] == 'f') { // "oodf" - char **argv = NULL; - int addr = 0; + break; + case 'f': // "oodf" argv = r_str_argv (input + 3, &argc); - if (argc == 0) { - eprintf ("Usage: oodf (uri://)[/path/to/file] (addr)\n"); + if (argc < 1 || argc > 2) { + r_core_cmd_help_match (core, help_msg_ood, "oodf", true); r_str_argv_free (argv); return 0; } - if (argc == 2) { - if (r_num_is_valid_input (core->num, argv[1])) { - addr = r_num_math (core->num, argv[1]); - } + if (argc == 2 && r_num_is_valid_input (core->num, argv[1])) { + addr = r_num_math (core->num, argv[1]); } r_core_file_reopen_remote_debug (core, argv[0], addr); r_str_argv_free (argv); - } else if ('?' == input[2]) { - r_core_cmd_help (core, help_msg_ood); - } else { + break; + case '\0': // "ood" + case ' ': // "ood " r_core_file_reopen_debug (core, r_str_trim_head_ro (input + 2)); + break; + case '?': // "ood?" + default: + r_core_cmd_help (core, help_msg_ood); + break; } break; case 'c': // "ooc" - r_core_cmd0 (core, "oc `o.`"); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_oo, "ooc", true); + } else { + r_core_cmd0 (core, "oc `o.`"); + } break; case 'b': // "oob" : reopen with bin info - if ('?' == input[2]) { - r_core_cmd_help (core, help_msg_oob); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_oo, "oob", true); } else { r_core_file_reopen (core, input + 2, 0, 2); } @@ -2252,8 +2224,8 @@ static int cmd_open(void *data, const char *input) { r_core_file_reopen (core, NULL, R_PERM_RW, 0); break; case 'n': // "oonn" - if ('?' == input[3] || !core->io->desc) { - r_core_cmd_help (core, help_msg_oonn); + if (input[3] == '?' || !core->io->desc) { + r_core_cmd_help_match (core, help_msg_oo, "oonn", false); break; } RIODesc *desc = r_io_desc_get (core->io, core->io->desc->fd); @@ -2273,13 +2245,13 @@ static int cmd_open(void *data, const char *input) { break; case '?': default: - r_core_cmd_help (core, help_msg_oon); + r_core_cmd_help_match (core, help_msg_oo, "oon", false); break; } break; case '+': // "oo+" - if ('?' == input[2]) { - r_core_cmd_help (core, help_msg_oo_plus); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_oo, "oo+", true); } else if (core && core->io && core->io->desc) { int fd; int perms = R_PERM_RW; @@ -2341,7 +2313,7 @@ static int cmd_open(void *data, const char *input) { } } break; - case '?': + case '?': // "oo?" default: r_core_cmd_help (core, help_msg_oo); break; diff --git a/libr/core/cmd_print.c b/libr/core/cmd_print.c index 8e4bb5d404..6faa58e97c 100644 --- a/libr/core/cmd_print.c +++ b/libr/core/cmd_print.c @@ -7,8 +7,9 @@ #define PF_USAGE_STR "pf[.k[.f[=v]]|[v]]|[n]|[0|cnt][fmt] [a0 a1 ...]" static int printzoomcallback(void *user, int mode, ut64 addr, ut8 *bufz, ut64 size); -static const char *help_msg_pa[] = { - "Usage: pa[edD]", "[asm|hex]", "print (dis)assembled", + +static RCoreHelpMessage help_msg_pa = { + "Usage: pa[edD]", "[asm|hex]", "Print (dis)assembly", "pa", " [assembly]", "print hexpairs of the given assembly expression", "paD", " [hexpairs]", "print assembly expression from hexpairs and show hexpairs", "pad", " [hexpairs]", "print assembly expression from hexpairs (alias for pdx, pix)", @@ -17,8 +18,8 @@ static const char *help_msg_pa[] = { NULL }; -static const char *help_msg_psz[] = { - "Usage: psz[jl]", "", "print zero-terminated string", +static RCoreHelpMessage help_msg_psz = { + "Usage: psz[jl]", "", "Print zero-terminated string", "psz", "", "print zero-terminated string", "psz*", "", "r2 command to write the null-terminated string in here", "pszj", "", "print zero-terminated string as json", @@ -26,20 +27,7 @@ static const char *help_msg_psz[] = { NULL }; -static const char *help_msg_pdf[] = { - "Usage: pdf[bf]", "", "disassemble function", - "pdf", "", "disassemble function", - "pdfs", "", "disassemble function summary", - NULL -}; - -static const char *help_msg_pdo[] = { - "Usage: pdo", "", "convert esil to C for N instructions", - "pdo", " [count]", "print decompiled opcodes using esil", - NULL -}; - -static const char *help_msg_p8[] = { +static RCoreHelpMessage help_msg_p8 = { "Usage: p8[*fjx]", " [len]", "8bit hexpair list of bytes (see pcj)", "p8", " ([len])", "print hexpairs string", "p8*", "","display r2 commands to write this block", @@ -49,7 +37,14 @@ static const char *help_msg_p8[] = { NULL }; -static const char *help_msg_pp[] = { +static RCoreHelpMessage help_msg_pm = { + "Usage: pm", "[file|directory]", "Set libmagic reference file or directory (see /m?)", + "pm", " [file|directory]", "set libmagic reference (see /m?)", + "e", " dir.magic", "defaults to " R_JOIN_2_PATHS (R2_PREFIX, R2_SDB_MAGIC), + NULL +}; + +static RCoreHelpMessage help_msg_pp = { "Usage: pp[d]", "", "print patterns", "pp0", "", "print buffer filled with zeros", "pp1", "", "print incremental byte pattern (honor lower bits of cur address and bsize)", @@ -63,7 +58,7 @@ static const char *help_msg_pp[] = { NULL }; -static const char *help_msg_pc[] = { +static RCoreHelpMessage help_msg_pc = { "Usage:", "pc", " # Print in code", "pc", "", "C", "pc*", "", "print 'wx' r2 commands", @@ -92,7 +87,7 @@ static const char *help_msg_pc[] = { NULL }; -static const char *help_msg_p6[] = { +static RCoreHelpMessage help_msg_p6 = { "Usage: p6[d|e][s|z]", " [len]", "base64 decoding/encoding", "p6d", "[s|z] [len]", "decode current block as base64", "p6e", "[s|z][len]", "encode current block in base64", @@ -103,7 +98,7 @@ static const char *help_msg_p6[] = { NULL }; -static const char *help_msg_pF[] = { +static RCoreHelpMessage help_msg_pF = { "Usage: pF[apdbA][*vqj]", "[len]", "parse ASN1, PKCS, X509, DER, protobuf, axml", "pFa", "[jq] [len]", "decode ASN1/DER from current block (PEM is B64(DER))", "pFA", "[j] [len]", "decode Android Binary XML from current block", @@ -128,7 +123,7 @@ static const char* help_msg_pr[] = { NULL }; -static const char *help_msg_prg[] = { +static RCoreHelpMessage help_msg_prg = { "Usage: prg[?ilo]", " [len]", "print raw inflated/decompressed block", "prg", "", "print gunzipped data of current block", "prgl", "", "decompress current block using LZ4 (adjust blocksize)", @@ -137,7 +132,7 @@ static const char *help_msg_prg[] = { NULL }; -static const char *help_msg_amper[] = { +static RCoreHelpMessage help_msg_amper = { "Usage:", "&[-|]", "Manage tasks (WARNING: Experimental. Use with caution!)", "&", " ", "run in a new background task", "&:", "", "queue to be executed later when possible", @@ -155,7 +150,7 @@ static const char *help_msg_amper[] = { NULL }; -static const char *help_msg_p[] = { +static RCoreHelpMessage help_msg_p = { "Usage:", "p[=68abcdDfiImrstuxz] [arg|len] [@addr]", "", "p", "[b|B|xb] [len] ([S])", "bindump N bits skipping S bytes", "p", "[iI][df] [len]", "print N ops/bytes (f=func) (see pi? and pdi)", @@ -173,13 +168,15 @@ static const char *help_msg_p[] = { "pc", "[?][p] [len]", "output C (or python) format", "pC", "[aAcdDxw] [rows]", "print disassembly in columns (see hex.cols and pdi)", "pd", "[?] [sz] [a] [b]", "disassemble N opcodes (pd) or N bytes (pD)", - "pf", "[?][.nam] [fmt]", "print formatted data (pf.name, pf.name $)", + "pf", "[?][.name] [fmt]", "print formatted data (pf.name, pf.name $)", "pF", "[?][apx]", "print asn1, pkcs7 or x509", "pg", "[?][x y w h] [cmd]", "create new visual gadget or print it (see pg? for details)", "ph", "[?][=|hash] ([len])", "calculate hash for a block", "pi", "[?][bdefrj] [num]", "print instructions", "pI", "[?][iI][df] [len]", "print N instructions/bytes (f=func)", "pj", "[?] [len]", "print as indented JSON", + "pk", " [len]", "print key in randomart mosaic", + "pK", " [len]", "print key in randomart mosaic", "pm", "[?] [magic]", "print libmagic data (see pm? and /m?)", "po", "[?] hex", "print operation applied to block (see po?)", "pp", "[?][sz] [len]", "print patterns, see pp? for more help", @@ -187,16 +184,19 @@ static const char *help_msg_p[] = { "pr", "[?][glx] [len]", "print N raw bytes (in lines or hexblocks, 'g'unzip)", "ps", "[?][pwz] [len]", "print pascal/wide/zero-terminated strings", "pt", "[?][dn] [len]", "print different timestamps", - "pu", "[?][w] [len]", "print N url encoded bytes (w=wide)", + "pu", "[w] [len]", "print N url encoded bytes (w=wide)", "pv", "[?][ejh] [mode]", "show value of given size (1, 2, 4, 8)", "pwd", "", "display current working directory", "px", "[?][owq] [len]", "hexdump of N bytes (o=octal, w=32bit, q=64bit)", "py", "([-:file]) [expr]", "print clipboard (yp) run python script (py:file) oneliner `py print(1)` or stdin slurp `py-`", "pz", "[?] [len]", "print zoom view (see pz? for help)", + "pkill", " [process-name]", "kill all processes with the given name", + "pushd", " [dir]", "cd to dir and push current directory to stack", + "popd", "[-a][-h]", "pop dir off top of stack and cd to it", NULL }; -static const char *help_msg_pxd[] = { +static RCoreHelpMessage help_msg_pxd = { "Usage:", "pxd[1248] ([len])", "show decimal byte/short/word/dword dumps", "pxd", "", "show base10 signed decimal hexdumps", "pxd1", "", "show byte hexdump (int8_t)", @@ -206,7 +206,7 @@ static const char *help_msg_pxd[] = { NULL }; -static const char *help_msg_pxu[] = { +static RCoreHelpMessage help_msg_pxu = { "Usage:", "pxu[1248] ([len])", "show unsigned decimal byte/short/word/dword dumps", "pxu", "", "show base10 unsigned decimal hexdumps", "pxu1", "", "show byte hexdump (int8_t)", @@ -216,7 +216,7 @@ static const char *help_msg_pxu[] = { NULL }; -static const char *help_msg_p_equal[] = { +static RCoreHelpMessage help_msg_p_equal = { "Usage:", "p=[=bep?][qj] [N] ([len]) ([offset]) ", "show entropy/printable chars/chars bars", "e ", "zoom.in", "specify range for zoom", "p=", "", "print bytes of current block in bars", @@ -239,7 +239,7 @@ static const char *help_msg_p_equal[] = { NULL }; -static const char *help_msg_pj[] = { +static RCoreHelpMessage help_msg_pj = { "Usage:", "pj[..] [size]", "", "pj", "", "print current block as indented JSON", "pj.", "", "print as indented JSON from 0 to the current offset", @@ -247,66 +247,58 @@ static const char *help_msg_pj[] = { NULL }; -static const char *help_msg_p_minus[] = { - "Usage:", "p-[hj] [nblocks] ", "bar|json|histogram blocks", - "p-", "", "show ascii-art bar of metadata in file boundaries", - "p-e", "", "show ascii-art bar of entropy per block", - "p-h", "", "show histogram analysis of metadata per block", - "p-j", "", "show json format", +static RCoreHelpMessage help_msg_p_minus = { + "Usage:", "p-[hej] [nblocks] ", "bar|json|histogram blocks", + "p-", " [nblocks]", "show ascii-art bar of metadata in file boundaries", + "p-e", " [nblocks]", "show ascii-art bar of entropy per block", + "p-h", " [nblocks]", "show histogram analysis of metadata per block", + "p-j", " [nblocks]", "show json format", NULL }; -static const char *help_msg_pd[] = { +static RCoreHelpMessage help_msg_pd = { "Usage:", "p[dD][ajbrfils] [[-]len]", " # Print N bytes/instructions bw/forward", "NOTE: ", "len", "parameter can be negative", "NOTE: ", "", "Pressing ENTER on empty command will repeat last print command in next page", "pD", " N", "disassemble N bytes", "pd", " -N", "disassemble N instructions backwards", "pd", " N", "disassemble N instructions", - "pd--", "[n]", "context disassembly of N instructions", - "pda", "[?]", "disassemble all possible opcodes (byte per byte)", - "pdb", "[?]", "disassemble basic block", + "pd--", " N", "context disassembly of N instructions", + "pda", "", "disassemble all possible opcodes (byte per byte)", + "pdaj", "", "disassemble all possible opcodes (byte per byte) in JSON", + "pdb", "[j]", "disassemble basic block (j for JSON)", "pdc", "[?][c]", "pseudo disassembler output in C-like syntax", "pdC", "", "show comments found in N instructions", - "pde", "[q|qq|j] [N]", "disassemble N instructions following execution flow from current PC", - "pdo", "[N]", "convert esil expressions of N instructions to C (bytes for pdO)", - "pdf", "[?]", "disassemble function", + "pde", "[q|qq|j] N", "disassemble N instructions following execution flow from current PC", + "pdo", " N", "convert esil expressions of N instructions to C (pdO for bytes)", + "pdf", "", "disassemble function", + "pdfs", "", "disassemble function summary", "pdi", "", "like 'pi', with offset and bytes", "pdj", "", "disassemble to json", "pdJ", "", "formatted disassembly like pd as json", "pdk", "[?]", "disassemble all methods of a class", "pdl", "", "show instruction sizes", - "pdp", "[?]", "disassemble by following pointers to read ropchains", - "pdr", "[?]", "recursive disassemble across the function graph", + "pdp", "", "disassemble by following pointers to read ropchains", + "pdr", "", "recursive disassemble across the function graph", "pdr.", "", "recursive disassemble across the function graph (from current basic block)", "pdR", "", "recursive disassemble block size bytes without analyzing functions", - "pds", "[?]", "disassemble summary (strings, calls, jumps, refs) (see pdsf and pdfs)", + "pds", "[bf] [N]", "disassemble summary: strings, calls, jumps, refs (b=N bytes f=function)", "pdu", "[aceios?]", "disassemble instructions until condition", "pd,", " [n] [query]", "disassemble N instructions in a table (see dtd for debug traces)", "pdx", " [hex]", "alias for pad or pix", NULL }; -static const char *help_msg_pda[] = { - "Usage:", "pda[j]", "Print disassembly of all possbile opcodes", - "pdaj", "", "display the disassembly of all possbile opcodes (byte per byte) in JSON", - NULL -}; - -static const char *help_msg_pde[] = { +static RCoreHelpMessage help_msg_pde = { "Usage:", "pde[q|qq|j] [N]", "Disassemble N instructions following execution flow from current PC", "pde", "", "disassemble N instructions following execution flow from current PC", + "pdeq", "", "disassemble N instructions following execution flow from current PC (like pdi)", + "pdeqq", "", "disassemble N instructions following execution flow from current PC (like pi)", "pdej", "", "disassemble N instructions following execution flow from current PC in JSON", NULL }; -static const char *help_msg_pdp[] = { - "Usage:", "pdp", "Disassemble by following pointers to read ropchains", - "pdp", "", "disassemble by following pointers to read ropchains", - NULL -}; - -static const char *help_msg_ph[] = { +static RCoreHelpMessage help_msg_ph = { "Usage:", "ph", " [algorithm] ([size])", "ph", " md5", "compute md5 hash of current block", "ph", ":md5", "same as 'ph md5' (colon acts as a space)", @@ -316,22 +308,8 @@ static const char *help_msg_ph[] = { NULL }; -static const char *help_msg_pdr[] = { - "Usage:", "pdr", "Disassemble N instructions following execution flow from current PC", - "pdr", "", "recursive disassemble across the function graph", - "pdr.", "", "recursive disassemble across the function graph (from current basic block)", - NULL -}; - -static const char *help_msg_pds[] = { - "Usage:", "pds[bf]", "Summarize N bytes or function", - "pdsf", "", "summarize the current function", - "pdsb", "", "summarize N bytes", - NULL -}; - -static const char *help_msg_pdu[] = { - "Usage:", "pdu[aceios][j]", "Disassemble instructions until condition", +static RCoreHelpMessage help_msg_pdu = { + "Usage:", "pdu[acios][j]", "Disassemble instructions until condition", "pdua", "[j] [addr]", "disassemble until address", "pduc", "[j]", "disassemble until call", //"pdue", "[j] [expr]", "disassemble until esil expression", @@ -341,7 +319,7 @@ static const char *help_msg_pdu[] = { NULL }; -static const char *help_msg_pf[] = { +static RCoreHelpMessage help_msg_pf = { "Usage:", PF_USAGE_STR, "", "Commands:", "", "", "pf", " fmt", "show data using the given format-string. See 'pf\?\?' and 'pf\?\?\?'.", @@ -356,19 +334,19 @@ static const char *help_msg_pf[] = { "pf.", "fmt_name.field_name[i]", "show element i of array field_name", "pf.", "fmt_name [0|cnt]fmt", "define a new named format", "pf?", "fmt_name", "show the definition of a named format", - "pfb ", "binfmt", "binary format", - "pfc ", "fmt_name|fmt", "show data using (named) format as C string", + "pfb", " binfmt", "binary format", + "pfc", " fmt_name|fmt", "show data using (named) format as C string", "pfd.", "fmt_name", "show data using named format as graphviz commands", "pfj ", "fmt_name|fmt", "show data using (named) format in JSON", "pfo", " fdf_name", "load a Format Definition File (fdf)", "pfo", "", "list all format definition files (fdf)", "pfq", " fmt ...", "quiet print format (do now show address)", - "pfs", "[.fmt_name| fmt]", "print the size of (named) format in bytes", + "pfs", "[.fmt_name|fmt]", "print the size of (named) format in bytes", "pfv.", "fmt_name[.field]", "print value(s) only for named format. Useful for one-liners", NULL }; -static const char *help_detail_pf[] = { +static RCoreHelpMessage help_detail_pf = { "Usage:", PF_USAGE_STR, "", "Format:", "", "", " ", "b", "byte (unsigned)", @@ -410,7 +388,7 @@ static const char *help_detail_pf[] = { NULL }; -static const char *help_detail2_pf[] = { +static RCoreHelpMessage help_detail2_pf = { "Usage:", PF_USAGE_STR, "", "Examples:", "", "", "pf", " 3xi foo bar", "3-array of struct, each with named fields: 'foo' as hex, and 'bar' as int", @@ -439,7 +417,7 @@ static const char *help_detail2_pf[] = { NULL }; -static const char *help_msg_pi[] = { +static RCoreHelpMessage help_msg_pi = { "Usage:", "pi[bdefrj] [num]", "", "pia", "", "print all possible opcodes (byte per byte)", "pib", "", "print instructions of basic block", @@ -453,7 +431,7 @@ static const char *help_msg_pi[] = { NULL }; -static const char *help_msg_pie[] = { +static RCoreHelpMessage help_msg_pie = { "Usage:", "pie[fq]", " # print esil of N instructions", "pie", "", "print esil of N instructions", "pieb", "", "alias for `pie $Fi`", @@ -464,7 +442,7 @@ static const char *help_msg_pie[] = { NULL }; -static const char *help_msg_pif[] = { +static RCoreHelpMessage help_msg_pif = { "Usage:", "pif[cj]", " # print instructions from function", "pif", "", "print function instructions", "pifj", "", "same as above but in JSON format", @@ -473,7 +451,7 @@ static const char *help_msg_pif[] = { NULL }; -static const char *help_msg_po[] = { +static RCoreHelpMessage help_msg_po = { "Usage:","po[24aAdlmorsx]"," [hexpairs] @ addr[!bsize] (see also `poke`)", "po[24aAdlmorsx]","", "without hexpair values, clipboard is used", "po2"," [val]","2= 2 byte endian swap", @@ -490,14 +468,14 @@ static const char *help_msg_po[] = { NULL }; -static const char *help_msg_pq[] = { +static RCoreHelpMessage help_msg_pq = { "Usage:", "pq[?z] [len]", "generate QR code in ascii art", "pq", " 32", "print QR code with the current 32 bytes", "pqz", "", "print QR code with current string in current offset", NULL }; -static const char *help_msg_ps[] = { +static RCoreHelpMessage help_msg_ps = { "Usage:", "ps[abijqpsuwWxz+] [N]", "Print String", "ps", "", "print string", "ps+", "[j]", "print libc++ std::string (same-endian, ascii, zero-terminated)", @@ -516,7 +494,7 @@ static const char *help_msg_ps[] = { NULL }; -static const char *help_msg_pt[] = { +static RCoreHelpMessage help_msg_pt = { "Usage: pt", "[dn]", "print timestamps", "pt.", "", "print current time", "pt", "", "print UNIX time (32 bit `cfg.bigendian`) Since January 1, 1970", @@ -527,7 +505,7 @@ static const char *help_msg_pt[] = { NULL }; -static const char *help_msg_pv[] = { +static RCoreHelpMessage help_msg_pv = { "Usage: pv[1248z][j]", "", "Print value(s) given size and endian", "pv", "", "print bytes based on asm.bits", "pv1", "", "print 1 byte in memory", @@ -540,7 +518,7 @@ static const char *help_msg_pv[] = { NULL }; -static const char *help_msg_px[] = { +static RCoreHelpMessage help_msg_px = { "Usage:", "px[0afoswqWqQ][f]", " # Print heXadecimal", "px", "", "show hexdump", "px--", "[n]", "context hexdump (the hexdump version of pd--3)", @@ -573,7 +551,7 @@ static const char *help_msg_px[] = { NULL }; -const char *help_msg_pz[] = { +static RCoreHelpMessage help_msg_pz = { "Usage: pz [len]", "", "print zoomed blocks (filesize/N)", "e ", "zoom.maxsz", "max size of block", "e ", "zoom.from", "start address", @@ -590,7 +568,7 @@ const char *help_msg_pz[] = { NULL }; -const char *help_msg_pxA[] = { +static RCoreHelpMessage help_msg_pxA = { "Usage: pxA [len]", "", "show op analysis color map", "$$", "", "int/swi/trap/new", "+-*/", "", "math ops", @@ -610,6 +588,15 @@ const char *help_msg_pxA[] = { NULL }; +static RCoreHelpMessage help_msg_pg = { + "Usage: pg[-]", "[asm|hex]", "print (dis)assembled", + "pg", " [x y w h cmd]", "add a new gadget", + "pg", "", "print them all", + "pg", "*", "print the gadgets as r2 commands", + "pg-", "*", "remove all the gadgets", + NULL +}; + static const ut32 colormap[256] = { 0x000000, 0x560000, 0x640000, 0x750000, 0x870000, 0x9b0000, 0xb00000, 0xc60000, 0xdd0000, 0xf50000, 0xff0f0f, 0xff2828, 0xff4343, 0xff5e5e, 0xff7979, 0xfe9595, 0x4c1600, 0x561900, 0x641e00, 0x752300, 0x872800, 0x9b2e00, 0xb03400, 0xc63b00, 0xdd4200, 0xf54900, 0xff570f, 0xff6928, 0xff7b43, 0xff8e5e, 0xffa179, 0xfeb595, @@ -758,7 +745,7 @@ static void cmd_printmsg(RCore *core, const char *input) { } else if (!strncmp (input, "fln ", 2)) { R_LOG_TODO ("waiting for r2shell"); } else { - R_LOG_INFO ("Usage: print, println, printf, printfln"); + r_core_cmd_help_match (core, help_msg_pr, "print", true); } } @@ -1416,7 +1403,7 @@ static void cmd_print_fromage(RCore *core, const char *input, const ut8* data, i break; case 'B': // "pFB" if (input[1] == '?') { - eprintf ("Usage: pFB[j] - parse binary plist format, check 'b'lock size, pFBj for json output\n"); + r_core_cmd_help_match (core, help_msg_pF, "pFB", true); } else { PJ *pj = r_core_pj_new (core); if (size > 0) { @@ -1452,15 +1439,6 @@ R_API void r_core_gadget_free(RCoreGadget *g) { } } -static const char *help_msg_pg[] = { - "Usage: pg[-]", "[asm|hex]", "print (dis)assembled", - "pg", " [x y w h cmd]", "add a new gadget", - "pg", "", "print them all", - "pg", "*", "print the gadgets as r2 commands", - "pg-", "*", "remove all the gadgets", - NULL -}; - static void cmd_print_gadget(RCore *core, const char *_input) { if (*_input == '?') { // "pg?" r_core_cmd_help (core, help_msg_pg); @@ -1544,14 +1522,6 @@ static void cmd_print_gadget(RCore *core, const char *_input) { } } -static void cmd_pfo_help(RCore *core) { - const char *help[] = { - "Usage:", "pfo [format-file]", "# List all format definition files (fdf)", - NULL - }; - r_core_cmd_help (core, help); -} - static ut64 read_val(RBitmap *bm, int pos, int sz) { int i; ut64 n = 0; @@ -1771,7 +1741,8 @@ static void cmd_print_format(RCore *core, const char *_input, const ut8* block, if (val) { r_cons_printf ("%d\n", r_print_format_struct_size (core->print, val, mode, 0)); } else { - R_LOG_WARN ("Struct %s not defined. Use pfs.struct_name | pfs format", _input); + R_LOG_WARN ("Struct %s not defined", _input); + r_core_cmd_help_match (core, help_msg_pf, "pfs", true); } } else if (*_input == ' ') { while (*_input == ' ' && *_input != '\0') { @@ -1780,10 +1751,11 @@ static void cmd_print_format(RCore *core, const char *_input, const ut8* block, if (*_input) { r_cons_printf ("%d\n", r_print_format_struct_size (core->print, _input, mode, 0)); } else { - R_LOG_WARN ("Struct %s not defined. Use pfs.struct_name | pfs format", _input); + R_LOG_WARN ("Struct %s not defined", _input); + r_core_cmd_help_match (core, help_msg_pf, "pfs", true); } } else { - eprintf ("Usage: pfs.struct_name | pfs format\n"); + r_core_cmd_help_match (core, help_msg_pf, "pfs", true); } return; } @@ -1819,12 +1791,12 @@ static void cmd_print_format(RCore *core, const char *_input, const ut8* block, if (_input[2] == ' ') { r_core_cmd_print_binformat (core, r_str_trim_head_ro (_input + 2), PFB_ART); } else { - eprintf ("Usage: pfb [binfmt] [names...]\n"); + r_core_cmd_help_match (core, help_msg_pf, "pfb", true); } return; case 'o': // "pfo" if (_input[2] == '?') { - cmd_pfo_help (core); + r_core_cmd_help_match (core, help_msg_pf, "pfo", true); } else if (_input[2] == ' ') { const char *fname = r_str_trim_head_ro (_input + 3); char *tmp = r_str_newf (R_JOIN_2_PATHS (R2_SDB_FORMAT, "%s"), fname); @@ -2030,13 +2002,10 @@ static void cmd_print_format(RCore *core, const char *_input, const ut8* block, goto err_args; } - /* check if fmt is '\d+ \d+<...>', common mistake due to usage string*/ + /* check if fmt is '\d+ \d+<...>', common mistake due to usage string */ const char *arg1 = strtok (args, " "); if (arg1 && r_str_isnumber (arg1)) { - r_core_cmd_help (core, (const char *[]) { - "Usage:", "pf [0|cnt][format-string]", "", - NULL - }); + r_core_cmd_help_match (core, help_msg_pf, "pf", true); goto err_arg1; } r_print_format (core->print, core->offset, @@ -5268,7 +5237,6 @@ static bool cmd_pi(RCore *core, const char *input, int len, int l, ut8 *block) { } switch (ch) { case '?': - // r_cons_printf ("Usage: pi[defj] [num]\n"); r_core_cmd_help (core, help_msg_pi); break; case 'u': // "piu" disasm until given optype @@ -5632,7 +5600,7 @@ static int cmd_print(void *data, const char *input) { } } if (halp) { - eprintf ("Usage: pushd [dir]\n"); + r_core_cmd_help_match (core, help_msg_p, "pushd", true); r_core_return_value (core, 1); } return 0; @@ -5641,7 +5609,7 @@ static int cmd_print(void *data, const char *input) { bool all = strstr (input, "-a"); bool halp = strstr (input, "-h"); if (halp) { - R_LOG_ERROR ("Usage: popd [-a]"); + r_core_cmd_help_match (core, help_msg_p, "popd", true); r_core_return_value (core, 1); } else { bool suc = all @@ -5841,7 +5809,7 @@ static int cmd_print(void *data, const char *input) { } if (input[1] == 'e') { // "pae" if (input[2] == '?') { - r_cons_printf ("Usage: pae [asm] print ESIL expression of the given assembly expression\n"); + r_core_cmd_help_match (core, help_msg_pa, "pae", true); } else { int printed = 0; int bufsz; @@ -5871,7 +5839,7 @@ static int cmd_print(void *data, const char *input) { } } else if (input[1] == 'D') { // "paD" if (input[2] == '?') { - r_cons_printf ("Usage: paD [hex] print assembly expression from hexpairs and show hexpairs\n"); + r_core_cmd_help_match (core, help_msg_pa, "paD", true); } else { r_core_cmdf (core, "pdi@x:%s", input + 2); } @@ -5879,7 +5847,7 @@ static int cmd_print(void *data, const char *input) { switch (input[2]) { case 'e': // "pade" if (input[3] == '?') { - r_cons_printf ("Usage: pade [hex] print ESIL expression from hexpairs\n"); + r_core_cmd_help_match (core, help_msg_pa, "pade", true); } else { int printed = 0; int bufsz; @@ -5915,7 +5883,7 @@ static int cmd_print(void *data, const char *input) { r_core_cmd_help_match (core, help_msg_pa, "pad", false); break; default: - r_cons_printf ("Usage: pa[edD] [asm|hex] print (dis)assembled\n"); + r_core_cmd_help (core, help_msg_pa); break; } } else if (input[1] == '?') { @@ -5945,7 +5913,7 @@ static int cmd_print(void *data, const char *input) { break; case 'b': { // "pb" if (input[1] == '?') { - r_cons_printf ("Usage: p[bB] [len] ([skip]) ; see also pB and pxb\n"); + r_core_cmd_help_match (core, help_msg_p, "pb", true); } else if (l != 0) { int from, to; const int size = len * 8; @@ -5990,7 +5958,7 @@ static int cmd_print(void *data, const char *input) { break; case 'B': { // "pB" if (input[1] == '?') { - r_cons_printf ("Usage: p[bB] [len] bitstream of N bytes\n"); + r_core_cmd_help_match (core, help_msg_p, "pB", true); } else if (l != 0) { int size; char *buf; @@ -6037,8 +6005,7 @@ static int cmd_print(void *data, const char *input) { } break; case '?': // "pi?" - r_cons_printf ("Usage: p[iI][df] [len] print N instructions/bytes" - "(f=func) (see pi? and pdi)\n"); + r_core_cmd_help (core, help_msg_pi); break; default: if (l) { @@ -6184,21 +6151,23 @@ static int cmd_print(void *data, const char *input) { } else { r_core_disasm_pdi (core, l, 0, 0); } - pd_result = 0; + pd_result = false; } break; case 'a': // "pda" processed_cmd = true; if (input[2] == '?') { - r_core_cmd_help (core, help_msg_pda); - break; + r_core_cmd_help_match (core, help_msg_pd, "pda", false); + } else if (input[2] == 'j' && input[3] == '?') { + r_core_cmd_help_match (core, help_msg_pd, "pdaj", true); + } else { + r_core_print_disasm_all (core, core->offset, l, len, input[2]); + pd_result = true; } - r_core_print_disasm_all (core, core->offset, l, len, input[2]); - pd_result = true; break; case 'o': // "pdo" if (input[2] == '?') { - r_core_cmd_help (core, help_msg_pdo); + r_core_cmd_help_match (core, help_msg_pd, "pdo", true); return 0; } core_print_decompile (core, input + 2); @@ -6216,11 +6185,23 @@ static int cmd_print(void *data, const char *input) { }; int mode = R_MODE_PRINT; if (input[2] == 'j') { + if (input[3] == '?') { + r_core_cmd_help_match (core, help_msg_pde, "pdej", true); + return 0; + } mode = R_MODE_JSON; } else if (input[2] == 'q') { if (input[3] == 'q') { // "pdeqq" + if (input[4] == '?') { + r_core_cmd_help_match (core, help_msg_pde, "pdeqq", true); + return 0; + } mode = R_MODE_SIMPLEST; // Like pi } else { // "pdeq" + if (input[3] == '?') { + r_core_cmd_help_match (core, help_msg_pde, "pdeq", false); + return 0; + } mode = R_MODE_SIMPLE; // Like pdi } } @@ -6239,11 +6220,12 @@ static int cmd_print(void *data, const char *input) { case 'r': // "pdr" processed_cmd = true; if (input[2] == '?') { // "pdr?" - r_core_cmd_help (core, help_msg_pdr); + r_core_cmd_help_match (core, help_msg_pd, "pdr", false); pd_result = true; break; - }; - { + } else if (input[2] == '.' && input[3] == '?') { + r_core_cmd_help_match (core, help_msg_pd, "pdr.", true); + } else { RAnalFunction *f = r_anal_get_fcn_in (core->anal, core->offset, 0); // R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM); if (f) { @@ -6257,7 +6239,7 @@ static int cmd_print(void *data, const char *input) { case 'b': // "pdb" processed_cmd = true; if (input[2] == '?') { - r_cons_printf ("Usage: pdb[j] - disassemble basic block\n"); + r_core_cmd_help_match (core, help_msg_pd, "pdb", true); } else { RAnalBlock *b = r_anal_bb_from_offset (core->anal, core->offset); if (b) { @@ -6291,13 +6273,13 @@ static int cmd_print(void *data, const char *input) { } } break; - case 's': // "pds" and "pdsf" + case 's': // "pds" processed_cmd = true; if (input[2] == '?') { - r_core_cmd_help (core, help_msg_pds); + r_core_cmd_help_match (core, help_msg_pd, "pds", true); } else { if (input[2] && input[3] == '?') { - r_core_cmd_help (core, help_msg_pds); + r_core_cmd_help_match (core, help_msg_pd, "pds", true); } else { disasm_strings (core, input, NULL); } @@ -6306,7 +6288,7 @@ static int cmd_print(void *data, const char *input) { case 'f': // "pdf" processed_cmd = true; if (input[2] == '?') { - r_core_cmd_help (core, help_msg_pdf); + r_core_cmd_help_match (core, help_msg_pd, "pdf", true); } else if (input[2] == 's') { // "pdfs" ut64 oseek = core->offset; int oblock = core->blocksize; @@ -6394,7 +6376,7 @@ static int cmd_print(void *data, const char *input) { case 'p': // "pdp" processed_cmd = true; if (input[2] == '?') { - r_core_cmd_help (core, help_msg_pdp); + r_core_cmd_help_match (core, help_msg_pd, "pdp", true); pd_result = true; break; }; @@ -6845,15 +6827,7 @@ static int cmd_print(void *data, const char *input) { break; case 'm': // "pm" if (input[1] == '?') { - r_cons_printf ("Usage: pm [file|directory]\n" - "| r_magic will use given file/dir as reference\n" - "| output of those magic can contain expressions like:\n" - "| foo@0x40 # use 'foo' magic file on address 0x40\n" - "| @0x40 # use current magic file on address 0x40\n" - "| \\n # append newline\n" - "| e dir.magic # defaults to " R_JOIN_2_PATHS ("{R2_PREFIX}", R2_SDB_MAGIC) "\n" - "| /m # search for magic signatures\n" - ); + r_core_cmd_help (core, help_msg_pm); } else if (input[1] == 'j') { // "pmj" const char *filename = r_str_trim_head_ro (input + 2); PJ *pj = r_core_pj_new (core); @@ -6868,8 +6842,7 @@ static int cmd_print(void *data, const char *input) { break; case 'u': // "pu" if (input[1] == '?') { - r_cons_printf ("Usage: pu[w] [len] print N url" - "encoded bytes (w=wide)\n"); + r_core_cmd_help_match (core, help_msg_p, "pu", true); } else { if (l > 0) { r_print_string (core->print, core->offset, core->block, len, @@ -6939,14 +6912,16 @@ static int cmd_print(void *data, const char *input) { cmd_pCx (core, input + 2, "pc"); break; default: - eprintf ("Usage: pC[dDaAxwc] - column output for pxa, pxA, pxw, ..\n"); + r_core_cmd_help_match (core, help_msg_p, "pC", true); break; } break; case 'r': // "pr" switch (input[1]) { case 'i': // "pri" // color raw image - if (input[2] == 'n') { + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_pr, "pri", true); + } else if (input[2] == 'n') { cmd_printmsg (core, input + 4); } else if (input[2] == '1') { bitimage (core, 1); @@ -7707,8 +7682,7 @@ static int cmd_print(void *data, const char *input) { case '2': // "p2" if (l) { if (input[1] == '?') { - r_cons_printf ("Usage: p2 [number of bytes representing tiles]\n" - "NOTE: Only full tiles will be printed\n"); + r_core_cmd_help_match (core, help_msg_p, "p2", true); } else { RConsContext *c = core->cons->context; const char **colors = (const char *[]) { @@ -7862,8 +7836,7 @@ static int cmd_print(void *data, const char *input) { break; case 'k': // "pk" if (input[1] == '?') { - r_cons_printf ("Usage: pk [len] print key in randomart\n"); - r_cons_printf ("Usage: pkill [process-name]\n"); + r_core_cmd_help_match (core, help_msg_p, "pk", false); } else if (!strncmp (input, "kill", 4)) { RListIter *iter; RDebugPid *pid; @@ -7889,7 +7862,7 @@ static int cmd_print(void *data, const char *input) { break; case 'K': // "pK" if (input[1] == '?') { - r_cons_printf ("Usage: pK [len] print key in randomart mosaic\n"); + r_core_cmd_help_match (core, help_msg_p, "pK", true); } else if (l > 0) { len = len > core->blocksize? core->blocksize: len; int w, h; diff --git a/libr/core/cmd_quit.c b/libr/core/cmd_quit.c index 7bf6ca7430..fa07ca016a 100644 --- a/libr/core/cmd_quit.c +++ b/libr/core/cmd_quit.c @@ -2,7 +2,7 @@ #include "r_core.h" -static const char *help_msg_q[] = { +static RCoreHelpMessage help_msg_q = { "Usage:", "q[!][!] [retval]", "", "q","","quit program", "q!","","force quit (no questions)", diff --git a/libr/core/cmd_search.c b/libr/core/cmd_search.c index 5fcfa365df..197dbb60ac 100644 --- a/libr/core/cmd_search.c +++ b/libr/core/cmd_search.c @@ -12,7 +12,7 @@ static int cmd_search(void *data, const char *input); #define SM4_SEARCH_LENGTH 24 #define PRIVATE_KEY_SEARCH_LENGTH 11 -static const char *help_msg_search_wide_string[] = { +static RCoreHelpMessage help_msg_slash_wide_string = { "Usage: /w[ij]", "[str]", "Wide string search subcommands", "/w ", "foo", "search for wide string 'f\\0o\\0o\\0'", "/wj ", "foo", "search for wide string 'f\\0o\\0o\\0' (json output)", @@ -21,22 +21,7 @@ static const char *help_msg_search_wide_string[] = { NULL }; -static const char *help_msg_search_offset[] = { - "Usage: /o", "[n]", "Shows offset of 'n' Backward instruction", - NULL -}; - -static const char *help_msg_search_offset_without_anal[] = { - "Usage: /O", "[n]", "Shows offset of 'n' Backward instruction, but with a different fallback if anal cannot be used.", - NULL -}; - -static const char *help_msg_search_string_no_case[] = { - "Usage: /i", "[str]", "Search str string ignorning case", - NULL -}; - -static const char *help_msg_search_esil[] = { +static RCoreHelpMessage help_msg_slash_esil = { "/E", " [esil-expr]", "search offsets matching a specific esil expression", "/Ej", " [esil-expr]", "same as above but using the given magic file", "/E?", " ", "show this help", @@ -45,43 +30,43 @@ static const char *help_msg_search_esil[] = { NULL }; -static const char *help_msg_search_backward[] = { +static RCoreHelpMessage help_msg_slash_backward = { "Usage: /b[p]", "[value]", "Backward search subcommands", "/b", "[x] [str|414243]", "search in hexadecimal 'ABC' backwards starting in current address", "/bp", "", "search previous prelude and set hit.prelude flag", NULL }; -static const char *help_msg_search_forward[] = { +static RCoreHelpMessage help_msg_slash_forward = { "Usage: /f", " ", "search forwards, command modifier, followed by other command", NULL }; -static const char *help_msg_search_sections[] = { +static RCoreHelpMessage help_msg_slash_sections = { "Usage: /s[*]", "[threshold]", "finds sections by grouping blocks with similar entropy.", NULL }; -static const char *help_msg_search_delta[] = { +static RCoreHelpMessage help_msg_slash_delta = { "Usage: /d", "delta", "search for a deltified sequence of bytes.", NULL }; -static const char *help_msg_search_pattern[] = { +static RCoreHelpMessage help_msg_slash_pattern = { "Usage: /p[p]", " [pattern]", "Search for patterns or preludes", "/p", " [hexpattern]", "search in hexpairs pattern in search.in", "/pp", "", "search for function preludes", NULL }; -static const char *help_msg_search_ad[] = { +static RCoreHelpMessage help_msg_slash_ad = { "Usage: /ad", "[value]", "Backward search subcommands", "/ad", " rax", "search in disasm plaintext for matching instructions", "/adq", " rax", "quiet mode ideal for scripting", NULL }; -static const char *help_msg_slash_m[] = { +static RCoreHelpMessage help_msg_slash_magic = { "/m", "", "search for known magic patterns", "/m", " [file]", "same as above but using the given magic file", "/me", " ", "like ?e similar to IRC's /me", @@ -90,7 +75,7 @@ static const char *help_msg_slash_m[] = { NULL }; -static const char *help_msg_slash[] = { +static RCoreHelpMessage help_msg_slash = { "Usage:", "/[!bf] [arg]", "Search stuff (see 'e??search' for options)\n" "Use io.va for searching in non virtual addressing spaces", "/", " foo\\x00", "search for string 'foo\\0'", @@ -142,7 +127,7 @@ static const char *help_msg_slash[] = { NULL }; -static const char *help_msg_slash_at[] = { +static RCoreHelpMessage help_msg_slash_at = { "Usage:", "/at[flmj] [arg]", "Search for instructions matching type/family/mnemonic", "/at", " [optype,optype2]", "list instructions matching any of the comma separated optypes", "/atj", " [optype,optype2]", "same as above but using json as output", @@ -152,7 +137,7 @@ static const char *help_msg_slash_at[] = { NULL }; -static const char *help_msg_slash_a[] = { +static RCoreHelpMessage help_msg_slash_a = { "Usage:", "/a[?] [arg]", "Search for assembly instructions matching given properties", "/a", " push rbp", "assemble given instruction and search the bytes", "/a1", " [number]", "find valid assembly generated by changing only the nth byte", @@ -165,7 +150,7 @@ static const char *help_msg_slash_a[] = { "/ad/a", " instr", "search for every byte instruction that matches regexp 'instr'", "/ae", " esil", "search for esil expressions matching substring", "/af", "[l] family", "search for instruction of specific family (afl=list", - "/aF", " opstr", "find instructions matching given opstr only in analyzed code", + "/aF", "[d] opstr", "find instructions matching given opstr only in analyzed code", "/ai", "[j] 0x300 [0x500]", "find all the instructions using that immediate (in range)", "/al", "", "same as aoml, list all opcodes", "/am", " opcode", "search for specific instructions of specific mnemonic", @@ -176,7 +161,7 @@ static const char *help_msg_slash_a[] = { NULL }; -static const char *help_msg_slash_c[] = { +static RCoreHelpMessage help_msg_slash_c = { "Usage: /c", "", "Search for crypto materials", "/ca", "[?] [algo]", "search for keys expanded in memory (algo can be 'aes' or 'sm4')", "/cc", "[algo] [digest]", "find collisions (bruteforce block length values until given checksum is found)", @@ -187,13 +172,18 @@ static const char *help_msg_slash_c[] = { NULL }; -static const char *help_msg_slash_re[] = { - "Usage:", "/re $$", "search references using linear esil emulation", - "/re", " [addr]", "target address is specified as addr", - NULL, +static RCoreHelpMessage help_msg_slash_cc = { + "Usage: /cc[aAldpb]", "[algo] [digest]", "find collisions", + "/cca", " [algo] [digest]", "lowercase alphabet chars only", + "/ccA", " [algo] [digest]", "uppercase alphabet chars only", + "/ccl", " [algo] [digest]", "letters (lower + upper alphabet chars)", + "/ccd", " [algo] [digest]", "digits (only numbers)", + "/ccp", " [algo] [digest]", "printable (alpha + digit)", + "/ccb", " [algo] [digest]", "binary (any number is valid)", + NULL }; -static const char *help_msg_slash_r[] = { +static RCoreHelpMessage help_msg_slash_r = { "Usage:", "/r[acerwx] [address]", " search references to this specific address", "/r", " [addr]", "search references to this specific address", "/ra", "", "search all references", @@ -206,7 +196,7 @@ static const char *help_msg_slash_r[] = { NULL }; -static const char *help_msg_slash_R[] = { +static RCoreHelpMessage help_msg_slash_R = { "Usage: /R", "", "search for ROP gadgets", "/R", " [filter-by-string]", "show gadgets", "/R/", " [filter-by-regexp]", "show gadgets [regular expression]", @@ -218,7 +208,7 @@ static const char *help_msg_slash_R[] = { NULL }; -static const char *help_msg_slash_Rk[] = { +static RCoreHelpMessage help_msg_slash_Rk = { "Usage: /Rk", "", "query stored ROP gadgets", "/Rk", " [nop|mov|const|arithm|arithm_ct]", "show gadgets", "/Rkj", "", "json output", @@ -226,7 +216,7 @@ static const char *help_msg_slash_Rk[] = { NULL }; -static const char *help_msg_slash_x[] = { +static RCoreHelpMessage help_msg_slash_x = { "Usage:", "/x [hexpairs]:[binmask]", "search in memory", "/x ", "9090cd80", "search for those bytes", "/x ", "9090cd80:ffff7ff0", "search with binary mask", @@ -1779,7 +1769,7 @@ static void do_esil_search(RCore *core, struct search_parameters *param, const c input++; } if (input[1] != ' ') { // "/E?" - r_core_cmd_help (core, help_msg_search_esil); + r_core_cmd_help (core, help_msg_slash_esil); return; } const unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size"); @@ -2219,8 +2209,7 @@ static void do_ref_search(RCore *core, ut64 addr,ut64 from, ut64 to, struct sear static void cmd_search_aF(RCore *core, const char *input) { bool quiet = *input == 'd'; if (*input && *input != ' ' && *input != 'd') { - eprintf ("Usage: /aF mov ## search in instructions covered by basic blocks ('uses the pi command')\n"); - eprintf ("Usage: /aFd mov ## uses internal disasm api (15x faster than /aF), no flag subst\n"); + r_core_cmd_help_match (core, help_msg_slash_a, "aF", false); return; } RAnalFunction *fcn; @@ -2630,7 +2619,7 @@ static bool do_anal_search(RCore *core, struct search_parameters *param, const c return false; case 'F': // "/aF" cmd_search_aF (core, input + 1); - return true; + return false; break; case 'f': // "/af" case 's': // "/as" @@ -2908,7 +2897,7 @@ static void do_asm_search(RCore *core, struct search_parameters *param, const ch param->outmode = R_MODE_RADARE; break; case '?': - r_core_cmd_help (core, help_msg_search_ad); + r_core_cmd_help (core, help_msg_slash_ad); return; default: break; @@ -3794,7 +3783,7 @@ reread: goto reread; case 'b': // "/b" backward search if (*(++input) == '?') { - r_core_cmd_help (core, help_msg_search_backward); + r_core_cmd_help (core, help_msg_slash_backward); goto beach; } param_offset--; @@ -3814,7 +3803,7 @@ reread: goto reread; case 'o': { // "/o" print the offset of the Previous opcode if (input[1] == '?') { - r_core_cmd_help (core, help_msg_search_offset); + r_core_cmd_help_match (core, help_msg_slash, "/o", true); break; } ut64 addr, n = input[param_offset - 1] ? r_num_math (core->num, input + param_offset) : 1; @@ -3835,7 +3824,7 @@ reread: break; case 'O': { // "/O" alternative to "/o" if (input[1] == '?') { - r_core_cmd_help (core, help_msg_search_offset_without_anal); + r_core_cmd_help_match (core, help_msg_slash, "/O", true); break; } ut64 addr, n = input[param_offset - 1] ? r_num_math (core->num, input + param_offset) : 1; @@ -3951,7 +3940,7 @@ reread: r_core_seek (core, curseek, true); } } else { - r_core_cmd_help (core, help_msg_slash_re); + r_core_cmd_help_match (core, help_msg_slash_r, "/re", true); dosearch = false; } break; @@ -4150,13 +4139,7 @@ reread: char *space = strchr (input, ' '); const char *arg = space? r_str_trim_head_ro (space + 1): NULL; if (!arg || input[2] == '?') { - eprintf ("Usage: /cc[aAdlpb] [hashname] [hexpairhashvalue]\n"); - eprintf (" /cca - lowercase alphabet chars only\n"); - eprintf (" /ccA - uppercase alphabet chars only\n"); - eprintf (" /ccl - letters (lower + upper alphabet chars)\n"); - eprintf (" /ccd - digits (only numbers)\n"); - eprintf (" /ccp - printable (alpha + digit)\n"); - eprintf (" /ccb - binary (any number is valid)\n"); + r_core_cmd_help (core, help_msg_slash_cc); goto beach; } char *s = strdup (arg); @@ -4189,8 +4172,7 @@ reread: r_core_return_value (core, 1); } } else { - eprintf ("Usage: /cc [hashname] [hexpairhashvalue]\n"); - eprintf ("Usage: /CC to search ascii collisions\n"); + r_core_cmd_help (core, help_msg_slash_cc); } free (s); goto beach; @@ -4319,7 +4301,7 @@ reread: case 'm': // "/m" dosearch = false; if (input[1] == '?') { // "/me" - r_core_cmd_help (core, help_msg_slash_m); + r_core_cmd_help (core, help_msg_slash_magic); } else if (input[1] == 'b') { // "/mb" bool bin_verbose = r_config_get_i (core->config, "bin.verbose"); r_config_set_i (core->config, "bin.verbose", false); @@ -4403,15 +4385,19 @@ reread: pj_end (param.pj); } } else { - eprintf ("Usage: /m [file]\n"); + r_core_cmd_help (core, help_msg_slash_magic); } r_cons_clear_line (1); break; case 'p': // "/p" - if (input[1] == '?') { // "/pp" -- find next prelude - r_core_cmd_help (core, help_msg_search_pattern); + if (input[1] == '?') { // "/p" -- find next pattern + r_core_cmd_help (core, help_msg_slash_pattern); } else if (input[1] == 'p') { // "/pp" -- find next prelude - __core_cmd_search_backward_prelude (core, false, true); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_slash_pattern, "/pp", true); + } else { + __core_cmd_search_backward_prelude (core, false, true); + } } else if (input[param_offset - 1]) { int ps = atoi (input + param_offset); if (ps > 1) { @@ -4461,17 +4447,15 @@ reread: } } if (err) { - eprintf ("Usage: /V[1|2|4|8] [minval] [maxval]\n"); + r_core_cmd_help_match (core, help_msg_slash, "/V", true); } } dosearch = false; break; case 'v': // "/v" - if (input[1]) { - if (input[1] == '?') { - r_cons_print ("Usage: /v[1|2|4|8] [value]\n"); - break; - } + if (input[1] == '?') { + r_core_cmd_help_match (core, help_msg_slash, "/v", true); + break; } r_search_reset (core->search, R_SEARCH_KEYWORD); r_search_set_distance (core->search, (int) @@ -4487,7 +4471,7 @@ reread: bsize = sizeof (ut64) * len; v_buf = v_writebuf (core, nums, len, '8', bsize); } else { - eprintf ("Usage: /v8 value\n"); + r_core_cmd_help_match (core, help_msg_slash, "/v", true); } break; case '1': @@ -4495,7 +4479,7 @@ reread: bsize = sizeof (ut8) * len; v_buf = v_writebuf (core, nums, len, '1', bsize); } else { - eprintf ("Usage: /v1 value\n"); + r_core_cmd_help_match (core, help_msg_slash, "/v", true); } break; case '2': @@ -4503,7 +4487,7 @@ reread: bsize = sizeof (ut16) * len; v_buf = v_writebuf (core, nums, len, '2', bsize); } else { - eprintf ("Usage: /v2 value\n"); + r_core_cmd_help_match (core, help_msg_slash, "/v", true); } break; default: // default size @@ -4514,7 +4498,7 @@ reread: v_buf = v_writebuf (core, nums, len, '4', bsize); } } else { - eprintf ("Usage: /v4 value\n"); + r_core_cmd_help_match (core, help_msg_slash, "/v", true); } break; } @@ -4528,12 +4512,12 @@ reread: break; case 'w': // "/w" search wide string, includes ignorecase search functionality (/wi cmd)! if (input[1] == '?') { - r_core_cmd_help (core, help_msg_search_wide_string); + r_core_cmd_help (core, help_msg_slash_wide_string); break; } if (input[2]) { if (input[2] == '?') { // "/w?" - r_core_cmd_help (core, help_msg_search_wide_string); + r_core_cmd_help (core, help_msg_slash_wide_string); break; } if (input[1] == 'j' || input[2] == 'j') { // "/wj" @@ -4565,7 +4549,7 @@ reread: break; case 'i': // "/i" if (input[1] == '?') { - r_core_cmd_help (core, help_msg_search_string_no_case); + r_core_cmd_help_match (core, help_msg_slash, "/i", true); break; } if (input[param_offset - 1] != ' ') { @@ -4628,7 +4612,7 @@ reread: break; case 'e': // "/e" match regexp if (input[1] == '?') { - eprintf ("Usage: /e /foo/i or /e/foo/i\n"); + r_core_cmd_help_match (core, help_msg_slash, "/e", true); } else if (input[1]) { RSearchKeyword *kw; kw = r_search_keyword_new_regexp (input + 1, NULL); @@ -4655,7 +4639,7 @@ reread: goto beach; case 'd': // "/d" search delta key if (input[1] == '?') { - r_core_cmd_help (core, help_msg_search_delta); + r_core_cmd_help (core, help_msg_slash_delta); break; } if (input[1]) { @@ -4675,7 +4659,7 @@ reread: if (p) { *p++ = 0; if (*arg == '?') { - eprintf ("Usage: /h md5 [hash] [datalen]\n"); + r_core_cmd_help_match (core, help_msg_slash, "/h", true); } else { ut32 min = UT32_MAX; ut32 max = UT32_MAX; @@ -4699,7 +4683,7 @@ reread: break; case 'f': // "/f" forward search if (input[1] == '?') { - r_core_cmd_help (core, help_msg_search_forward); + r_core_cmd_help (core, help_msg_slash_forward); break; } if (core->offset) { @@ -4715,8 +4699,7 @@ reread: break; case 'g': // "/g" graph search if (input[1] == '?') { - r_cons_printf ("Usage: /g[g] [fromaddr] @ [toaddr]\n"); - r_cons_printf ("(find all graph paths A to B (/gg follow jumps, see search.count and anal.depth)"); + r_core_cmd_help_match (core, help_msg_slash, "/g", true); } else { ut64 addr = UT64_MAX; if (input[1]) { @@ -4785,7 +4768,7 @@ reread: r_str_argv_free (args); free (buf); } else { - eprintf ("Usage: /F[j] [file] ([offset] ([sz]))\n"); + r_core_cmd_help_match (core, help_msg_slash, "/F", true); } break; case 'x': // "/x" search hex @@ -4816,7 +4799,7 @@ reread: break; case 's': // "/s" if (input[1] == '?') { - r_core_cmd_help (core, help_msg_search_sections); + r_core_cmd_help (core, help_msg_slash_sections); break; } do_section_search (core, ¶m, input + 1); @@ -4856,7 +4839,7 @@ again: free (str); free (buf); } else { - eprintf ("Usage: /+ [string]\n"); + r_core_cmd_help_match (core, help_msg_slash, "/+", true); } break; case 'z': // "/z" search strings of min-max range @@ -4864,7 +4847,7 @@ again: char *p; ut32 min, max; if (!input[1]) { - eprintf ("Usage: /z min max\n"); + r_core_cmd_help_match (core, help_msg_slash, "/z", true); break; } const char *maxstr = NULL; @@ -4873,7 +4856,7 @@ again: maxstr = r_str_trim_head_ro (p + 1); max = r_num_math (core->num, maxstr); } else { - eprintf ("Usage: /z min max\n"); + r_core_cmd_help_match (core, help_msg_slash, "/z", true); break; } const char *minstr = r_str_trim_head_ro (input + 2); diff --git a/libr/core/cmd_seek.c b/libr/core/cmd_seek.c index a06d62fcee..678a011e01 100644 --- a/libr/core/cmd_seek.c +++ b/libr/core/cmd_seek.c @@ -4,7 +4,7 @@ static void __core_cmd_search_backward_prelude(RCore *core, bool doseek, bool forward); -static const char *help_msg_s[] = { +static RCoreHelpMessage help_msg_s = { "Usage: s", "", " # Help for the seek commands. See ?$? to see all variables", "s", "", "print current address", "s", " addr", "seek to address", @@ -18,7 +18,7 @@ static const char *help_msg_s[] = { "s+", " n", "seek n bytes forward", "s++", "[n]", "seek blocksize bytes forward (/=n)", "s[j*=!]", "", "list undo seek history (JSON, =list, *r2, !=names, s==)", - "s/", " DATA", "search for next occurrence of 'DATA'", + "s/", " DATA", "search for next occurrence of 'DATA' (see /?)", "s/x", " 9091", "search for next occurrence of \\x90\\x91", "sa", " [[+-]a] [asz]", "seek asz (or bsize) aligned to addr", "sb", "", "seek aligned to bb start", @@ -36,45 +36,46 @@ static const char *help_msg_s[] = { "sr", " PC", "seek to register (or register alias) value", "ss", "[?]", "seek silently (without adding an entry to the seek history)", // "sp [page] seek page N (page = block)", + "sort", " [file]", "sort the contents of the file", NULL }; -static const char *help_msg_sdot[] = { +static RCoreHelpMessage help_msg_sdot = { "Usage:", "s.", "Seek here or there (near seeks)", "s.", "", "seek here, same as 's $$'", "s..", "32a8", "seek to the same address but replacing the lower nibbles", NULL }; -static const char *help_msg_sh[] = { +static RCoreHelpMessage help_msg_sh = { "Usage:", "sh", "r2's posix shell compatible subset", "sh", "", "enters a posix shell subset repl (requires scr.interactive)", "sh", " [cmd]", "run the given line and update $?", NULL }; -static const char *help_msg_sC[] = { +static RCoreHelpMessage help_msg_sC = { "Usage:", "sC", "Comment grep", "sC", "*", "list all comments", "sC", " str", "seek to the first comment matching 'str'", NULL }; -static const char *help_msg_sn[] = { +static RCoreHelpMessage help_msg_sn = { "Usage:", "sn[p]", "", "sn", " [line]", "seek to next address", "snp", "", "seek to next prelude", NULL }; -static const char *help_msg_sp[] = { +static RCoreHelpMessage help_msg_sp = { "Usage:", "sp[p]", "", "sp", " [line]", "seek to previous address", "spp", "", "seek to previous prelude", NULL }; -static const char *help_msg_sl[] = { +static RCoreHelpMessage help_msg_sl = { "Usage:", "sl+ or sl- or slc", "", "sl", " [line]", "seek to absolute line", "sl", "[+-][line]", "seek to relative line", @@ -84,7 +85,7 @@ static const char *help_msg_sl[] = { NULL }; -static const char *help_msg_ss[] = { +static RCoreHelpMessage help_msg_ss = { "Usage: ss", "", " # Seek silently (not recorded in the seek history)", "s?", "", "works with all s subcommands", NULL @@ -248,7 +249,7 @@ static int cmd_sort(void *data, const char *input) { // "sort" } switch (*input) { case '?': // "sort?" - eprintf ("Usage: sort # sort the contents of the file\n"); + r_core_cmd_help_match (core, help_msg_s, "sort", true); break; default: // "ls" if (!arg) { @@ -325,10 +326,6 @@ static int cmd_seek_opcode_forward(RCore *core, int n) { } static void cmd_seek_opcode(RCore *core, const char *input) { - if (input[0] == '?') { - r_core_cmd_help_match (core, help_msg_s, "so", false); - return; - } if (!strcmp (input, "-")) { input = "-1"; } @@ -484,8 +481,7 @@ static int cmd_seek(void *data, const char *input) { r_config_set_i (core->config, "search.maxhits", saved_maxhits); break; case '?': - eprintf ("Usage: s/.. arg.\n"); - r_cons_printf ("/?\n"); + r_core_cmd_help_match (core, help_msg_s, "s/", false); break; default: R_LOG_ERROR ("unknown search subcommand"); @@ -759,10 +755,14 @@ static int cmd_seek(void *data, const char *input) { case 'r': if (input[2] == 't') { cmd_sort (core, input); + } else if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_s, "sort", true); } else { return -1; } break; + case '?': + r_core_cmd_help_match (core, help_msg_s, "so", false); case ' ': case '\0': case '+': @@ -843,7 +843,7 @@ static int cmd_seek(void *data, const char *input) { } r_cons_sleep_end (bed); } else { - eprintf ("Usage: sleep [seconds]\n"); + r_core_cmd_help_match (core, help_msg_sl, "sleep", true); } } break; diff --git a/libr/core/cmd_type.c b/libr/core/cmd_type.c index dbc286197e..f381169fa8 100644 --- a/libr/core/cmd_type.c +++ b/libr/core/cmd_type.c @@ -2,69 +2,59 @@ #include -static const char *help_msg_t[] = { - "Usage: t", "", "# cparse types commands", +static RCoreHelpMessage help_msg_t = { + "Usage: t", "", "Parse, manage, and print C types", "t", "", "list all loaded types", - "tj", "", "List all loaded types as json", + "tj", "", "list all loaded types as json", "t", " ", "show type in 'pf' syntax", "t*", "", "list types info in r2 commands", - "t-", " ", "delete types by its name", + "t-", " ", "delete type by name", "t-*", "", "remove all types", - "tail", " [filename]", "output the last part of files", - "tac", " [filename]", "the infamous reverse cat command", - "tc", " [type.name]", "list all/given types in C output format", + "tail", "([n]) [file]", "output the last n lines of a file (default n=5)", + "tac", " [file]", "the infamous reverse cat command", + "tc", "[?] [type.name]", "list all/given types in C output format", + "td", " ", "load types from string (quote the whole command: \"td ...\")", "te", "[?]", "list all loaded enums", - "td", "[?] ", "load types from string", - "tf", "", "list all loaded functions signatures", + "tf", "[?]", "list all loaded functions signatures", "tk", " ", "perform sdb query", "tl", "[?]", "show/Link type to an address", "tn", "[?] [-][addr]", "manage noreturn function attributes and marks", - "to", " -", "open cfg.editor to load types", - "to", " ", "load types from C header file", - "toe", " [type.name]", "open cfg.editor to edit types", - "tos", " ", "load types from parsed Sdb database", - "touch", " ", "create or update timestamp in file", - "tp", " [addr|varname]", "cast data at
to and print it (XXX: type can contain spaces)", - "tpv", " @ [value]", "show offset formatted for given type", - "tpx", " ", "show value for type with specified byte sequence (XXX: type can contain spaces)", + "to", "[?] ", "load types from C header file", + "tp", "[?] [addr|varname]", "cast data at
to and print it (XXX: type can contain spaces)", "ts", "[?]", "print loaded struct types", - "tu", "[?]", "print loaded union types", - "tx", "[f?]", "type xrefs", "tt", "[?]", "list all loaded typedefs", + "tu", "[?]", "print loaded union types", + "tx", "[?]", "type xrefs", NULL }; -static const char *help_msg_tx[] = { - "Usage: tx", "[flg] [...]", "", +static RCoreHelpMessage help_msg_tx = { + "Usage: tx[.tflg]", "[...]", "Function types", + "tx", "", "list functions and the types they use", "tx.", "", "same as txf", + "tx", " int32_t", "list functions names using this type", + "txt", " int32_t", "same as 'tx type'", "txf", " ([addr])", "list all types used in the current or given function (same as tx.)", "txl","","list all types used by any function", "txg", "", "render the type xrefs graph (usage .txg;aggv)", - "tx", " int32_t", "list functions names using this type", - "txt", " int32_t", "same as 'tx type'", - "tx", "", "list functions and the types they use", NULL }; -static const char *help_msg_tcc[] = { - "Usage: tcc", "[-name]", "# type function calling conventions (see also afc? and arcc)", - "tcc", "", "list all calling convcentions", - "tcc", " r0 pascal(r0,r1,r2)", "define signature for pascall cc (see also arcc)", - "tcc", "-pascal", "remove the pascal cc", - "tcc-*", "", "unregister all the calling conventions", - "tcck", "", "list calling conventions in k=v", +static RCoreHelpMessage help_msg_tcc = { + "Usage: tcc", "[-name]", "Type function calling conventions (see also afc? and arcc)", + "tcc", "", "list all calling conventions", + "tcc*", "", "list calling conventions as r2 commands", + "tcck", "", "list calling conventions in k=v format", "tccl", "", "list cc signatures (return ccname (arg0, arg1, ..) err;)", "tccj", "", "list them in JSON", - "tcc*", "", "list them as r2 commands", + "tcc ", " ([args]) ([err])", "define function cc", + "tcc ", "r0 pascal(r0,r1,r2)", "define signature for pascal cc (see also arcc)", + "tcc-", "", "unregister calling convention by name", + "tcc-*", "", "unregister all calling conventions", NULL }; -static const char *help_msg_t_minus[] = { - "Usage: t-", " ", "Delete type by its name", - NULL -}; - -static const char *help_msg_tf[] = { +static RCoreHelpMessage help_msg_tf = { "Usage: tf[...]", "", "", "tf", "", "list all function definitions loaded", "tf", " ", "show function signature", @@ -75,65 +65,60 @@ static const char *help_msg_tf[] = { NULL }; -static const char *help_msg_to[] = { +static RCoreHelpMessage help_msg_to = { "Usage: to[...]", "", "", "to", " -", "open cfg.editor to load types", "to", " ", "load types from C header file", "tos", " ", "load types from parsed Sdb database", + "toe", " [type.name]", "open cfg.editor to edit types", + "tos", " ", "load types from parsed Sdb database", "touch", " ", "create or update timestamp in file", NULL }; -static const char *help_msg_tp[] = { - "Usage: tp[...]", "", "", +static RCoreHelpMessage help_msg_tp = { + "Usage: tp[vx]", " [...]", "Print type", "tp", " [addr|varname]", "cast data at
to and print it (XXX: type can contain spaces)", - "tpv", " @ [value]", "show offset formatted for given type", + "tpv", " [@addr]", "show offset formatted for given type", "tpx", " ", "show value for type with specified byte sequence (XXX: type can contain spaces)", NULL }; -static const char *help_msg_tc[] = { - "Usage: tc[...]", " [cctype]", "", - "tc", " [type.name]", "list all/given loaded types in C output format with newlines", +static RCoreHelpMessage help_msg_tc = { + "Usage: tc[...]", " [type]", "Print loaded types", + "tc", "", "list all loaded types in C output format with newlines", + "tc", " [type.name]", "list given loaded type in C output format with newlines", "tcd", "", "list all loaded types in C output format without newlines", - "tcc", "?", "manage calling conventions types", - "tc?", "", "show this help", + "tcc", "[?]", "manage calling convention types", NULL }; -static const char *help_msg_td[] = { - "Usage:", "\"td [...]\"", "", - "td", "[string]", "load types from string", - NULL -}; - -static const char *help_msg_te[] = { - "Usage: te[...]", "", "", +static RCoreHelpMessage help_msg_te = { + "Usage: te[...]", "", "Type enum commands", "te", "", "list all loaded enums", "te", " ", "print all values of enum for given name", + "te", " ", "show name for given enum number", "te-", "", "delete enum type definition", "tej", "", "list all loaded enums in json", "tej", " ", "show enum in json", - "te", " ", "show name for given enum number", "teb", " ", "show matching enum bitfield for given name", - "tec", "", "list all/given loaded enums in C output format with newlines", + "tec", "", "list all loaded enums in C output format with newlines", + "tec", " ", "list given loaded enums in C output format with newlines", "ted", "", "list all loaded enums in C output format without newlines", - "te?", "", "show this help", NULL }; -static const char *help_msg_tt[] = { - "Usage: tt[...]", "", "", +static RCoreHelpMessage help_msg_tt = { + "Usage: tt[...]", "", "Type typedef commands", "tt", "", "list all loaded typedefs", "tt", " ", "show name for given type alias", "ttj", "", "show typename and type alias in json", "ttc", "", "show typename and type alias in C output format", - "tt?", "", "show this help", NULL }; -static const char *help_msg_tl[] = { - "Usage: tl[...]", "[typename] [[=] address]", "# Type link commands", +static RCoreHelpMessage help_msg_tl = { + "Usage: tl[...]", "[typename] [[=] address]", "Type link commands", "tl", "", "list all links.", "tll", "", "list all links in readable format.", "tllj", "", "list all links in readable JSON format.", @@ -147,7 +132,7 @@ static const char *help_msg_tl[] = { NULL }; -static const char *help_msg_tn[] = { +static RCoreHelpMessage help_msg_tn = { "Usage:", "tn [-][0xaddr|symname]", " manage no-return marks", "tn[a]", " 0x3000", "stop function analysis if call/jmp to this address", "tn[n]", " sym.imp.exit", "same as above but for flag/fcn names", @@ -158,7 +143,7 @@ static const char *help_msg_tn[] = { NULL }; -static const char *help_msg_ts[] = { +static RCoreHelpMessage help_msg_ts = { "Usage: ts[...]", " [type]", "", "ts", "", "list all loaded structs", "ts", " [type]", "show pf format string for given struct", @@ -170,11 +155,10 @@ static const char *help_msg_ts[] = { "tsc", "", "list all/given loaded structs in C output format with newlines", "tsd", "", "list all loaded structs in C output format without newlines", "tss", " [type]", "display size of struct", - "ts?", "", "show this help", NULL }; -static const char *help_msg_tu[] = { +static RCoreHelpMessage help_msg_tu = { "Usage: tu[...]", "", "", "tu", "", "list all loaded unions", "tu", " [type]", "show pf format string for given union", @@ -184,14 +168,9 @@ static const char *help_msg_tu[] = { "tu*", " [type]", "show pf. format string for given union", "tuc", "", "list all/given loaded unions in C output format with newlines", "tud", "", "list all loaded unions in C output format without newlines", - "tu?", "", "show this help", NULL }; -static void show_help(RCore *core) { - r_core_cmd_help (core, help_msg_t); -} - static bool cc_cb(void *p, const char *k, const char *v) { if (!strcmp (v, "cc")) { RList *list = (RList*)p; @@ -257,26 +236,33 @@ static void cmd_tcc(RCore *core, const char *input) { break; case '-': if (input[1] == '*') { - sdb_reset (core->anal->sdb_cc); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_tcc, "tcc-*", true); + } else { + sdb_reset (core->anal->sdb_cc); + } + } else if (input[1] == '?') { + r_core_cmd_help_match (core, help_msg_tcc, "tcc-", false); } else { r_anal_cc_del (core->anal, r_str_trim_head_ro (input + 1)); } break; - case 0: - cmd_afcl (core, ""); - break; + case '\0': case 'l': - cmd_afcl (core, "l"); - break; case 'j': - cmd_afcl (core, "j"); - break; - break; case '*': - cmd_afcl (core, "*"); + if (*input && input[1] == '?') { + r_core_cmd_help_match_spec (core, help_msg_tcc, "tcc", *input, true); + } else { + cmd_afcl (core, input); + } break; case 'k': - cmd_afck (core, NULL); + if (input[1] == '?') { + r_core_cmd_help_match (core, help_msg_tcc, "tcck", true); + } else { + cmd_afck (core, NULL); + } break; case ' ': if (strchr (input, '(')) { @@ -334,6 +320,7 @@ static void showFormat(RCore *core, const char *name, int mode) { } static int cmd_tac(void *data, const char *_input) { // "tac" + RCore *core = (RCore *) data; char *input = strdup (_input); char *arg = strchr (input, ' '); if (arg) { @@ -341,21 +328,21 @@ static int cmd_tac(void *data, const char *_input) { // "tac" } switch (*input) { case '?': // "tac?" - eprintf ("Usage: tac [file]\n"); + r_core_cmd_help_match (core, help_msg_t, "tac", true); break; default: // "tac" if (R_STR_ISNOTEMPTY (arg)) { - char *data = r_file_slurp (arg, NULL); - RList *lines = r_str_split_list (data, "\n", 0); + char *filedata = r_file_slurp (arg, NULL); + RList *lines = r_str_split_list (filedata, "\n", 0); RListIter *iter; char *line; r_list_foreach_prev (lines, iter, line) { r_cons_printf ("%s\n", line); } r_list_free (lines); - free (data); + free (filedata); } else { - eprintf ("Usage: tac [file]\n"); + r_core_cmd_help_match (core, help_msg_t, "tac", true); } break; } @@ -380,7 +367,7 @@ static int cmd_tail(void *data, const char *_input) { // "tail" } switch (*input) { case '?': // "tail?" - eprintf ("Usage: tail [file] # to list last n lines in file\n"); + r_core_cmd_help_match (core, help_msg_t, "tail", true); break; default: // "tail" if (!arg) { @@ -1129,12 +1116,16 @@ static int cmd_type(void *data, const char *input) { break; } case 'k': // "tk" - res = (input[1] == ' ') - ? sdb_querys (TDB, NULL, -1, input + 2) - : sdb_querys (TDB, NULL, -1, "*"); - if (res) { - r_cons_print (res); - free (res); + if (input[1] == '?') { + r_core_cmd_help_match (core, help_msg_t, "tk", true); + } else { + res = (input[1] == ' ') + ? sdb_querys (TDB, NULL, -1, input + 2) + : sdb_querys (TDB, NULL, -1, "*"); + if (res) { + r_cons_print (res); + free (res); + } } break; case 'c': // "tc" @@ -1173,7 +1164,11 @@ static int cmd_type(void *data, const char *input) { r_core_cmd0 (core, "tfc;tuc;tsc;ttc;tec"); break; case 'd': // "tcd" - r_core_cmd0 (core, "tud;tsd;ttc;ted"); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_tc, "tcd", true); + } else { + r_core_cmd0 (core, "tud;tsd;ttc;ted"); + } break; default: r_core_cmd_help (core, help_msg_tc); @@ -1241,7 +1236,7 @@ static int cmd_type(void *data, const char *input) { if (member_name) { *member_name++ = 0; } - if (name && (r_type_kind (TDB, name) != R_TYPE_ENUM)) { + if (R_STR_ISNOTEMPTY (name) && (r_type_kind (TDB, name) != R_TYPE_ENUM)) { R_LOG_ERROR ("%s is not an enum", name); free (name); break; @@ -1251,7 +1246,7 @@ static int cmd_type(void *data, const char *input) { r_core_cmdf (core, "t-%s", r_str_trim_head_ro (input + 2)); break; case 'j': // "tej" - if (input[2] == 0) { // "tej" + if (input[2] == '\0') { // "tej" char *name = NULL; SdbKv *kv; SdbListIter *iter; @@ -1259,25 +1254,24 @@ static int cmd_type(void *data, const char *input) { PJ *pj = pj_new (); pj_o (pj); ls_foreach (l, iter, kv) { - if (!strcmp (sdbkv_value (kv), "enum")) { - if (!name || strcmp (sdbkv_value (kv), name)) { - free (name); - name = strdup (sdbkv_key (kv)); - pj_k (pj, name); - { - RList *list = r_type_get_enum (TDB, name); - if (list && !r_list_empty (list)) { - pj_o (pj); - RListIter *iter; - RTypeEnum *member; - r_list_foreach (list, iter, member) { - pj_kn (pj, member->name, r_num_math (NULL, member->val)); - } - pj_end (pj); - } - r_list_free (list); + if (!strcmp (sdbkv_value (kv), "enum") + && (!name || strcmp (sdbkv_value (kv), name))) { + RList *list; + free (name); + name = strdup (sdbkv_key (kv)); + pj_k (pj, name); + list = r_type_get_enum (TDB, name); + if (!r_list_empty (list)) { + RListIter *iter; + RTypeEnum *member; + pj_o (pj); + r_list_foreach (list, iter, member) { + pj_kn (pj, member->name, + r_num_math (NULL, member->val)); } + pj_end (pj); } + r_list_free (list); } } pj_end (pj); @@ -1285,6 +1279,8 @@ static int cmd_type(void *data, const char *input) { pj_free (pj); free (name); ls_free (l); + } else if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_te, "tej", false); } else { // "tej ENUM" RListIter *iter; PJ *pj = pj_new (); @@ -1295,7 +1291,7 @@ static int cmd_type(void *data, const char *input) { // NEVER REACHED } else { RList *list = r_type_get_enum (TDB, name); - if (list && !r_list_empty (list)) { + if (!r_list_empty (list)) { pj_ks (pj, "name", name); pj_k (pj, "values"); pj_o (pj); @@ -1312,15 +1308,27 @@ static int cmd_type(void *data, const char *input) { } break; case 'b': // "teb" - res = r_type_enum_member (TDB, name, member_name, 0); + if (R_STR_ISEMPTY (name) || input[2] == '?') { + r_core_cmd_help_match (core, help_msg_te, "teb", true); + } else { + res = r_type_enum_member (TDB, name, member_name, 0); + } break; case 'c': // "tec" - print_enum_in_c_format(TDB, r_str_trim_head_ro (input + 2), true); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_te, "tec", true); + } else { + print_enum_in_c_format (TDB, r_str_trim_head_ro (input + 2), true); + } break; - case 'd': - print_enum_in_c_format(TDB, r_str_trim_head_ro (input + 2), false); + case 'd': // "ted" + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_te, "ted", true); + } else { + print_enum_in_c_format (TDB, r_str_trim_head_ro (input + 2), false); + } break; - case ' ': + case ' ': // "te " if (member_name) { res = r_type_enum_member (TDB, name, NULL, r_num_math (core->num, member_name)); } else { @@ -1382,8 +1390,12 @@ static int cmd_type(void *data, const char *input) { // t* - list all types in 'pf' syntax case 'j': // "tj" case '*': // "t*" - case 0: // "t" - typesList (core, input[0]); + case '\0': // "t" + if (input[0] && input[1] == '?') { + r_core_cmd_help_match_spec (core, help_msg_t, "t", input[0], true); + } else { + typesList (core, input[0]); + } break; case 'o': // "to" if (input[1] == '?') { @@ -1435,7 +1447,7 @@ static int cmd_type(void *data, const char *input) { if (arg) { r_file_touch (arg + 1); } else { - eprintf ("Usage: ot|touch [filename]\n"); + r_core_cmd_help_match (core, help_msg_to, "touch", true); } } else if (input[1] == 's') { const char *dbpath = input + 3; @@ -1473,9 +1485,7 @@ static int cmd_type(void *data, const char *input) { case 'd': // "td" if (input[1] == '?') { // TODO #7967 help refactor: move to detail - r_core_cmd_help (core, help_msg_td); - r_cons_printf ("Note: The td command should be put between double quotes\n" - "Example: \"td struct foo {int bar;int cow;};\"\n"); + r_core_cmd_help_match (core, help_msg_t, "td", true); } else if (input[1] == ' ') { char *tmp = r_str_newf ("%s;", input + 2); if (!tmp) { @@ -1595,11 +1605,11 @@ static int cmd_type(void *data, const char *input) { if (input[2] == 'l') { cmd_tail (core, input); } else { - eprintf ("Usage: tail [number] [file]\n"); + r_core_cmd_help_match (core, help_msg_t, "tail", true); } break; default: - R_LOG_WARN ("`ta` command is deprecated. Use \"aht\" instead"); + r_core_cmd_help_match (core, help_msg_t, "ta", false); break; } break; @@ -1702,7 +1712,7 @@ static int cmd_type(void *data, const char *input) { ut64 val = core->offset; r_core_cmdf (core, "pf %s @v:0x%08" PFMT64x, fmt, val); } else { - eprintf ("Usage: tpv [type] @ [value]\n"); + r_core_cmd_help_match (core, help_msg_tp, "tpv", true); } } else if (input[1] == ' ' || input[1] == 'x' || !input[1]) { char *tmp = strdup (input); @@ -1767,9 +1777,13 @@ static int cmd_type(void *data, const char *input) { break; case '-': // "t-" if (input[1] == '?') { - r_core_cmd_help (core, help_msg_t_minus); + r_core_cmd_help_match (core, help_msg_t, "t-", false); } else if (input[1] == '*') { - sdb_reset (TDB); + if (input[2] == '?') { + r_core_cmd_help_match (core, help_msg_t, "t-*", true); + } else { + sdb_reset (TDB); + } } else { const char *name = r_str_trim_head_ro (input + 1); if (*name) { @@ -1911,7 +1925,7 @@ static int cmd_type(void *data, const char *input) { } default: case '?': - show_help (core); + r_core_cmd_help (core, help_msg_t); break; } return true; diff --git a/libr/core/cmd_write.c b/libr/core/cmd_write.c index a038db9a64..818fabc913 100644 --- a/libr/core/cmd_write.c +++ b/libr/core/cmd_write.c @@ -2,11 +2,11 @@ #include -static const char *help_msg_w[] = { +static RCoreHelpMessage help_msg_w = { "Usage:","w[x] [str] [", "extend the underlying file inserting NUM null bytes at current offset", "weN", " ", "extend current file and insert bytes at address", @@ -89,7 +89,7 @@ static const char *help_msg_we[] = { NULL }; -static const char *help_msg_wo[] = { +static RCoreHelpMessage help_msg_wo = { "Usage:","wo[asmdxoArl24]"," [hexpairs] @ addr[!bsize] write operation in current block", "wo2", "", "2= 2 byte endian swap (word)", "wo4", "", "4= 4 byte endian swap (dword)", @@ -97,7 +97,7 @@ static const char *help_msg_wo[] = { "woa", " [hexpair]", "+= addition (f.ex: woa 0102)", "woA", " [hexpair]", "&= and", "wod", " [hexpair]", "/= divide", - "woD", "[algo] [key] [IV]", "decrypt current block with given algo and key", + "woD", " [algo] [key] [IV]", "decrypt current block with given algo and key", "woE", " [algo] [key] [IV]", "encrypt current block with given algo and key", "woe", " [from to] [step] [wsz=1]",".. create sequence", "woi", "", "inverse bytes in current block", @@ -113,7 +113,7 @@ static const char *help_msg_wo[] = { NULL }; -static const char *help_msg_wop[] = { +static RCoreHelpMessage help_msg_wop = { "Usage:","wop[DO]"," len @ addr | value", "wopD"," len [@ addr]","write a De Bruijn Pattern of length 'len' at address 'addr'", "wopD*"," len [@ addr]","show wx command that creates a debruijn pattern of a specific length", @@ -122,7 +122,7 @@ static const char *help_msg_wop[] = { }; // TODO -static const char *help_msg_wp[] = { +static RCoreHelpMessage help_msg_wp = { "Usage:", "wp", "[-|r2patch-file]", "^#", "", "comments", ".", "", "execute command", @@ -135,7 +135,7 @@ static const char *help_msg_wp[] = { NULL }; -static const char *help_msg_wt[] = { +static RCoreHelpMessage help_msg_wt = { "Usage:", "wt[afs] [filename] [size]", " Write current block or [size] bytes from offset to file", "wta", " [filename]", "append to 'filename'", "wtf", " [filename] [size]", "write to file (see also 'wxf' and 'wf?')", @@ -146,7 +146,7 @@ static const char *help_msg_wt[] = { NULL }; -static const char *help_msg_wf[] = { +static RCoreHelpMessage help_msg_wf = { "Usage:", "wf[fs] [-|args ..]", " Write from (file, swap, offset)", "wf", " 10 20", "write 20 bytes from offset 10 into current seek", "wff", " file [len]", "write contents of file into current offset", @@ -155,7 +155,7 @@ static const char *help_msg_wf[] = { NULL }; -static const char *help_msg_wv[] = { +static RCoreHelpMessage help_msg_wv = { "Usage:", "wv[size] [value]", " Write value of given size", "wv", " 0x834002", "write dword with this value", "wv1", " 234", "write one byte with this value", @@ -170,7 +170,7 @@ static const char *help_msg_wv[] = { NULL }; -static const char *help_msg_wx[] = { +static RCoreHelpMessage help_msg_wx = { "Usage:", "wx[f] [arg]", "", "wx", " 3.", "write the left nibble of the current byte", "wx", " .5", "write the right nibble of the current byte", @@ -332,9 +332,7 @@ static int cmd_wo(void *data, const char *input) { case '4': // "wo4" case '8': // "wo8" if (input[1] == '?') { // parse val from arg - char s[8]; - snprintf (s, sizeof (s), "wo%c", input[0]); - r_core_cmd_help_match (core, help_msg_wo, s, true); + r_core_cmd_help_match_spec (core, help_msg_wo, "wo", input[0], true); } else if (input[1]) { // parse val from arg r_core_write_op (core, r_str_trim_head_ro (input + 1), input[0]); } else { // use clipboard instead of val @@ -368,11 +366,11 @@ static int cmd_wo(void *data, const char *input) { } } algo = args; - if (algo && *algo && key) { + if (R_STR_ISNOTEMPTY (algo) && key) { encrypt_or_decrypt_block (core, algo, key, direction, iv); } else { - eprintf ("Usage: wo%c [algo] [key] [IV]\n", ((!direction)?'E':'D')); r_crypto_list (core->crypto, r_cons_printf, 0); + r_core_cmd_help_match_spec (core, help_msg_wo, "wo", input[0], true); } free (args); } @@ -876,7 +874,7 @@ static int w_incdec_handler(void *data, const char *input, int inc) { cmd_write_inc (core, inc, -num); break; default: - eprintf ("Usage: w[1248][+-][num] # inc/dec byte/word/..\n"); + r_core_cmd_help_match (core, help_msg_w, "w", true); } return 0; } @@ -957,7 +955,7 @@ static int cmd_w6(void *data, const char *input) { r_core_block_read (core); free (buf); } else { - eprintf ("Usage: w6[d|e|x] base64/string/hex\n"); + r_core_cmd_help_match (core, help_msg_w, "w6", true); } return 0; } @@ -1226,7 +1224,7 @@ static int cmd_wr(void *data, const char *input) { } #if 0 -static const char *help_msg_wA[] = { +static RCoreHelpMessage help_msg_wA = { "Usage:", " wA", "[type] [value]", "Types", "", "", "r", "", "raw write value", @@ -1259,7 +1257,7 @@ static int cmd_wA(void *data, const char *input) { eprintf ("r_asm_modify = %d\n", len); } } else { - eprintf ("Usage: wA [type] [value]\n"); + r_core_cmd_help_match (core, help_msg_w, "wA", true); } break; case '?': @@ -1363,7 +1361,7 @@ static int cmd_wc(void *data, const char *input) { if (input[1] == ' ') { cmd_wcf (core, r_str_trim_head_ro (input + 1)); } else { - eprintf ("Usage: wcf [file]\n"); + r_core_cmd_help_match (core, help_msg_wc, "wcf", true); } break; case '*': // "wc*" @@ -2162,11 +2160,11 @@ static int cmd_wd(void *data, const char *input) { free (data); } } else { - eprintf ("See wd?\n"); + r_core_cmd_help_match (core, help_msg_w, "wd", true); } free (inp); } else { - eprintf ("Usage: wd [source-offset] [length] @ [dest-offset]\n"); + r_core_cmd_help_match (core, help_msg_w, "wd", true); } return 0; } diff --git a/libr/core/cmd_zign.c b/libr/core/cmd_zign.c index 30286b17f0..61959c533b 100644 --- a/libr/core/cmd_zign.c +++ b/libr/core/cmd_zign.c @@ -2,7 +2,7 @@ #include -static const char *help_msg_z[] = { +static RCoreHelpMessage help_msg_z = { "Usage:", "z[*j-aof/cs] [args] ", "# Manage zignatures", "z", "", "show zignatures", "z.", "", "find matching zignatures in current offset", @@ -25,14 +25,14 @@ static const char *help_msg_z[] = { NULL }; -static const char *help_msg_zb[] = { +static RCoreHelpMessage help_msg_zb = { "Usage:", "zb[r?] [args]", "# search for closest matching signatures", "zb ", "[n]", "find n closest matching zignatures to function at current offset", "zbr ", "zigname [n]", "search for n most similar functions to zigname", NULL }; -static const char *help_msg_z_slash[] = { +static RCoreHelpMessage help_msg_z_slash = { "Usage:", "z/[f*] ", "# Search signatures (see 'e?search' for options)", "z/ ", "", "search zignatures on range and flag matches", "z/f ", "", "zignature search on known functions", @@ -40,7 +40,7 @@ static const char *help_msg_z_slash[] = { NULL }; -static const char *help_msg_za[] = { +static RCoreHelpMessage help_msg_za = { "Usage:", "za[fFM?] [args] ", "# Add zignature", "za ", "zigname type params", "add zignature", "zac ", "", "Compute collisions between signatures", @@ -51,7 +51,7 @@ static const char *help_msg_za[] = { NULL }; -static const char *help_msg_zf[] = { +static RCoreHelpMessage help_msg_zf = { "Usage:", "zf[dsz] filename ", "# Manage FLIRT signatures", "zfd ", "filename", "open FLIRT file and dump", "zfs ", "filename", "open FLIRT file and scan", @@ -60,7 +60,7 @@ static const char *help_msg_zf[] = { NULL }; -static const char *help_msg_zo[] = { +static RCoreHelpMessage help_msg_zo = { "Usage:", "zo[zs] filename ", "# Manage zignature files (see dir.zigns)", "zo ", "filename", "load zinatures from sdb file", "zoz ", "filename", "load zinatures from gzipped sdb file", @@ -68,7 +68,7 @@ static const char *help_msg_zo[] = { NULL }; -static const char *help_msg_zs[] = { +static RCoreHelpMessage help_msg_zs = { "Usage:", "zs[+-*] [namespace] ", "# Manage zignspaces", "zs", "", "display zignspaces", "zs ", "zignspace", "select zignspace", @@ -81,7 +81,7 @@ static const char *help_msg_zs[] = { NULL }; -static const char *help_msg_zc[] = { +static RCoreHelpMessage help_msg_zc = { "Usage:", "zc[n!] other_space ", "# Compare zignspaces, match >= threshold (e zign.diff.*)", "zc", " other_space", "compare all current space with other_space", "zcn", " other_space", "compare current space with zigns with same name on other_space", diff --git a/libr/core/linux_heap_jemalloc.c b/libr/core/linux_heap_jemalloc.c index b2fbacc481..eeff9c9c66 100644 --- a/libr/core/linux_heap_jemalloc.c +++ b/libr/core/linux_heap_jemalloc.c @@ -516,7 +516,7 @@ static void GH(jemalloc_get_runs)(RCore *core, const char *input) { #endif static int GH(cmd_dbg_map_jemalloc)(RCore *core, const char *input) { - const char *help_msg[] = { + RCoreHelpMessage help_msg = { "Usage:", "dmh", " # Memory map heap", "dmha", "[arena_t]", "show all arenas created, or print arena_t structure for given arena", "dmhb", "[arena_t]", "show all bins created for given arena", diff --git a/libr/core/p/core_a2f.c b/libr/core/p/core_a2f.c index 075c1d9c95..44b9b09b62 100644 --- a/libr/core/p/core_a2f.c +++ b/libr/core/p/core_a2f.c @@ -397,16 +397,25 @@ static bool analyzeFunction(RCore *core, ut64 addr) { static int r_cmd_anal_call(void *user, const char *input) { RCore *core = (RCore *) user; + static RCoreHelpMessage help_msg_a2f = { + "Usage:", "a2f", "Experimental function analysis", + "a2f", "", "like af, but with an experimental engine. see anal.a2f", + NULL + }; if (!strncmp (input, "a2", 2)) { switch (input[2]) { case 'f': + if (input[3] == '?') { + r_core_cmd_help (core, help_msg_a2f); + return true; + } + if (!analyzeFunction (core, core->offset)) { R_LOG_DEBUG ("a2f: Failed to analyze function at 0x%08"PFMT64x, core->offset); } break; default: - eprintf ("Usage: a2f @ address_of_function # See anal.a2f\n"); - eprintf ("a2f is an experimental analysis engine that replaces af.\n"); + r_core_cmd_help (core, help_msg_a2f); break; } return true; diff --git a/libr/core/p/core_sixref.c b/libr/core/p/core_sixref.c index 4ff5dacb88..4d087e7f96 100644 --- a/libr/core/p/core_sixref.c +++ b/libr/core/p/core_sixref.c @@ -299,6 +299,12 @@ static void siguza_xrefs(RCore *core, ut64 search, ut64 start, int lenbytes) { } static int r_cmdsixref_call(void *user, const char *input) { + static RCoreHelpMessage help_msg_sixref = { + "Usage:", "sixref", "Fast xref discovery in arm64 executable sections", + "sixref", " [addr] [len]", "find xrefs in arm64 executable sections", + NULL + }; + if (!r_str_startswith (input, "sixref")) { return false; } @@ -309,7 +315,7 @@ static int r_cmdsixref_call(void *user, const char *input) { const int bits = r_config_get_i (core->config, "asm.bits"); if (*input == '?') { - eprintf ("Usage: sixref [address] [len] Find x-refs in executable sections (arm64 only but fast!)\n"); + r_core_cmd_help (core, help_msg_sixref); goto done; } diff --git a/libr/core/panels.c b/libr/core/panels.c index 44dd980f67..b93b3bb693 100644 --- a/libr/core/panels.c +++ b/libr/core/panels.c @@ -207,7 +207,7 @@ static const char *cache_white_list_cmds[] = { NULL }; -static const char *help_msg_panels[] = { +static RCoreHelpMessage help_msg_panels = { "|", "split current panel vertically", "-", "split current panel horizontally", ":", "run r2 command in prompt", @@ -260,7 +260,7 @@ static const char *help_msg_panels[] = { NULL }; -static const char * const help_msg_panels_window[] = { +static RCoreHelpMessage help_msg_panels_window = { ":", "run r2 command in prompt", ";", "add/remove comment", "\"", "create a panel from the list and replace the current one", @@ -280,7 +280,7 @@ static const char * const help_msg_panels_window[] = { NULL }; -static const char * const help_msg_panels_zoom[] = { +static RCoreHelpMessage help_msg_panels_zoom = { "?", "show this help", ":", "run r2 command in prompt", ";", "add/remove comment", diff --git a/libr/core/pseudo.c b/libr/core/pseudo.c index 2a4847f2b3..7349a4713c 100644 --- a/libr/core/pseudo.c +++ b/libr/core/pseudo.c @@ -162,7 +162,7 @@ static void find_and_change(char* in, int len) { } } -static const char *help_msg_pdc[] = { +static RCoreHelpMessage help_msg_pdc = { "Usage: pdc[oj]", "", "experimental, unreliable and hacky pseudo-decompiler", "pdc", "", "pseudo decompile function in current offset", "pdcc", "", "pseudo-decompile with C helpers around", diff --git a/libr/core/visual.c b/libr/core/visual.c index d650665785..7e3230c899 100644 --- a/libr/core/visual.c +++ b/libr/core/visual.c @@ -288,7 +288,7 @@ static bool __core_visual_gogo(RCore *core, int ch) { return false; } -static const char *help_visual[] = { +static RCoreHelpMessage help_visual = { "?", "full help", "!", "enter panels", "a", "code analysis", @@ -302,7 +302,7 @@ static const char *help_visual[] = { NULL }; -static const char *help_msg_visual[] = { +static RCoreHelpMessage help_msg_visual = { "?", "show visual mode help (short)", "??", "show visual mode help (full)", "$", "set the program counter to the current offset + cursor", @@ -360,7 +360,7 @@ static const char *help_msg_visual[] = { NULL }; -static const char *help_msg_visual_fn[] = { +static RCoreHelpMessage help_msg_visual_fn = { "F2", "toggle breakpoint", "F4", "run to cursor", "F7", "single step", @@ -1413,7 +1413,7 @@ static int follow_ref(RCore *core, RList *xrefs, int choice, int xref) { return 0; } -static const char *help_msg_visual_xref[] = { +static RCoreHelpMessage help_msg_visual_xref = { "j/k", "select next or previous item (use arrows)", "J/K", "scroll by 10 refs", "g/G", "scroll to top / bottom", diff --git a/libr/core/vmenus.c b/libr/core/vmenus.c index 18d0495bd5..2cb4c8712b 100644 --- a/libr/core/vmenus.c +++ b/libr/core/vmenus.c @@ -137,11 +137,16 @@ R_API bool r_core_visual_esil(RCore *core, const char *input) { RAnalOp analop; ut8 buf[sizeof (ut64)]; unsigned int addrsize = r_config_get_i (core->config, "esil.addr.size"); + static RCoreHelpMessage help_msg_aev = { + "Usage:", "aev [esil]", "Visual esil debugger", + "aev", " [esil]", "visual esil debugger for the given expression or current instruction", + NULL + }; if (input && !*input) { input = NULL; } if (input && *input == '?') { - eprintf ("Usage: aev [esil-expression] # same as VbE\n"); + r_core_cmd_help (core, help_msg_aev); return false; } if (!r_config_get_b (core->config, "scr.interactive")) { @@ -3197,7 +3202,7 @@ static void r_core_visual_anal_refresh_column(RCore *core, int colpos) { free (cmdf); } -static const char *help_fun_visual[] = { +static RCoreHelpMessage help_fun_visual = { "(a)", "analyze ", "(-)", "delete ", "(x)", "xrefs ", "(X)", "refs ", "(j/k)", "next/prev\n", "(r)", "rename ", "(c)", "calls ", "(d)", "define ", "(Tab)", "disasm ", "(_)", "hud\n", "(d)", "define ", "(v)", "vars ", "(?)", " help ", "(:)", "shell " ,"(q)", "quit\n", @@ -3205,20 +3210,20 @@ static const char *help_fun_visual[] = { NULL }; -static const char *help_var_visual[] = { +static RCoreHelpMessage help_var_visual = { "(a)", "add " ,"(x)", "xrefs ", "(r)", "rename\n", "(t)", "type ", "(g)", "go ", "(-)" ,"delete\n", "(q)", "quit ", "(s)", "signature\n\n", NULL }; -static const char *help_visual_anal_actions[] = { +static RCoreHelpMessage help_visual_anal_actions = { "functions:", "Add, Modify, Delete, Xrefs Calls Vars", "variables:", "Add, Modify, Delete", NULL }; -static const char *help_visual_anal_keys[] = { +static RCoreHelpMessage help_visual_anal_keys = { "j/k", "select next/prev item; scroll disasm column", "J/K", "scroll next/prev by page", "b/h", "functions analysis (level 0)", @@ -3236,7 +3241,7 @@ static const char *help_visual_anal_keys[] = { NULL }; -static void r_core_vmenu_append_help(RStrBuf *p, const char **help) { +static void r_core_vmenu_append_help(RStrBuf *p, RCoreHelpMessage help) { int i; RConsContext *cons_ctx = r_cons_singleton ()->context; const char *pal_args_color = cons_ctx->color_mode ? cons_ctx->pal.args : "", diff --git a/libr/core/windows_heap.c b/libr/core/windows_heap.c index 97b7bd9e85..fc43faa5f3 100644 --- a/libr/core/windows_heap.c +++ b/libr/core/windows_heap.c @@ -1321,14 +1321,14 @@ static void w32_list_heaps_blocks(RCore *core, const char format) { RtlDestroyQueryDebugBuffer (db); } -static const char *help_msg[] = { +static RCoreHelpMessage help_msg = { "Usage:", " dmh[?|b][f|j]", " # Memory map heap", "dmh[j]", "", "List process heaps", "dmhb[?] [addr]", "", "List process heap blocks", NULL }; -static const char *help_msg_block[] = { +static RCoreHelpMessage help_msg_block = { "Usage:", " dmhb[f|j]", " # Memory map heap", "dmhb [addr]", "", "List allocated heap blocks", "dmhbf", "", "Create flags for each allocated block", diff --git a/libr/core/yank.c b/libr/core/yank.c index 9e23bedd9d..cb93029b68 100644 --- a/libr/core/yank.c +++ b/libr/core/yank.c @@ -213,7 +213,6 @@ R_API int r_core_yank_to(RCore *core, const char *_arg) { str[0] = ' '; } if (!str || pos == -1 || len == 0) { - eprintf ("Usage: yt [len] [dst-addr]\n"); free (arg); return res; } diff --git a/libr/io/p/io_r2k_linux.c b/libr/io/p/io_r2k_linux.c index a0f5e4f078..0ac3677134 100644 --- a/libr/io/p/io_r2k_linux.c +++ b/libr/io/p/io_r2k_linux.c @@ -234,7 +234,7 @@ static void print_help(RIO *io, char *cmd, int p_usage) { ":dp [pid] Print current selected pid or change it", ":e r2k.io=[012] Read/Write from 0: Linear, 1: Process, 2: Physical addresses" }; - const char *help_msg_old[] = { + RCoreHelpMessage help_msg_old = { ":M Print kernel memory map", ":b beid [pid] Change r2k backend. pid is required when beid is 1.", " 0: linear address; 1: process address; 2: physical address", diff --git a/test/db/cmd/cmd_aes b/test/db/cmd/cmd_aes index fc9ad2eecf..50fa0afc08 100644 --- a/test/db/cmd/cmd_aes +++ b/test/db/cmd/cmd_aes @@ -75,17 +75,17 @@ aep test @ 0x5 "aep strlen=dr R0=`pszl@r:A0`;aexa ret" "aep puts=psz@r:A0; aexa ret" test -Usage: te[...] +Usage: te[...] Type enum commands | te list all loaded enums | te print all values of enum for given name +| te show name for given enum number | te- delete enum type definition | tej list all loaded enums in json | tej show enum in json -| te show name for given enum number | teb show matching enum bitfield for given name -| tec list all/given loaded enums in C output format with newlines +| tec list all loaded enums in C output format with newlines +| tec list given loaded enums in C output format with newlines | ted list all loaded enums in C output format without newlines -| te? show this help EOF EXPECT_ERR= RUN diff --git a/test/db/cmd/cmd_help b/test/db/cmd/cmd_help index 1f2b90c32c..ce1cf1b6e0 100644 --- a/test/db/cmd/cmd_help +++ b/test/db/cmd/cmd_help @@ -68,6 +68,7 @@ EXPECT=< /dev/null cat .tmp/testexp/rc.r2 | grep base64 -rmdir -p .tmp/testexp +rm -rf .tmp/testexp EOF EXPECT=<