aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlufia <lufia@lufia.org>2025-07-21 13:36:21 +0900
committerDan Cross <crossd@gmail.com>2025-07-27 09:55:45 -0400
commit8ff39da0623dbab13c00ce25a16dda168f6ec0a0 (patch)
tree7ad6a351cf9a0538ece73813da14872c6bd90785
parentcc89d242358cc777a22beefe2456d11e12e94197 (diff)
src/cmd/rc: import rc syntax `delim{cmd} for splitting commands from 9atom
Co-authored-by: <ori@eigenstate.org>
-rw-r--r--man/man1/rc.14
-rw-r--r--src/cmd/rc/code.c18
-rw-r--r--src/cmd/rc/exec.c2
-rw-r--r--src/cmd/rc/havefork.c7
-rw-r--r--src/cmd/rc/parse.c12
-rw-r--r--src/cmd/rc/pcmd.c2
-rw-r--r--src/cmd/rc/syn.y3
7 files changed, 38 insertions, 10 deletions
diff --git a/man/man1/rc.1 b/man/man1/rc.1
index 38a867d7..35670f0f 100644
--- a/man/man1/rc.1
+++ b/man/man1/rc.1
@@ -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
@@ -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
diff --git a/src/cmd/rc/code.c b/src/cmd/rc/code.c
index 208476ae..436e754a 100644
--- a/src/cmd/rc/code.c
+++ b/src/cmd/rc/code.c
@@ -94,6 +94,8 @@ outcode(tree *t, int eflag)
{
int p, q;
tree *tt;
+ char *ifs;
+
if(t==0)
return;
if(t->type!=NOT && t->type!=';')
@@ -141,14 +143,26 @@ outcode(tree *t, int eflag)
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
- emits(fnstr(c0));
+ emits(fnstr(c1));
break;
case ANDAND:
outcode(c0, 0);
diff --git a/src/cmd/rc/exec.c b/src/cmd/rc/exec.c
index 94d3321a..7987b0a5 100644
--- a/src/cmd/rc/exec.c
+++ b/src/cmd/rc/exec.c
@@ -218,7 +218,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
diff --git a/src/cmd/rc/havefork.c b/src/cmd/rc/havefork.c
index 63f83354..fd1561cc 100644
--- a/src/cmd/rc/havefork.c
+++ b/src/cmd/rc/havefork.c
@@ -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;
@@ -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;
diff --git a/src/cmd/rc/parse.c b/src/cmd/rc/parse.c
index a9cf497a..2713c0d6 100644
--- a/src/cmd/rc/parse.c
+++ b/src/cmd/rc/parse.c
@@ -409,7 +409,8 @@ yyword(int tok, int *ptok, int eqok)
// | '"' 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
@@ -499,8 +500,13 @@ word1(int tok, int *ptok)
return tree1(COUNT, word1(yylex(), ptok));
case '`':
- // | '`' brace {$$=tree1('`', $2);}
- t = tree1('`', brace(yylex()));
+ // | '`' brace {$$=tree2('`', (struct tree*)0, $2);}
+ // | '`' word brace {$$=tree2('`', $2, $3);}
+ w = nil;
+ tok = dropsp(yylex());
+ if(iswordtok(tok))
+ w = yyword(tok, &tok, 1);
+ t = tree2('`', w, brace(tok));
*ptok = yylex();
return t;
diff --git a/src/cmd/rc/pcmd.c b/src/cmd/rc/pcmd.c
index cae84737..89c30a18 100644
--- a/src/cmd/rc/pcmd.c
+++ b/src/cmd/rc/pcmd.c
@@ -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;
diff --git a/src/cmd/rc/syn.y b/src/cmd/rc/syn.y
index 5c98ef80..046f65d8 100644
--- a/src/cmd/rc/syn.y
+++ b/src/cmd/rc/syn.y
@@ -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