svn commit: r230161 - in head: bin/sh
tools/regression/bin/sh/builtins
Jilles Tjoelker
jilles at FreeBSD.org
Sun Jan 15 21:39:39 UTC 2012
Author: jilles
Date: Sun Jan 15 21:39:38 2012
New Revision: 230161
URL: http://svn.freebsd.org/changeset/base/230161
Log:
sh: Fix some bugs with exit status from case containing ;&.
Also, rework evalcase() to not evaluate any tree. Instead, return the
NCLISTFALLTHRU node and handle it in evaltree().
Fixed bugs:
* If a ;& list with non-zero exit status is followed by an empty ;; or final
list, the exit status of the case command should be equal to the exit
status of the ;& list, not 0.
* An empty ;& case should not reset $?.
Added:
head/tools/regression/bin/sh/builtins/case17.0 (contents, props changed)
head/tools/regression/bin/sh/builtins/case18.0 (contents, props changed)
head/tools/regression/bin/sh/builtins/case19.0 (contents, props changed)
Modified:
head/bin/sh/eval.c
Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c Sun Jan 15 20:53:50 2012 (r230160)
+++ head/bin/sh/eval.c Sun Jan 15 21:39:38 2012 (r230161)
@@ -89,7 +89,7 @@ int oexitstatus; /* saved exit status *
static void evalloop(union node *, int);
static void evalfor(union node *, int);
-static union node *evalcase(union node *, int);
+static union node *evalcase(union node *);
static void evalsubshell(union node *, int);
static void evalredir(union node *, int);
static void expredir(union node *);
@@ -256,7 +256,18 @@ evaltree(union node *n, int flags)
evalfor(n, flags & ~EV_EXIT);
break;
case NCASE:
- next = evalcase(n, flags);
+ next = evalcase(n);
+ break;
+ case NCLIST:
+ next = n->nclist.body;
+ break;
+ case NCLISTFALLTHRU:
+ if (n->nclist.body) {
+ evaltree(n->nclist.body, flags & ~EV_EXIT);
+ if (evalskip)
+ goto out;
+ }
+ next = n->nclist.next;
break;
case NDEFUN:
defun(n->narg.text, n->narg.next);
@@ -366,9 +377,14 @@ evalfor(union node *n, int flags)
}
+/*
+ * Evaluate a case statement, returning the selected tree.
+ *
+ * The exit status needs care to get right.
+ */
static union node *
-evalcase(union node *n, int flags)
+evalcase(union node *n)
{
union node *cp;
union node *patp;
@@ -384,13 +400,12 @@ evalcase(union node *n, int flags)
if (casematch(patp, arglist.list->text)) {
popstackmark(&smark);
while (cp->nclist.next &&
- cp->type == NCLISTFALLTHRU) {
- evaltree(cp->nclist.body,
- flags & ~EV_EXIT);
- if (evalskip != 0)
- return (NULL);
+ cp->type == NCLISTFALLTHRU &&
+ cp->nclist.body == NULL)
cp = cp->nclist.next;
- }
+ if (cp->nclist.next &&
+ cp->type == NCLISTFALLTHRU)
+ return (cp);
if (cp->nclist.body == NULL)
exitstatus = 0;
return (cp->nclist.body);
Added: head/tools/regression/bin/sh/builtins/case17.0
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/case17.0 Sun Jan 15 21:39:38 2012 (r230161)
@@ -0,0 +1,3 @@
+# $FreeBSD$
+
+! case x in x) false ;& y) esac
Added: head/tools/regression/bin/sh/builtins/case18.0
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/case18.0 Sun Jan 15 21:39:38 2012 (r230161)
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+case x$(false) in
+x) ;&
+y) [ $? != 0 ] ;;
+z) false ;;
+esac
Added: head/tools/regression/bin/sh/builtins/case19.0
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/case19.0 Sun Jan 15 21:39:38 2012 (r230161)
@@ -0,0 +1,7 @@
+# $FreeBSD$
+
+[ "`case x in
+x) false ;&
+y) ;&
+z) echo $? ;;
+esac`" != 0 ]
More information about the svn-src-all
mailing list