shithub: riscv

Download patch

ref: 3ec84c5d7364c8ed4602561743bf35e3b399e53d
parent: cabbe0a84c7aae53316347185a5bdf8095bac9c8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Jun 30 15:09:27 EDT 2016

rc: implement 9atoms ` split {command} syntax extension

--- a/sys/man/1/rc
+++ b/sys/man/1/rc
@@ -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
--- a/sys/src/cmd/rc/code.c
+++ b/sys/src/cmd/rc/code.c
@@ -125,9 +125,19 @@
 		emitf(Xconc);
 		break;
 	case '`':
+		emitf(Xmark);
+		if(c0){
+			outcode(c0, 0);
+			emitf(Xglob);
+		} else {
+			emitf(Xmark);
+			emitf(Xword);
+			emits(estrdup("ifs"));
+			emitf(Xdol);
+		}
 		emitf(Xbackq);
 		p = emiti(0);
-		outcode(c0, 0);
+		outcode(c1, 0);
 		emitf(Xexit);
 		stuffdot(p);
 		break;
--- a/sys/src/cmd/rc/exec.c
+++ b/sys/src/cmd/rc/exec.c
@@ -208,7 +208,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
--- a/sys/src/cmd/rc/havefork.c
+++ b/sys/src/cmd/rc/havefork.c
@@ -85,10 +85,11 @@
 	int pfd[2];
 	char *s, *wd, *ewd, *stop;
 	struct io *f;
-	var *ifs = vlook("ifs");
 	word *v, *nextv;
 
-	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;
@@ -135,6 +136,7 @@
 		free(wd);
 		closeio(f);
 		Waitfor(pid, 0);
+		poplist();	/* ditch split in "stop" */
 		/* v points to reversed arglist -- reverse it onto argv */
 		while(v){
 			nextv = v->next;
--- a/sys/src/cmd/rc/pcmd.c
+++ b/sys/src/cmd/rc/pcmd.c
@@ -32,7 +32,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;
--- a/sys/src/cmd/rc/syn.y
+++ b/sys/src/cmd/rc/syn.y
@@ -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