Hello.

The trivial patch for add ';&' and ';;&' case break types in attach

test code:

foo() {
 case "$1" in
 a)   echo "case (a)" ;&
 a*)  echo "case (a*)" ;;&
 ab*) echo "case (ab*)" ;;
 *)   echo "default"
 esac
}

$ foo
default

$ foo b
default

$ foo a
case (a)
case (a*)
default

$ foo ab
case (a*)
case (ab*)

$ foo ad
case (a*)
default

$ foo abc
case (a*)
case (ab*)


--w
vodz
--- eval.c.orig 2021-02-04 00:38:55.261769233 +0400
+++ eval.c      2021-02-04 00:45:51.555756211 +0400
@@ -440,6 +440,7 @@
        union node *patp;
        struct arglist arglist;
        int status = 0;
+       int skipmatch = 0;

        errlinno = lineno = n->ncase.linno;
        if (funcline)
@@ -449,7 +450,7 @@
        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) 
{
-                       if (casematch(patp, arglist.list->text)) {
+                       if (skipmatch || casematch(patp, arglist.list->text)) {
                                /* Ensure body is non-empty as otherwise
                                 * EV_EXIT may prevent us from setting the
                                 * exit status.
@@ -458,7 +459,15 @@
                                        status = evaltree(cp->nclist.body,
                                                          flags);
                                }
-                               goto out;
+                               switch (cp->nclist.brk_type) {
+                               case 0:
+                                       goto out;
+                               case 1:
+                                       skipmatch = 1;
+                                       break;
+                               default:
+                                       skipmatch = 0;
+                               }
                        }
                }
        }
--- mktokens.orig       2021-02-04 00:26:31.252792506 +0400
+++ mktokens    2021-02-04 00:29:26.483787025 +0400
@@ -50,6 +50,8 @@
 TLP    0       "("
 TRP    1       ")"
 TENDCASE 1     ";;"
+TENDCSCONT 1   ";&"
+TENDCSNPAT 1   ";;&"
 TENDBQUOTE 1   "`"
 TREDIR 0       redirection
 TWORD  0       word
--- parser.c.orig       2021-02-04 00:31:56.372782336 +0400
+++ parser.c    2021-02-04 00:51:34.876964135 +0400
@@ -449,10 +449,14 @@

                        checkkwd = CHKNL | CHKKWD;
                        if ((t = readtoken()) != TESAC) {
-                               if (t != TENDCASE)
+                               if (t != TENDCASE &&
+                                   t != TENDCSCONT &&
+                                   t != TENDCSNPAT) {
                                        synexpect(TENDCASE);
-                               else
+                               } else {
+                                       cp->nclist.brk_type = t - TENDCASE;
                                        goto next_case;
+                               }
                        }
                }
                *cpp = NULL;
--- nodetypes.orig      2021-02-04 00:29:46.284786405 +0400
+++ nodetypes   2021-02-04 00:31:25.715783295 +0400
@@ -102,6 +102,7 @@
 
 NCLIST nclist                  # a case
        type      int
+       brk_type  int                   # 0 - ;;  1 - ;&  2 - ;;&
        next      nodeptr               # the next case in list
        pattern   nodeptr               # list of patterns for this case
        body      nodeptr               # code to execute for this case

Reply via email to