Change macro syntax to use ; instead of ,

This change is to ease the switch to the new parser and make the syntax
more consistent and easy. As things were before this patch, ',' could be
part of an argument of a command, but at the same time it was used as a
separator when defining a new macro. This difference in how `,` is
interpreter, makes parsing commands harder, as grep specifiers,
arguments, etc. should be parsed differently based on whether they are
inside a macro body or not.

By switching to using `;` as separator in the macro body, arguments,
grep specifiers, etc. can be parsed as they would be outside of a macro
body, making the new parser more consistent and easier.
This commit is contained in:
Riccardo Schirone 2020-03-10 15:47:13 +01:00 committed by radare
parent bde3fa171b
commit c1c54be39e
23 changed files with 121 additions and 107 deletions

View File

@ -2518,6 +2518,30 @@ static char *parse_tmp_evals(RCore *core, const char *str) {
return res;
}
static bool is_macro_command(const char *ptr) {
ptr = r_str_trim_head_ro (ptr);
while (IS_DIGIT (*ptr)) {
ptr++;
}
return *ptr == '(';
}
static char *find_ch_after_macro(char *ptr, char ch) {
int depth = 0;
while (*ptr) {
if (depth == 0 && *ptr == ch) {
return ptr;
}
if (*ptr == '(') {
depth++;
} else if (*ptr == ')') {
depth--;
}
ptr++;
}
return NULL;
}
static int r_core_cmd_subst(RCore *core, char *cmd) {
ut64 rep = strtoull (cmd, NULL, 10);
int ret = 0, orep;
@ -2571,7 +2595,12 @@ static int r_core_cmd_subst(RCore *core, char *cmd) {
}
if (*cmd != '"') {
if (!strchr (cmd, '\'')) { // allow | awk '{foo;bar}' // ignore ; if there's a single quote
if ((colon = strchr (cmd, ';'))) {
if (is_macro_command (cmd)) {
colon = find_ch_after_macro (cmd, ';');
} else {
colon = strchr (cmd, ';');
}
if (colon) {
*colon = 0;
}
}
@ -2893,7 +2922,11 @@ static int r_core_cmd_subst_i(RCore *core, char *cmd, char *colon, bool *tmpseek
// TODO: must honor " and ` boundaries
//ptr = strrchr (cmd, ';');
if (*cmd != '#') {
ptr = (char *)r_str_lastbut (cmd, ';', quotestr);
if (is_macro_command (cmd)) {
ptr = find_ch_after_macro (cmd, ';');
} else {
ptr = (char *)r_str_lastbut (cmd, ';', quotestr);
}
if (colon && ptr) {
int ret ;
*ptr = '\0';

View File

@ -932,7 +932,7 @@ static void find_refs(RCore *core, const char *glob) {
}
eprintf ("Finding references of flags matching '%s'...\n", glob);
snprintf (cmd, sizeof (cmd) - 1, ".(findstref) @@= `f~%s[0]`", glob);
r_core_cmd0 (core, "(findstref,f here=$$,s entry0,/r here,f-here)");
r_core_cmd0 (core, "(findstref;f here=$$;s entry0;/r here;f-here)");
r_core_cmd0 (core, cmd);
r_core_cmd0 (core, "(-findstref)");
r_core_seek (core, curseek, 1);

View File

@ -336,7 +336,7 @@ R_API int r_cmd_macro_add(RCmdMacro *mac, const char *oname) {
return 0;
}
pbody = strchr (name, ',');
pbody = strchr (name, ';');
if (!pbody) {
eprintf ("Invalid macro body\n");
free (name);
@ -394,52 +394,15 @@ R_API int r_cmd_macro_add(RCmdMacro *mac, const char *oname) {
macro->nargs = r_str_word_set0 (ptr+1);
}
#if 0
if (pbody) {
#endif
for (lidx=0; pbody[lidx]; lidx++) {
if (pbody[lidx] == ',') {
pbody[lidx]='\n';
} else if (pbody[lidx] == ')' && pbody[lidx - 1] == '\n') {
pbody[lidx] = '\0';
}
}
strncpy (macro->code, pbody, macro->codelen);
macro->code[macro->codelen-1] = 0;
//strcat (macro->code, ",");
#if 0
} else {
int lbufp, codelen = 0, nl = 0;
eprintf ("Reading macro from stdin:\n");
for (;codelen<R_CMD_MAXLEN;) { // XXX input from mac->fd
#if 0
if (stdin == r_cons_stdin_fd) {
mac->cb_printf(".. ");
fflush(stdout);
}
fgets(buf, sizeof (buf), r_cons_stdin_fd);
#endif
fgets (buf, sizeof (buf), stdin);
if (*buf=='\n' && nl)
break;
nl = (*buf == '\n')?1:0;
if (*buf==')')
break;
for (bufp=buf;*bufp==' '||*bufp=='\t';bufp++);
lidx = strlen (buf)-2;
lbufp = strlen (bufp);
if (buf[lidx]==')' && buf[lidx-1]!='(') {
buf[lidx]='\0';
memcpy (macro->code+codelen, bufp, lbufp+1);
break;
}
if (*buf != '\n') {
memcpy (macro->code+codelen, bufp, lbufp+1);
codelen += lbufp;
}
for (lidx = 0; pbody[lidx]; lidx++) {
if (pbody[lidx] == ';') {
pbody[lidx] = '\n';
} else if (pbody[lidx] == ')' && pbody[lidx - 1] == '\n') {
pbody[lidx] = '\0';
}
}
#endif
strncpy (macro->code, pbody, macro->codelen);
macro->code[macro->codelen-1] = 0;
if (macro_update == 0) {
r_list_append (mac->macros, macro);
}
@ -477,10 +440,10 @@ R_API void r_cmd_macro_list(RCmdMacro *mac) {
int j, idx = 0;
RListIter *iter;
r_list_foreach (mac->macros, iter, m) {
mac->cb_printf ("%d (%s %s, ", idx, m->name, m->args);
mac->cb_printf ("%d (%s %s; ", idx, m->name, m->args);
for (j=0; m->code[j]; j++) {
if (m->code[j] == '\n') {
mac->cb_printf (", ");
mac->cb_printf ("; ");
} else {
mac->cb_printf ("%c", m->code[j]);
}
@ -499,7 +462,7 @@ R_API void r_cmd_macro_meta(RCmdMacro *mac) {
mac->cb_printf ("(%s %s, ", m->name, m->args);
for (j=0; m->code[j]; j++) {
if (m->code[j] == '\n') {
mac->cb_printf (", ");
mac->cb_printf ("; ");
} else {
mac->cb_printf ("%c", m->code[j]);
}
@ -685,7 +648,7 @@ R_API int r_cmd_macro_call(RCmdMacro *mac, const char *name) {
free (str);
return 0;
}
ptr = strchr (str, ',');
ptr = strchr (str, ';');
if (ptr) {
*ptr = 0;
}

View File

@ -3,18 +3,18 @@
#include "r_core.h"
static const char *help_msg_lparen[] = {
"Usage:", "(foo args,cmd1,cmd2,..)", "Aliases",
"(foo args,..,..)", "", "define a macro",
"(foo args,..,..)()", "", "define and call a macro",
"Usage:", "(foo args;cmd1;cmd2;..)", "Aliases",
"(foo args;..;..)", "", "define a macro",
"(foo args;..;..)()", "", "define and call a macro",
"(-foo)", "", "remove a macro",
".(foo)", "", "to call it",
"()", "", "break inside macro",
"(*", "", "list all defined macros",
"", "Argument support:", "",
"(foo x y, $0 @ $1)", "", "define fun with args (x - $0, y - $1)",
"(foo x y; $0 @ $1)", "", "define fun with args (x - $0; y - $1)",
".(foo 128 0x804800)", "", "call it with args",
"", "Iterations:", "",
".(foo,() $@)", "", "define iterator returning iter index",
".(foo;() $@)", "", "define iterator returning iter index",
"x @@ .(foo)", "", "iterate over them",
NULL
};
@ -75,7 +75,7 @@ static int cmd_macro(void *data, const char *input) {
if (mustcall) {
char *comma = strchr (buf, ' ');
if (!comma) {
comma = strchr (buf, ',');
comma = strchr (buf, ';');
}
if (comma) {
*comma = ' ';

View File

@ -2454,7 +2454,7 @@ e anal.nopskip=false
e asm.bb.middle=true
e anal.jmp.mid=true
e io.cache=true
"(show_fcn bin, wx $0, af-*, af, afi, ?e, afb, ?e, pdr, ?e, agf, ?e, e asm.bb.middle=true, pdf, ?e, e asm.bb.middle=false, pdf)"
"(show_fcn bin; wx $0; af-*; af; afi; ?e; afb; ?e; pdr; ?e; agf; ?e; e asm.bb.middle=true; pdf; ?e; e asm.bb.middle=false; pdf)"
.(show_fcn b8210000c1ebfdbb2c000000cc)
?e
.(show_fcn b8210000c1ebfdbb2c000000ebf6)

View File

@ -4,7 +4,7 @@ FILE=-
CMDS=<<EOF
cd `e dir.tmp`
e io.cache=true
"(show_fname fname, wz $0, wtf `prz`, o `prz`, i~file, ij, rm `prz`)"
"(show_fname fname; wz $0; wtf `prz`; o `prz`; i~file; ij; rm `prz`)"
.(show_fname A\x1b¢\302\200€𝄞\363\240\201\201\\.bin)
.(show_fname B\x1b¢\302\200€𝄞\363\240\201\201\\.bin)
# INVALID FILENAME .(show_fname B\x1b¢\302\200\200€𝄞\363\240\201\201\\.bin)

View File

@ -4,7 +4,7 @@ FILE=-
CMDS=<<EOF
cd `e dir.tmp`
e io.cache=true
"(show_fname fname, wz $0, wtf `prz`, o `prz`, i~file, ij, rm `prz`)"
"(show_fname fname; wz $0; wtf `prz`; o `prz`; i~file; ij; rm `prz`)"
.(show_fname A\x1b¢\302\200€𝄞\363\240\201\201\\.bin)
.(show_fname B\x1b¢\302\200€𝄞\363\240\201\201\\.bin)
# INVALID FILENAME .(show_fname B\x1b¢\302\200\200€𝄞\363\240\201\201\\.bin)

View File

@ -93,7 +93,7 @@ CMDS=<<EOF
e scr.color=0
e dbg.swstep=true
f times=5
(times_stop,?e Loop `?vi times`,f times=`?vi times-1`,?= times)
(times_stop;?e Loop `?vi times`;f times=`?vi times-1`;?= times)
db 0x4000ce
dbC 0x4000ce .(times_stop)
dc
@ -115,7 +115,7 @@ CMDS=<<EOF
e scr.color=0
e dbg.swstep=true
e cmd.hitinfo=0
(break_rax,f reg_rax=`dr rax`,f test=`?vi reg_rax-0x31c0`,?= test)
(break_rax;f reg_rax=`dr rax`;f test=`?vi reg_rax-0x31c0`;?= test)
db 0x4000ce
dbC 0x4000ce .(break_rax)
dc
@ -136,7 +136,7 @@ CMDS=<<EOF
e scr.color=0
e dbg.swstep=true
e cmd.hitinfo=0
(trace_rax,dr rax,f reg_rax=`dr rax`,f test=`?vi reg_rax-0x0440`,?= test)
(trace_rax;dr rax;f reg_rax=`dr rax`;f test=`?vi reg_rax-0x0440`;?= test)
db 0x4000ce
dbC 0x4000ce .(trace_rax)
dc

View File

@ -3632,7 +3632,7 @@ izz~0x00412420
e bin.str.purge=true
izz~0x00412420 # Should print nothing
?e --3--
(test_iz,iz~0x004131d8,iz~0x00413228,iz~0x00413233,iz~0x0041323a)
(test_iz;iz~0x004131d8;iz~0x00413228;iz~0x00413233;iz~0x0041323a)
e bin.str.purge=false
.(test_iz)
?e --4--

View File

@ -1,27 +1,27 @@
NAME=(msg x,?e $0)
NAME=(msg x;?e $0)
FILE=-
EXPECT=<<EOF
HelloWorld
EOF
CMDS=<<EOF
"(msg x,?e $0)"
"(msg x;?e $0)"
.(msg HelloWorld)
EOF
RUN
NAME=(msg x,?e $0)
NAME=(msg x;?e $0)
FILE=-
EXPECT=<<EOF
HelloWorld
EOF
CMDS=<<EOF
"(msg x,?e $0)"
"(msg x;?e $0)"
.(msg HelloWorld)
EOF
RUN
NAME=(msg x,?e $0)
NAME=(msg x;?e $0)
FILE=-
EXPECT=<<EOF
@ -29,19 +29,19 @@ HelloWorld
hiz
EOF
CMDS=<<EOF
"(msg x,?e $0)"
"(msg x;?e $0)"
.(msg HelloWorld)
?e hiz
EOF
RUN
NAME=.(msg x y,?e $0 $1)
NAME=.(msg x y;?e $0 $1)
FILE=-
EXPECT=<<EOF
Hello World
EOF
CMDS=<<EOF
"(msg x y,?e $0 $1)"
"(msg x y;?e $0 $1)"
.(msg Hello World)
EOF
RUN
@ -52,7 +52,7 @@ EXPECT=<<EOF
Hello World
EOF
CMDS=<<EOF
"(msg x,?e $0)"
"(msg x;?e $0)"
.(msg "Hello World")
EOF
RUN
@ -63,7 +63,7 @@ EXPECT=<<EOF
Hello World
EOF
CMDS=<<EOF
"(msg x,?e $0)"
"(msg x;?e $0)"
.(msg Hello\ World)
EOF
RUN
@ -74,13 +74,13 @@ EXPECT=<<EOF
2
EOF
CMDS=<<EOF
(foo,bar)
(bar,cow)
(foo;bar)
(bar;cow)
(*~?
EOF
RUN
NAME=3(foo,p8 4,s+$0)(1)
NAME=3(foo;p8 4;s+$0)(1)
FILE=-
EXPECT=<<EOF
01020304
@ -89,11 +89,11 @@ EXPECT=<<EOF
EOF
CMDS=<<EOF
wx 010203040506070809
3(foo,p8 4,s+$0)(1)
3(foo;p8 4;s+$0)(1)
EOF
RUN
NAME=3(foo,?e a,?e b)()
NAME=3(foo;?e a;?e b)()
FILE=-
EXPECT=<<EOF
a
@ -101,7 +101,7 @@ b
a
b
EOF
CMDS=2(foo,?e a,?e b)()
CMDS=2(foo;?e a;?e b)()
RUN
NAME=?v $$ @@ foo*
@ -130,6 +130,24 @@ CMDS=<<EOF
f foo.one = 1
f foo.bar = 2
f foo.cow = 3
(,?v $$)() @@ foo*
(;?v $$)() @@ foo*
EOF
RUN
NAME=multiple commands
FILE=-
CMDS=<<EOF
(foo x y; p8 $0 @ $1; ?e Hello $0)(2 0)
(bar x y; p8 $0 @ $1; ?e Hello $0; ?e World $1)(1 0)
(zas x y; .(foo $1 $0))(3 1)
EOF
EXPECT=<<EOF
0000
Hello 2
00
Hello 1
World 0
00
Hello 1
EOF
RUN

View File

@ -1029,7 +1029,7 @@ e asm.noisy=false
e asm.bytes=false
e asm.cmt.off=false
e str.escbslash=true
(test_str.enc enc, e bin.str.enc=$0, e bin.str.enc)
(test_str.enc enc; e bin.str.enc=$0; e bin.str.enc)
.(test_str.enc guess)
.(test_str.enc utf-8)
.(test_str.enc utf-16le)
@ -1056,7 +1056,7 @@ RUN
NAME=bin.str.enc error handling
FILE=-
CMDS=<<EOF
(test_str.enc enc, e bin.str.enc=$0, e bin.str.enc)
(test_str.enc enc; e bin.str.enc=$0; e bin.str.enc)
.(test_str.enc UTF-32LE)
.(test_str.enc cat_sat_on_keyboard)
.(test_str.enc CAT_SAT_ON_KEYBOARD)

View File

@ -549,8 +549,8 @@ FILE=../bins/elf/ls
CMDS=<<EOF
e asm.bytes=false
e asm.filter=true
(pd_tests, e asm.relsub=true, pd 15, ?e, e asm.relsub=false, pd 1 @ 0x000041ee, pd 1 @ 0x00004225)
(insn_tests, e scr.color=0, .(pd_tests), ?e, e scr.color=1, .(pd_tests))
(pd_tests; e asm.relsub=true; pd 15; ?e; e asm.relsub=false; pd 1 @ 0x000041ee; pd 1 @ 0x00004225)
(insn_tests; e scr.color=0; .(pd_tests); ?e; e scr.color=1; .(pd_tests))
s 0x000041e0
.(insn_tests)
?e
@ -753,8 +753,8 @@ e asm.bytes=false
e asm.offset=false
e asm.cmt.off=false
aar
(pdenc enc, e bin.str.enc=$0, pd 1)
(pdstr bits, s `axt obj.utf$0be~[1]`, .(pdenc guess), .(pdenc utf$0le), .(pdenc utf$0be))
(pdenc enc; e bin.str.enc=$0; pd 1)
(pdstr bits; s `axt obj.utf$0be~[1]`; .(pdenc guess); .(pdenc utf$0le); .(pdenc utf$0be))
.(pdstr 16)
?e
.(pdstr 32)
@ -778,7 +778,7 @@ e asm.offset=0
e asm.cmt.off=0
e bin.str.enc=guess
aar
(pdstr flag, s `axt obj.$0~[1]`, pd 1)
(pdstr flag; s `axt obj.$0~[1]`; pd 1)
.(pdstr utf8_bom)
.(pdstr utf16le_bom)
.(pdstr utf16be_bom)

View File

@ -859,7 +859,7 @@ NAME=pf z, scr.strconv and str.escbslash
FILE=-
CMDS=<<EOF
wz \x7fabc\\123\n
(print strconv escbslash, e scr.strconv=$0, e str.escbslash=$1, pf z)
(print strconv escbslash; e scr.strconv=$0; e str.escbslash=$1; pf z)
.(print asciiesc false)
.(print asciiesc true)
.(print asciidot false)

View File

@ -308,7 +308,7 @@ NAME=pf/pfj z with size
FILE=-
CMDS=<<EOF
wz ABCDE
(pf2 format, pf $0, pfj $0)
(pf2 format; pf $0; pfj $0)
.(pf2 z)
?e
.(pf2 [3]z)

View File

@ -397,7 +397,7 @@ pf? elf_header
pfs.elf_header
?e
wz `pf? elf_header`
(pfelf num, pf.elf_header {$0}`psz`, pf? elf_header, pfs.elf_header)
(pfelf num; pf.elf_header {$0}`psz`; pf? elf_header; pfs.elf_header)
.(pfelf 1)
?e
.(pfelf 2)

View File

@ -711,7 +711,7 @@ NAME=io.unalloc, io.unalloc.ch and prc
FILE=../bins/elf/analysis/tiny.elf
CMDS=<<EOF
. ../bins/other/palette.r2
(print, prc 0x00010032-0x0000fffa @ 0x0000fffa)
(print; prc 0x00010032-0x0000fffa @ 0x0000fffa)
e io.unalloc=true
e scr.color=0
.(print)

View File

@ -45,7 +45,7 @@ FILE=../bins/elf/analysis/tiny.elf
CMDS=<<EOF
. ../bins/other/palette.r2
e io.unalloc=true
(dump, xc 0x00010060-0x0000ffd0 @ 0x0000ffd0-6)
(dump; xc 0x00010060-0x0000ffd0 @ 0x0000ffd0-6)
e scr.color=3
e hex.comments=true
.(dump)

View File

@ -213,7 +213,7 @@ RUN
NAME=so -N, pd -N
FILE=../bins/pe/cmd_adf_sample0.exe
CMDS=<<EOF
"(test_so_pd addr, ?e, ?e --- From $0 ---, ?e, ?e -- 1 --, s $0, pd -1, so -1, s, pd 1, ?e, ?e -- 2 --, s $0, pd -2, so -2, s, pd 2)"
"(test_so_pd addr; ?e; ?e --- From $0 ---; ?e; ?e -- 1 --; s $0; pd -1; so -1; s; pd 1; ?e; ?e -- 2 --; s $0; pd -2; so -2; s; pd 2)"
.(test_so_pd 0x0) # Special case
.(test_so_pd 0x401000)
s 0x560e67

View File

@ -62,11 +62,11 @@ s 0x123
?v $$ @ 0x300
?v $$$ @ 0x300
?e
(test, ?v $$$)
(test; ?v $$$)
.(test)
.(test) @ 0x300
s
(test2, .(test) @ 0x400)
(test2; .(test) @ 0x400)
.(test2)
s
.(test2) @ 0x300
@ -91,9 +91,9 @@ RUN
NAME=nested $$
FILE=-
CMDS=<<EOF
(nested_seek, ?v $$)
(nested_seek; ?v $$)
.(nested_seek) @ 0x500
(nested_seek2, ?v $$, .(nested_seek) @ 0x600, ?v $$)
(nested_seek2; ?v $$; .(nested_seek) @ 0x600; ?v $$)
.(nested_seek2) @ 0x700
EOF
EXPECT=<<EOF

View File

@ -279,7 +279,7 @@ idx=2 addr=0x00000006 size=3 000000 -> 909090 (written)
EOF
CMDS=<<EOF
e io.cache=true
(wxseek , wx 909090, s+ 3)
(wxseek ; wx 909090; s+ 3)
3.(wxseek)
wci
wc

View File

@ -8,7 +8,7 @@ CMDS=<<EOF
e asm.arch=ppc
e asm.bits=32
e cfg.bigendian=true
"(pi bytes,wx $0,pi 1,pie 1)"
(pi bytes;wx $0;pi 1;pie 1)
.(pi 8421fff8)
EOF
RUN
@ -23,7 +23,7 @@ CMDS=<<EOF
e asm.arch=ppc
e asm.bits=32
e cfg.bigendian=true
"(pi bytes,wx $0,pi 1,pie 1)"
(pi bytes;wx $0;pi 1;pie 1)
.(pi 9421fff8)
EOF
RUN
@ -38,7 +38,7 @@ CMDS=<<EOF
e asm.arch=ppc
e asm.bits=32
e cfg.bigendian=true
"(pi bytes,wx $0,pi 1,pie 1)"
(pi bytes;wx $0;pi 1;pie 1)
.(pi 4200fff0)
EOF
RUN

View File

@ -7,7 +7,7 @@ EOF
CMDS=<<EOF
e asm.arch=x86
e asm.bits=64
"(pi bytes,wx $0,pi 1,pie 1)"
(pi bytes;wx $0;pi 1;pie 1)
.(pi 49f7e9)
EOF
RUN
@ -21,7 +21,7 @@ EOF
CMDS=<<EOF
e asm.arch=x86
e asm.bits=64
"(pi bytes,wx $0,pi 1,pie 1)"
(pi bytes;wx $0;pi 1;pie 1)
.(pi 0fafc1)
EOF
RUN
@ -35,7 +35,7 @@ EOF
CMDS=<<EOF
e asm.arch=x86
e asm.bits=64
"(pi bytes,wx $0,pi 1,pie 1)"
(pi bytes;wx $0;pi 1;pie 1)
.(pi 4969c367666633)
EOF
RUN

View File

@ -117,7 +117,7 @@ FILE=../bins/elf/abcde-qt32
CMDS=<<EOF
e asm.demangle=true
e asm.bytes=false
(pd_calls, pd 1 @ 0x0804921a, pd 1 @ 0x08049249, pd 1 @ 0x08049278)
(pd_calls; pd 1 @ 0x0804921a; pd 1 @ 0x08049249; pd 1 @ 0x08049278)
e asm.cmt.right=true
.(pd_calls)
?e