Import rc syntax `delim{cmd} for splitting commands from 9atom. This allows an elegant, concise way of handling parsing the output of commands. Reference: /n/sources/patch/rc-line-split Date: Fri Dec 6 05:21:41 GMT 2019 Signed-off-by: ori@eigenstate.org --- /sys/man/1/rc Fri Dec 6 05:19:38 2019 +++ /sys/man/1/rc Fri Dec 6 05:19:32 2019 @@ -233,6 +233,8 @@ separated by spaces. A variable with zero elements yields the empty string. .HP .BI `{ command } +.HP +.BI ` "split " { command } .br .I rc executes the @@ -245,6 +247,8 @@ .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 --- /sys/src/cmd/rc/code.c Fri Dec 6 05:19:46 2019 +++ /sys/src/cmd/rc/code.c Fri Dec 6 05:19:41 2019 @@ -84,6 +84,8 @@ { int p, q; tree *tt; + char *ifs; + if(t==0) return; if(t->type!=NOT && t->type!=';') @@ -131,10 +133,22 @@ emitf(Xconc); break; case '`': + emitf(Xmark); + if(c0){ + outcode(c0, 0); + emitf(Xglob); + } else { + if((ifs = strdup("ifs")) == nil) + sysfatal("strdup: %r"); + emitf(Xmark); + emitf(Xword); + emits(ifs); + emitf(Xdol); + } emitf(Xbackq); if(havefork){ p = emiti(0); - outcode(c0, 0); + outcode(c1, 0); emitf(Xexit); stuffdot(p); } else --- /sys/src/cmd/rc/exec.c Fri Dec 6 05:19:56 2019 +++ /sys/src/cmd/rc/exec.c Fri Dec 6 05:19:50 2019 @@ -195,7 +195,7 @@ * 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 --- /sys/src/cmd/rc/havefork.c Fri Dec 6 05:20:03 2019 +++ /sys/src/cmd/rc/havefork.c Fri Dec 6 05:19:59 2019 @@ -84,11 +84,12 @@ char *stop; char utf[UTFmax+1]; io *f, *wd; - var *ifs = vlook("ifs"); word *v, *nextv; 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; @@ -132,6 +133,7 @@ s_free(word); closeio(f); Waitfor(pid, 0); + poplist(); /* ditch split in "stop" */ /* v points to reversed arglist -- reverse it onto argv */ while(v){ nextv = v->next; --- /sys/src/cmd/rc/pcmd.c Fri Dec 6 05:20:09 2019 +++ /sys/src/cmd/rc/pcmd.c Fri Dec 6 05:20:06 2019 @@ -33,7 +33,7 @@ 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; --- /sys/src/cmd/rc/syn.y Fri Dec 6 05:20:16 2019 +++ /sys/src/cmd/rc/syn.y Fri Dec 6 05:20:12 2019 @@ -83,7 +83,8 @@ | '"' 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);} | REDIR brace {$$=mung1($1, $2); $$->type=PIPEFD;} keyword: FOR|IN|WHILE|IF|NOT|TWIDDLE|BANG|SUBSHELL|SWITCH|FN