Skip to content

Commit

Permalink
rc: implement 9atoms `sep{command} syntax
Browse files Browse the repository at this point in the history
After a bunch of experience using this, I
find that it  makes a good deal of code
far simpler to write. For example,

	nl='
	'

	for(f in `$nl{find . -type f})
		munge $f

ends up quite a bit more pleasant to use
for handling file output line by line,
since it doesn't cause scoping issues
for rc functions, and is more explicit
about what is being split on.
  • Loading branch information
oridb committed Oct 7, 2020
1 parent 291f741 commit fa4ae53
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 8 deletions.
4 changes: 4 additions & 0 deletions man/man1/rc.1
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,8 @@ The value is a single string containing the components of the named variable
separated by spaces. A variable with zero elements yields the empty string.
.HP
.BI `{ command }
.HP
.BI ` "split " { command }
.br
.I rc
executes the
Expand All @@ -240,6 +242,8 @@ If
.B $ifs
is not otherwise set, its value is
.BR "'\ \et\en'" .
In the second form of the command, split is used instead of
.BR $ifs .
.HP
.BI <{ command }
.HP
Expand Down
12 changes: 11 additions & 1 deletion src/cmd/rc/code.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,20 @@ outcode(tree *t, int eflag)
emitf(Xconc);
break;
case '`':
emitf(Xmark);
if(c0){
outcode(c0, 0);
emitf(Xglob);
}else{
emitf(Xmark);
emitf(Xword);
emits(strdup("ifs"));
emitf(Xdol);
}
emitf(Xbackq);
if(havefork){
p = emiti(0);
outcode(c0, 0);
outcode(c1, 0);
emitf(Xexit);
stuffdot(p);
} else
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/rc/exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ main(int argc, char *argv[])
* Xappend(file)[fd] open file to append
* Xassign(name, val) assign val to name
* Xasync{... Xexit} make thread for {}, no wait
* Xbackq{... Xreturn} make thread for {}, push stdout
* Xbackq(split){... Xreturn} make thread for {}, push stdout
* Xbang complement condition
* Xcase(pat, value){...} exec code on match, leave (value) on
* stack
Expand Down
7 changes: 5 additions & 2 deletions src/cmd/rc/havefork.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,14 @@ Xbackq(void)
int c, n;
char *s, *ewd=&wd[8192], *stop, *q;
struct io *f;
var *ifs = vlook("ifs");
word *v, *nextv;
int pfd[2];
int pid;
Rune r;
stop = ifs->val?ifs->val->word:"";

stop = "";
if(runq->argv && runq->argv->words)
stop = runq->argv->words->word;
if(pipe(pfd)<0){
Xerror("can't make pipe");
return;
Expand Down Expand Up @@ -168,6 +170,7 @@ Xbackq(void)
}
closeio(f);
Waitfor(pid, 0);
poplist(); /* ditch split in "stop" */
/* v points to reversed arglist -- reverse it onto argv */
while(v){
nextv = v->next;
Expand Down
9 changes: 7 additions & 2 deletions src/cmd/rc/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,8 +501,13 @@ word1(int tok, int *ptok)
return tree1(COUNT, word1(yylex(), ptok));

case '`':
// | '`' brace {$$=tree1('`', $2);}
t = tree1('`', brace(yylex()));
// | '`' brace {$$=tree1('`', nil, $2);}
// | '`' word brace {$$=tree1('`', $2, $3);}
w = nil;
tok = yylex();
if(tok != '{')
w = yyword(tok, &tok, 1);
t = tree2('`', w, brace(tok));
*ptok = yylex();
return t;

Expand Down
2 changes: 1 addition & 1 deletion src/cmd/rc/pcmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pcmd(io *f, tree *t)
break;
case '^': pfmt(f, "%t^%t", c0, c1);
break;
case '`': pfmt(f, "`%t", c0);
case '`': pfmt(f, "`%t%t", c0, c1);
break;
case ANDAND: pfmt(f, "%t && %t", c0, c1);
break;
Expand Down
3 changes: 2 additions & 1 deletion src/cmd/rc/syn.y
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ comword: '$' word {$$=tree1('$', $2);}
| '"' word {$$=tree1('"', $2);}
| COUNT word {$$=tree1(COUNT, $2);}
| WORD
| '`' brace {$$=tree1('`', $2);}
| '`' brace {$$=tree2('`', (struct tree*)0, $2);}
| '`' word brace {$$=tree2('`', $2, $3);}
| '(' words ')' {$$=tree1(PAREN, $2);}
| REDIRW brace {$$=mung1($1, $2); $$->type=PIPEFD;}
keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN
Expand Down

0 comments on commit fa4ae53

Please sign in to comment.