1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-02-13 19:52:20 +00:00

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
This commit is contained in:
Martijn Dekker 2022-07-03 12:21:51 +02:00
parent 400806afa6
commit 24c3d77e3c
4 changed files with 17 additions and 14 deletions

View file

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

View file

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

View file

@ -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)
{

View file

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