Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/bin/sh Implement the '; &' (used instead of '; ; ') case statem...



details:   https://anonhg.NetBSD.org/src/rev/18a68ba49d31
branches:  trunk
changeset: 823709:18a68ba49d31
user:      kre <kre%NetBSD.org@localhost>
date:      Thu May 04 04:37:51 2017 +0000

description:
Implement the ';&' (used instead of ';;') case statement list terminator
which causes fall through the to command list of the following pattern
(wuthout evaluating that pattern).   This has been approved for inclusion
in the next major version of the POSIX standard (Issue 8), and is
implemented by most other shells.

Now all form a circle and together attempt to summon the great wizd
in the hopes that his magic spells can transform the poor attempt
at documenting this feature into something rational...

diffstat:

 bin/sh/eval.c    |  24 ++++++++++++++++--------
 bin/sh/jobs.c    |  13 ++++++++++---
 bin/sh/mktokens  |   3 ++-
 bin/sh/nodetypes |   3 ++-
 bin/sh/parser.c  |  19 +++++++++++++------
 bin/sh/sh.1      |  26 +++++++++++++++++++++++---
 6 files changed, 66 insertions(+), 22 deletions(-)

diffs (233 lines):

diff -r 31720b20bada -r 18a68ba49d31 bin/sh/eval.c
--- a/bin/sh/eval.c     Wed May 03 21:39:27 2017 +0000
+++ b/bin/sh/eval.c     Thu May 04 04:37:51 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: eval.c,v 1.133 2017/05/03 05:49:54 kre Exp $   */
+/*     $NetBSD: eval.c,v 1.134 2017/05/04 04:37:51 kre Exp $   */
 
 /*-
  * Copyright (c) 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)eval.c     8.9 (Berkeley) 6/8/95";
 #else
-__RCSID("$NetBSD: eval.c,v 1.133 2017/05/03 05:49:54 kre Exp $");
+__RCSID("$NetBSD: eval.c,v 1.134 2017/05/04 04:37:51 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -456,7 +456,7 @@
 STATIC void
 evalcase(union node *n, int flags)
 {
-       union node *cp;
+       union node *cp, *ncp;
        union node *patp;
        struct arglist arglist;
        struct stackmark smark;
@@ -465,18 +465,26 @@
        setstackmark(&smark);
        arglist.lastp = &arglist.list;
        expandarg(n->ncase.expr, &arglist, EXP_TILDE);
-       for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
-               for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
+       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)) {
-                               if (evalskip == 0) {
-                                       evaltree(cp->nclist.body, flags);
+                               while (cp != NULL && evalskip == 0 &&
+                                   nflag == 0) {
+                                       if (cp->type == NCLISTCONT)
+                                               ncp = cp->nclist.next;
+                                       else
+                                               ncp = NULL;
+                                       evaltree(cp->nclist.body,
+                                           ncp ? (flags & ~EV_EXIT) | EV_MORE
+                                               : flags );
                                        status = exitstatus;
+                                       cp = ncp;
                                }
                                goto out;
                        }
                }
        }
-out:
+ out:
        exitstatus = status;
        popstackmark(&smark);
 }
diff -r 31720b20bada -r 18a68ba49d31 bin/sh/jobs.c
--- a/bin/sh/jobs.c     Wed May 03 21:39:27 2017 +0000
+++ b/bin/sh/jobs.c     Thu May 04 04:37:51 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: jobs.c,v 1.81 2017/05/03 21:31:03 kre Exp $    */
+/*     $NetBSD: jobs.c,v 1.82 2017/05/04 04:37:51 kre Exp $    */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)jobs.c     8.5 (Berkeley) 5/4/95";
 #else
-__RCSID("$NetBSD: jobs.c,v 1.81 2017/05/03 21:31:03 kre Exp $");
+__RCSID("$NetBSD: jobs.c,v 1.82 2017/05/04 04:37:51 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -1336,7 +1336,14 @@
                        cmdtxt(np->nclist.pattern);
                        cmdputs(") ");
                        cmdtxt(np->nclist.body);
-                       cmdputs(";; ");
+                       switch (n->type) {      /* switch (not if) for later */
+                       case NCLISTCONT:
+                               cmdputs(";& ");
+                               break;
+                       default:
+                               cmdputs(";; ");
+                               break;
+                       }
                }
                cmdputs("esac");
                break;
diff -r 31720b20bada -r 18a68ba49d31 bin/sh/mktokens
--- a/bin/sh/mktokens   Wed May 03 21:39:27 2017 +0000
+++ b/bin/sh/mktokens   Thu May 04 04:37:51 2017 +0000
@@ -1,5 +1,5 @@
 #!/bin/sh -
-#      $NetBSD: mktokens,v 1.12 2008/10/25 22:18:15 apb Exp $
+#      $NetBSD: mktokens,v 1.13 2017/05/04 04:37:51 kre Exp $
 #
 # Copyright (c) 1991, 1993
 #      The Regents of the University of California.  All rights reserved.
