From: svav2021@gmail.com
To: herbert@gondor.apana.org.au
Cc: dash@vger.kernel.org, Arav Verma <svav2021@gmail.com>
Subject: [PATCH] case: Implement fallthrough (;&) operator
Date: Sun, 23 Aug 2026 13:26:35 -0500 [thread overview]
Message-ID: <20260823182703.31754-1-svav2021@gmail.com> (raw)
From: Arav Verma <svav2021@gmail.com>
Add support for the fallthrough operator, as specified
in POSIX.1-2024, (defect 449). The ;& operator allows
execution to continue to the next case pattern without
re-evaluating the switch expression
Signed-off-by: Arav Verma <svav2021@gmail.com>
---
src/eval.c | 35 +++++++++++++++++++++++++----------
src/mktokens | 1 +
src/parser.c | 14 ++++++++++----
3 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/src/eval.c b/src/eval.c
index 0f2a7ba..f9acea5 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -451,6 +451,7 @@ evalcase(union node *n, int flags)
union node *patp;
struct arglist arglist;
int status = 0;
+ int fallthrough = 0;
errlinno = lineno = n->ncase.linno;
if (funcline)
@@ -460,19 +461,33 @@ evalcase(union node *n, int flags)
expandarg(n->ncase.expr, &arglist, FNMATCH_IS_ENABLED ? EXP_TILDE :
EXP_TILDE | EXP_MBCHAR);
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)) {
- /* Ensure body is non-empty as otherwise
- * EV_EXIT may prevent us from setting the
- * exit status.
- */
- if (evalskip == 0 && cp->nclist.body) {
- status = evaltree(cp->nclist.body,
- flags);
+ int matched = 0;
+
+ if (fallthrough) {
+ matched = 1;
+ } else {
+ for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
+ if (casematch(patp, arglist.list->text)) {
+ matched = 1;
+ break;
}
- goto out;
}
}
+ if (matched) {
+ int terminator = cp->type >> 8;
+ if (evalskip == 0 && cp->nclist.body) {
+ int eval_flags = flags;
+ if (terminator == TFALLTHRU)
+ eval_flags &= ~EV_EXIT;
+ status = evaltree(cp->nclist.body, eval_flags);
+ if (terminator != TFALLTHRU)
+ goto out;
+ } else if (terminator != TFALLTHRU)
+ goto out;
+
+ if (terminator == TFALLTHRU)
+ fallthrough = 1;
+ }
}
out:
return status;
diff --git a/src/mktokens b/src/mktokens
index dcef676..b7cd0ff 100644
--- a/src/mktokens
+++ b/src/mktokens
@@ -51,6 +51,7 @@ TPIPE 0 "|"
TLP 0 "("
TRP 1 ")"
TENDCASE 1 ";;"
+TFALLTHRU 1 ";&"
TENDBQUOTE 1 "`"
TREDIR 0 redirection
TWORD 0 word
diff --git a/src/parser.c b/src/parser.c
index e44b3c3..ede908f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -463,10 +463,12 @@ next_case:
checkkwd = CHKNL | CHKKWD;
if ((t = readtoken()) != TESAC) {
- if (t != TENDCASE)
+ if (t != TENDCASE && t != TFALLTHRU)
synexpect(TENDCASE);
- else
+ else {
+ cp->type = NCLIST | (t << 8);
goto next_case;
+ }
}
}
*cpp = NULL;
@@ -833,11 +835,15 @@ xxreadtoken(void)
RETURN(TOR);
pungetc();
RETURN(TPIPE);
- case ';':
- if (pgetc_eatbnl() == ';')
+ case ';': {
+ int nextc = pgetc_eatbnl();
+ if (nextc == ';')
RETURN(TENDCASE);
+ else if (nextc == '&')
+ RETURN(TFALLTHRU);
pungetc();
RETURN(TSEMI);
+ }
case '(':
RETURN(TLP);
case ')':
--
2.47.3
reply other threads:[~2026-08-23 18:27 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260823182703.31754-1-svav2021@gmail.com \
--to=svav2021@gmail.com \
--cc=dash@vger.kernel.org \
--cc=herbert@gondor.apana.org.au \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox