commit b3b9943da25aa0f86e2542c6846142aeeaa0cfe5
parent 7d179ce096c89963deae835327596de435e66cdf
Author: Toby Goodwin <toby@paccrat.org>
Date: Mon, 5 Mar 2018 06:51:31 +0000
implement walk half of if not, plus tests
Diffstat:
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/trip.rc b/trip.rc
@@ -17,8 +17,11 @@ fn expect {
fn submatch {
if (!~ $#* 3)
fail incorrect invocation of submatch
- prompt=$nl if (!~ `` $nl {$rc -ic $1>[2=1]} $2)
+ got = `` $nl { prompt=$nl $rc -ic $1>[2=1] }
+ if (!~ $got $2) {
+ echo got $got expected $2
fail $3
+ }
}
fn sigexit sigint sigquit sigsegv
fn sigexit {
@@ -675,7 +678,7 @@ if (!~ $^L 'a c e f') {
}
# test support for unquoted =
-submatch 'echo foo = bar' 'foo = bar' 'unquoted equals 2'
+submatch 'echo foo = bar' 'foo = bar' 'unquoted equals 1'
submatch 'echo foo=bar' 'foo=bar' 'unquoted equals 2'
submatch 'echo foo=' 'foo=' 'unquoted equals 3'
submatch 'echo =bar; whatis -v echo' 'echo=bar' 'unquoted equals 4'
@@ -700,3 +703,7 @@ $rc -ec 'X=`{false}'
if (~ $status 0) {
fail '"rc -e" exits with zero status when backquote command returns non-zero'
}
+
+# exercise "if not"
+submatch 'if (false) echo foo; if not echo bar' 'bar' 'if not 1'
+submatch 'if (false) echo foo; echo qux; if not echo bar' 'rc: `if not'' must follow `if''' 'if not 2'
diff --git a/walk.c b/walk.c
@@ -18,6 +18,7 @@ static bool isallpre(Node *);
static bool dofork(bool);
static void dopipe(Node *);
static void loop_body(Node* n);
+static int if_state = 2; /* last if, for "if not" interactive top-level */
/* Tail-recursive version of walk() */
@@ -33,6 +34,7 @@ top: sigchk();
set(TRUE);
return TRUE;
}
+ if (parent && n->type != nIfnot) if_state = 2;
switch (n->type) {
case nArgs: case nBackq: case nConcat: case nCount:
case nFlat: case nLappend: case nRedir: case nVar:
@@ -96,10 +98,17 @@ top: sigchk();
true_cmd = true_cmd->u[0].p;
}
cond = TRUE;
- if (!walk(n->u[0].p, TRUE))
- true_cmd = false_cmd; /* run the else clause */
+ if_state = walk(n->u[0].p, TRUE);
cond = oldcond;
- WALK(true_cmd, parent);
+ WALK(if_state ? true_cmd : false_cmd, parent);
+ }
+ case nIfnot: {
+ if (if_state == 2)
+ rc_error("`if not' must follow `if'");
+ if (if_state == 0)
+ walk(n->u[0].p, TRUE);
+ if_state = 2;
+ break;
}
case nWhile: {
Jbwrap break_jb;