@@ -51,6 +51,7 @@
 TLP    0       "("
 TRP    1       ")"
 TENDCASE 1     ";;"
+TCASEFALL 1    ";&"
 TENDBQUOTE 1   "`"
 TREDIR 0       redirection
 TWORD  0       word
diff -r 31720b20bada -r 18a68ba49d31 bin/sh/nodetypes
--- a/bin/sh/nodetypes  Wed May 03 21:39:27 2017 +0000
+++ b/bin/sh/nodetypes  Thu May 04 04:37:51 2017 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: nodetypes,v 1.13 2009/05/26 07:30:51 joerg Exp $
+#      $NetBSD: nodetypes,v 1.14 2017/05/04 04:37:51 kre Exp $
 # Copyright (c) 1991, 1993
 #      The Regents of the University of California.  All rights reserved.
 #
@@ -95,6 +95,7 @@
        expr      nodeptr               # the word to switch on
        cases     nodeptr               # the list of cases (NCLIST nodes)
 
+NCLISTCONT nclist              # a case terminated by ';&' (fall through)
 NCLIST nclist                  # a case
        type      int
        next      nodeptr               # the next case in list
diff -r 31720b20bada -r 18a68ba49d31 bin/sh/parser.c
--- a/bin/sh/parser.c   Wed May 03 21:39:27 2017 +0000
+++ b/bin/sh/parser.c   Thu May 04 04:37:51 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: parser.c,v 1.122 2017/05/03 21:36:16 kre Exp $ */
+/*     $NetBSD: parser.c,v 1.123 2017/05/04 04:37:51 kre Exp $ */
 
 /*-
  * Copyright (c) 1991, 1993
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "@(#)parser.c   8.7 (Berkeley) 5/16/95";
 #else
-__RCSID("$NetBSD: parser.c,v 1.122 2017/05/03 21:36:16 kre Exp $");
+__RCSID("$NetBSD: parser.c,v 1.123 2017/05/04 04:37:51 kre Exp $");
 #endif
 #endif /* not lint */
 
@@ -469,10 +469,12 @@
 
                        checkkwd = 2;
                        if ((t = readtoken()) != TESAC) {
-                               if (t != TENDCASE) {
+                               if (t != TENDCASE && t != TCASEFALL) {
                                        noalias = 0;
                                        synexpect(TENDCASE, 0);
                                } else {
+                                       if (t == TCASEFALL)
+                                               cp->type = NCLISTCONT;
                                        noalias = 1;
                                        checkkwd = 2;
                                        readtoken();
@@ -1021,10 +1023,15 @@
                        pungetc();
                        RETURN(TPIPE);
                case ';':
-                       if (pgetc_linecont() == ';')
+                       switch (pgetc_linecont()) {
+                       case ';':
                                RETURN(TENDCASE);
-                       pungetc();
-                       RETURN(TSEMI);
+                       case '&':
+                               RETURN(TCASEFALL);
+                       default:
+                               pungetc();
+                               RETURN(TSEMI);
+                       }
                case '(':
                        RETURN(TLP);
                case ')':
diff -r 31720b20bada -r 18a68ba49d31 bin/sh/sh.1
--- a/bin/sh/sh.1       Wed May 03 21:39:27 2017 +0000
+++ b/bin/sh/sh.1       Thu May 04 04:37:51 2017 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: sh.1,v 1.134 2017/05/03 00:43:22 kre Exp $
+.\"    $NetBSD: sh.1,v 1.135 2017/05/04 04:37:51 kre Exp $
 .\" Copyright (c) 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
 .\"
@@ -31,7 +31,7 @@
 .\"
 .\"    @(#)sh.1        8.6 (Berkeley) 5/4/95
 .\"
-.Dd April 29, 2017
+.Dd May 4, 2017
 .Dt SH 1
 .ds flags abCEeFfhnuvxIimpqV
 .Os
@@ -807,7 +807,8 @@
 The syntax of the case command is
 .Bd -literal -offset indent
 case word in
-pattern) list ;;
+[(] pattern ) list ;&
+[(] pattern ) list ;;
 \&...
 esac
 .Ed
@@ -817,6 +818,25 @@
 described later), separated by
 .Dq \*(Ba
 characters.
+.Pp
+Word is expanded and matched against each pattern in turn,
+from first to last,
+with each pattern being expanded just before the match is attempted.
+When a match is found, pattern comparisons cease, and the associated
+.Dq list
+(which may be empty)
+is evaluated.
+If the list is terminated with
+.Dq \&;&
+execution then falls through to the following list, if any,
+without evaluating its pattern, or attempting a match.
+When a list terminated with
+.Dq \&;;
+has been executed, or when
+.Dv esac
+is reached execution of the case statement is complete.
+The exit status is that of the last command executed
+from the last list evaluated, if any, or zero otherwise.
 .Ss Grouping Commands Together
 Commands may be grouped by writing either
 .Pp



Home | Main Index | Thread Index | Old Index