--- 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