Skip to content

Commit

Permalink
rc: introduce automatically quoted mini syntax
Browse files Browse the repository at this point in the history
This is an experimental change that propose an explicit mini syntax
that automatically quote arguments like

 --foo=bar
 -DMACRO=baz
 if=file of=file

This mini-syntax is enabled by a single '$' that marks the end of
variable assignments in a command. The scope of the syntax is a
single command: it's automatically turned of on &, &&, || and so on.

The price of this sugar is that you can't define variables after the
$ marker till the end of the command.

Some examples:

% a=1 echo b=$a
rc: #d/0: token '=': syntax error
% a=1 $ echo b=$a
b=1
% $ eval prefix=$home/foo && echo $prefix
/usr/glenda/foo
% $ eval prefix=$home/foo; echo ./configure --prefix=$prefix
rc: #d/0: token '=': syntax error
% $ eval prefix=$home/foo; $ echo ./configure --prefix=$prefix
./configure --prefix=/usr/glenda/foo
% inf=/dev/random out=/dev/null $ echo dd if=$inf of=$out
dd if=/dev/random of=/dev/null

Also read on 9fans http://marc.info/?t=149366703800002&r=1&w=2
  • Loading branch information
Shamar committed May 15, 2017
1 parent ecd6ddd commit 0031419
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
1 change: 1 addition & 0 deletions sys/src/cmd/rc/rc.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct tree{
tree *newtree(void);
tree *token(char*, int), *klook(char*), *tree1(int, tree*);
tree *tree2(int, tree*, tree*), *tree3(int, tree*, tree*, tree*);
tree *treeeq(int, tree*, tree*);
tree *mung1(tree*, tree*), *mung2(tree*, tree*, tree*);
tree *mung3(tree*, tree*, tree*, tree*), *epimung(tree*, tree*);
tree *simplemung(tree*), *heredoc(tree*);
Expand Down
20 changes: 20 additions & 0 deletions sys/src/cmd/rc/syn.y
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
};
%type<tree> line paren brace body cmdsa cmdsan assign epilog redir
%type<tree> cmd simple first word comword keyword words
%type<tree> qcmd qsimple qpareq qfirst qword qcomword
%type<tree> NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN
%type<tree> WORD REDIR DUP PIPE
%%
Expand All @@ -33,12 +34,31 @@ cmdsan: cmdsa
| cmd '\n'
brace: '{' body '}' {$$=tree1(BRACE, $2);}
paren: '(' body ')' {$$=tree1(PCMD, $2);}
/* auto-quoted mini syntax */
qfirst: qcomword
| qfirst '^' qword {$$=tree2('^', $1, $3);}
qword: keyword {lastword=1; $1->type=WORD;}
| qcomword
| qword '^' qword {$$=tree2('^', $1, $3);}
qcomword: '$' qword {$$=tree1('$', $2);}
| '$' qword SUB words ')' {$$=tree2(SUB, $2, $4);}
| '"' qword {$$=tree1('"', $2);}
| COUNT qword {$$=tree1(COUNT, $2);}
| WORD
qpareq: qword '=' qword {$$=treeeq('^', $1, $3);}
qsimple: qfirst
| qsimple '{' '}' {$$=tree2(ARGLIST, $1, token("{}", WORD));}
| qsimple qpareq {$$=tree2(ARGLIST, $1, $2);}
| qsimple qword {$$=tree2(ARGLIST, $1, $2);}
| qsimple redir {$$=tree2(ARGLIST, $1, $2);}
qcmd: '$' qsimple {$$=simplemung($2);}
assign: first '=' word {$$=tree2('=', $1, $3);}
epilog: {$$=0;}
| redir epilog {$$=mung2($1, $1->child[0], $2);}
redir: REDIR word {$$=mung1($1, $1->rtype==HERE?heredoc($2):$2);}
| DUP
cmd: {$$=0;}
| qcmd
| brace epilog {$$=epimung($1, $2);}
| IF paren {skipnl();} cmd
{$$=mung2($1, $2, $4);}
Expand Down
11 changes: 11 additions & 0 deletions sys/src/cmd/rc/tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,17 @@ tree3(int type, tree *c0, tree *c1, tree *c2)
return t;
}

tree*
treeeq(int type, tree *c0, tree *c1)
{
char *old;
old = c0->str;
c0->str = smprint("%s=", old);
c0->quoted = 1;
free(old);
return tree2('^', c0, c1);
}

tree*
mung1(tree *t, tree *c0)
{
Expand Down

0 comments on commit 0031419

Please sign in to comment.