* SUCH DAMAGE.
*
* @(#)eval.c 8.9 (Berkeley) 6/8/95
- * $FreeBSD: src/bin/sh/eval.c,v 1.110 2011/06/16 21:50:28 jilles Exp $
+ * $FreeBSD: src/bin/sh/eval.c,v 1.111 2011/06/17 13:03:49 jilles Exp $
*/
#include <sys/time.h>
for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
if (casematch(patp, arglist.list->text)) {
+ while (cp->nclist.next &&
+ cp->type == NCLISTFALLTHRU) {
+ if (evalskip != 0)
+ break;
+ evaltree(cp->nclist.body,
+ flags & ~EV_EXIT);
+ cp = cp->nclist.next;
+ }
if (evalskip == 0) {
evaltree(cp->nclist.body, flags);
}
# SUCH DAMAGE.
#
# @(#)mktokens 8.1 (Berkeley) 5/31/93
-# $FreeBSD: src/bin/sh/mktokens,v 1.11 2011/05/22 15:24:56 jilles Exp $
+# $FreeBSD: src/bin/sh/mktokens,v 1.12 2011/06/17 13:03:49 jilles Exp $
# The following is a list of tokens. The second column is nonzero if the
# token marks the end of a list. The third column is the name to print in
TLP 0 "("
TRP 1 ")"
TENDCASE 1 ";;"
+TFALLTHRU 1 ";&"
TREDIR 0 redirection
TWORD 0 word
TIF 0 "if"
# SUCH DAMAGE.
#
# @(#)nodetypes 8.2 (Berkeley) 5/4/95
-# $FreeBSD: src/bin/sh/nodetypes,v 1.10 2005/01/10 08:39:25 imp Exp $
+# $FreeBSD: src/bin/sh/nodetypes,v 1.11 2011/06/17 13:03:49 jilles Exp $
# This file describes the nodes used in parse trees. Unindented lines
# contain a node type followed by a structure tag. Subsequent indented
expr nodeptr # the word to switch on
cases nodeptr # the list of cases (NCLIST nodes)
-NCLIST nclist # a case
+NCLIST nclist # a case ending with ;;
type int
next nodeptr # the next case in list
pattern nodeptr # list of patterns for this case
body nodeptr # code to execute for this case
+NCLISTFALLTHRU nclist # a case ending with ;&
NDEFUN narg # define a function. The "next" field contains
# the body of the function.
* SUCH DAMAGE.
*
* @(#)parser.c 8.7 (Berkeley) 5/16/95
- * $FreeBSD: src/bin/sh/parser.c,v 1.113 2011/06/09 23:12:23 jilles Exp $
+ * $FreeBSD: src/bin/sh/parser.c,v 1.114 2011/06/17 13:03:49 jilles Exp $
*/
#include <stdio.h>
checkkwd = CHKNL | CHKKWD | CHKALIAS;
if ((t = readtoken()) != TESAC) {
- if (t != TENDCASE)
- synexpect(TENDCASE);
+ if (t == TENDCASE)
+ ;
+ else if (t == TFALLTHRU)
+ cp->type = NCLISTFALLTHRU;
else
- checkkwd = CHKNL | CHKKWD, readtoken();
+ synexpect(TENDCASE);
+ checkkwd = CHKNL | CHKKWD, readtoken();
}
cpp = &cp->nclist.next;
}
pungetc();
RETURN(TPIPE);
case ';':
- if (pgetc() == ';')
+ c = pgetc();
+ if (c == ';')
RETURN(TENDCASE);
+ else if (c == '&')
+ RETURN(TFALLTHRU);
pungetc();
RETURN(TSEMI);
case '(':
.\" SUCH DAMAGE.
.\"
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
-.\" $FreeBSD: src/bin/sh/sh.1,v 1.169 2011/06/15 21:48:10 jilles Exp $
+.\" $FreeBSD: src/bin/sh/sh.1,v 1.170 2011/06/17 13:03:49 jilles Exp $
.\"
.Dd August 21, 2011
.Dt SH 1
.It Control operators:
.Bl -column "XXX" "XXX" "XXX" "XXX" "XXX" -offset center -compact
.It Li & Ta Li && Ta Li ( Ta Li ) Ta Li \en
-.It Li ;; Ta Li ; Ta Li | Ta Li ||
+.It Li ;; Ta Li ;& Ta Li ; Ta Li | Ta Li ||
.El
.It Redirection operators:
.Bl -column "XXX" "XXX" "XXX" "XXX" "XXX" -offset center -compact
separated by
.Ql \&|
characters.
+If the selected list is terminated by the control operator
+.Ql ;&
+instead of
+.Ql ;; ,
+execution continues with the next list.
The exit code of the
.Ic case
command is the exit code of the last command executed in the list or
--- /dev/null
+# $FreeBSD: src/tools/regression/bin/sh/builtins/case9.0,v 1.1 2011/06/17 13:03:49 jilles Exp $
+
+errors=0
+
+f() {
+ result=
+ case $1 in
+ a) result=${result}a ;;
+ b) result=${result}b ;&
+ c) result=${result}c ;&
+ d) result=${result}d ;;
+ e) result=${result}e ;&
+ esac
+}
+
+check() {
+ f "$1"
+ if [ "$result" != "$2" ]; then
+ printf "For %s, expected %s got %s\n" "$1" "$2" "$result"
+ errors=$((errors + 1))
+ fi
+}
+
+check '' ''
+check a a
+check b bcd
+check c cd
+check d d
+check e e
+
+if ! (case 1 in
+ 1) false ;&
+ 2) true ;;
+esac) then
+ echo "Subshell bad"
+ errors=$((errors + 1))
+fi
+
+exit $((errors != 0))