From 24c3d77e3ca364b6cd66e4a6a6766823e0b48d89 Mon Sep 17 00:00:00 2001 From: Martijn Dekker Date: Sun, 3 Jul 2022 12:21:51 +0200 Subject: [PATCH] cleanup: remove redundant sh.st.execbrk flag The 'break' and 'continue' flow control commands use three int variables in the scoped sh.st struct: sh.st.execbrk: nonzero if 'break' or 'continue' are used sh.st.breakcnt: number of levels to 'break'/'continue' (negative if 'continue') sh.st.loopcnt: loop level counter for 'break'/'continue' Reading the code that sets and uses these (in bltins/cflow.c and sh/xec.c) makes it fairly obvious that the sh.st.execbrk flag is redundant; it is zero if no 'break' or 'continue' should happen, but the same is true for sh.st.breakcnt. This commit simplifies the code by removing sh.st.execbrk. It also adds some comments clarifying the use of the other two. Trivia: the ancient "Version 06/03/86a" ksh source code was recently discovered. It uses global execbrk, breakcnt and loopcnt variables with the same redundancy. More evidence that the AT&T team always lacked a question-everything department... https://minnie.tuhs.org/pipermail/tuhs/2020-December/022640.html https://github.com/weiss/original-bsd/blob/master/local/toolchest/ksh/sh/builtin.c https://github.com/weiss/original-bsd/blob/master/local/toolchest/ksh/sh/xec.c --- src/cmd/ksh93/bltins/cflow.c | 2 +- src/cmd/ksh93/include/shell.h | 5 ++--- src/cmd/ksh93/sh/main.c | 4 ++-- src/cmd/ksh93/sh/xec.c | 20 ++++++++++++-------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/src/cmd/ksh93/bltins/cflow.c b/src/cmd/ksh93/bltins/cflow.c index cc3e99f36..2e0582b77 100644 --- a/src/cmd/ksh93/bltins/cflow.c +++ b/src/cmd/ksh93/bltins/cflow.c @@ -128,7 +128,7 @@ int b_break(register int n, register char *argv[],Shbltin_t *context) } if(sh.st.loopcnt) { - sh.st.execbrk = sh.st.breakcnt = n; + sh.st.breakcnt = n; if(sh.st.breakcnt > sh.st.loopcnt) sh.st.breakcnt = sh.st.loopcnt; if(cont) diff --git a/src/cmd/ksh93/include/shell.h b/src/cmd/ksh93/include/shell.h index 406b9b424..da2e426a5 100644 --- a/src/cmd/ksh93/include/shell.h +++ b/src/cmd/ksh93/include/shell.h @@ -193,9 +193,8 @@ struct sh_scoped Dt_t *var_local; /* local level variables for name() */ struct slnod *staklist; /* link list of function stacks */ int states; /* shell state bits used by sh_isstate(), etc. */ - int breakcnt; - int execbrk; - int loopcnt; + int breakcnt; /* number of levels to 'break'/'continue' (negative if 'continue') */ + int loopcnt; /* loop level counter for 'break'/'continue' */ int firstline; int32_t optindex; int32_t optnum; diff --git a/src/cmd/ksh93/sh/main.c b/src/cmd/ksh93/sh/main.c index 1ae64ec08..c8b2d7439 100644 --- a/src/cmd/ksh93/sh/main.c +++ b/src/cmd/ksh93/sh/main.c @@ -437,7 +437,7 @@ static void exfile(register Sfio_t *iop,register int fno) sh_iorestore(0,jmpval); hist_flush(sh.hist_ptr); sfsync(sh.outpool); - sh.st.execbrk = sh.st.breakcnt = 0; + sh.st.breakcnt = 0; /* check for return from profile or env file */ if(sh_isstate(SH_PROFILE) && (jmpval==SH_JMPFUN || jmpval==SH_JMPEXIT)) { @@ -604,7 +604,7 @@ static void exfile(register Sfio_t *iop,register int fno) { execflags |= sh_state(SH_NOFORK); } - sh.st.execbrk = 0; + sh.st.breakcnt = 0; sh_exec(t,execflags); if(sh.forked) { diff --git a/src/cmd/ksh93/sh/xec.c b/src/cmd/ksh93/sh/xec.c index 9baf6efe7..319b77db4 100644 --- a/src/cmd/ksh93/sh/xec.c +++ b/src/cmd/ksh93/sh/xec.c @@ -920,7 +920,7 @@ int sh_exec(register const Shnode_t *t, int flags) { Stk_t *stkp = sh.stk; sh_sigcheck(); - if(t && !sh.st.execbrk && !sh_isoption(SH_NOEXEC)) + if(t && sh.st.breakcnt==0 && !sh_isoption(SH_NOEXEC)) { register int type = t->tre.tretyp; register char *com0 = 0; @@ -2045,7 +2045,7 @@ int sh_exec(register const Shnode_t *t, int flags) nameref = nv_isref(np)!=0; sh.st.loopcnt++; cp = *args; - while(cp && sh.st.execbrk==0) + while(cp && sh.st.breakcnt==0) { if(t->tre.tretyp&COMSCAN) { @@ -2115,8 +2115,9 @@ int sh_exec(register const Shnode_t *t, int flags) else cp = *++args; check: + /* decrease 'continue' level */ if(sh.st.breakcnt<0) - sh.st.execbrk = (++sh.st.breakcnt !=0); + sh.st.breakcnt++; } #if SHOPT_OPTIMIZE endfor: @@ -2126,8 +2127,9 @@ int sh_exec(register const Shnode_t *t, int flags) if(jmpval) siglongjmp(*sh.jmplist,jmpval); #endif /* SHOPT_OPTIMIZE */ + /* decrease 'break' level */ if(sh.st.breakcnt>0) - sh.st.execbrk = (--sh.st.breakcnt !=0); + sh.st.breakcnt--; sh.st.loopcnt--; sh_argfree(argsav,0); break; @@ -2171,7 +2173,7 @@ int sh_exec(register const Shnode_t *t, int flags) } #endif /* SHOPT_FILESCAN */ sh.st.loopcnt++; - while(sh.st.execbrk==0) + while(sh.st.breakcnt==0) { #if SHOPT_FILESCAN if(iop) @@ -2184,10 +2186,11 @@ int sh_exec(register const Shnode_t *t, int flags) if((sh_exec(tt,first)==0)!=(type==TWH)) break; r = sh_exec(t->wh.dotre,first|errorflg); + /* decrease 'continue' level */ if(sh.st.breakcnt<0) - sh.st.execbrk = (++sh.st.breakcnt !=0); + sh.st.breakcnt++; /* This is for the arithmetic for */ - if(sh.st.execbrk==0 && t->wh.whinc) + if(sh.st.breakcnt==0 && t->wh.whinc) sh_exec((Shnode_t*)t->wh.whinc,first); first = 0; errorflg &= ~OPTIMIZE_FLAG; @@ -2205,8 +2208,9 @@ int sh_exec(register const Shnode_t *t, int flags) if(jmpval) siglongjmp(*sh.jmplist,jmpval); #endif /* SHOPT_OPTIMIZE */ + /* decrease 'break' level */ if(sh.st.breakcnt>0) - sh.st.execbrk = (--sh.st.breakcnt !=0); + sh.st.breakcnt--; sh.st.loopcnt--; sh.exitval= r; #if SHOPT_FILESCAN