svn commit: r223186 - in head: bin/sh
tools/regression/bin/sh/builtins
Jilles Tjoelker
jilles at FreeBSD.org
Fri Jun 17 13:03:49 UTC 2011
Author: jilles
Date: Fri Jun 17 13:03:49 2011
New Revision: 223186
URL: http://svn.freebsd.org/changeset/base/223186
Log:
sh: Add case statement fallthrough (with ';&' instead of ';;').
Replacing ;; with the new control operator ;& will cause the next list to be
executed as well without checking its pattern, continuing until a list ends
with ;; or until the end of the case statement. This is like omitting
"break" in a C "switch" statement.
The sequence ;& was formerly invalid.
This feature is proposed for the next POSIX issue in Austin Group issue
#449.
Added:
head/tools/regression/bin/sh/builtins/case9.0 (contents, props changed)
Modified:
head/bin/sh/eval.c
head/bin/sh/mktokens
head/bin/sh/nodetypes
head/bin/sh/parser.c
head/bin/sh/sh.1
Modified: head/bin/sh/eval.c
==============================================================================
--- head/bin/sh/eval.c Fri Jun 17 12:12:52 2011 (r223185)
+++ head/bin/sh/eval.c Fri Jun 17 13:03:49 2011 (r223186)
@@ -386,6 +386,14 @@ evalcase(union node *n, int flags)
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);
}
Modified: head/bin/sh/mktokens
==============================================================================
--- head/bin/sh/mktokens Fri Jun 17 12:12:52 2011 (r223185)
+++ head/bin/sh/mktokens Fri Jun 17 13:03:49 2011 (r223186)
@@ -50,6 +50,7 @@ TPIPE 0 "|"
TLP 0 "("
TRP 1 ")"
TENDCASE 1 ";;"
+TFALLTHRU 1 ";&"
TREDIR 0 redirection
TWORD 0 word
TIF 0 "if"
Modified: head/bin/sh/nodetypes
==============================================================================
--- head/bin/sh/nodetypes Fri Jun 17 12:12:52 2011 (r223185)
+++ head/bin/sh/nodetypes Fri Jun 17 13:03:49 2011 (r223186)
@@ -96,12 +96,13 @@ NCASE ncase # a case statement
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.
Modified: head/bin/sh/parser.c
==============================================================================
--- head/bin/sh/parser.c Fri Jun 17 12:12:52 2011 (r223185)
+++ head/bin/sh/parser.c Fri Jun 17 13:03:49 2011 (r223186)
@@ -542,10 +542,13 @@ TRACE(("expecting DO got %s %s\n", tokna
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;
}
@@ -931,8 +934,11 @@ xxreadtoken(void)
pungetc();
RETURN(TPIPE);
case ';':
- if (pgetc() == ';')
+ c = pgetc();
+ if (c == ';')
RETURN(TENDCASE);
+ else if (c == '&')
+ RETURN(TFALLTHRU);
pungetc();
RETURN(TSEMI);
case '(':
Modified: head/bin/sh/sh.1
==============================================================================
--- head/bin/sh/sh.1 Fri Jun 17 12:12:52 2011 (r223185)
+++ head/bin/sh/sh.1 Fri Jun 17 13:03:49 2011 (r223186)
@@ -32,7 +32,7 @@
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
.\" $FreeBSD$
.\"
-.Dd June 15, 2011
+.Dd June 17, 2011
.Dt SH 1
.Os
.Sh NAME
@@ -372,7 +372,7 @@ The following is a list of valid operato
.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
@@ -990,6 +990,11 @@ described later),
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
Added: head/tools/regression/bin/sh/builtins/case9.0
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/tools/regression/bin/sh/builtins/case9.0 Fri Jun 17 13:03:49 2011 (r223186)
@@ -0,0 +1,39 @@
+# $FreeBSD$
+
+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))
More information about the svn-src-head
mailing list