1
0
Fork 0
mirror of git://git.code.sf.net/p/cdesktopenv/code synced 2025-03-09 15:50:02 +00:00

[v1.0] Remove experimental .getn discipline

*.getn discipline functions cause .sh.value to have a float type
for arithmetic expressions that get the value of foo, avoiding the
problem of having to convert between floats and strings (e.g.
rounding errors). There is no corresponding .setn discipline.

A search in the ast-open-archive repo reveals that the getn
discipline was quietly added in version 2009-08-21 93t+, with not
even a mention in the RELEASE file.

The one available mention on the internet is this old thread:
https://www.mail-archive.com/ast-users@research.att.com/msg00601.html
Apparently a setn discipline *was* planned, but never implemented.

getn discipline functions may also crash in several ways. I've been
unsuccessful at solving all the crashes, particularly as one of
them is intermittent. This should not be in the 1.0 release.

Further discussion: https://github.com/ksh93/ksh/issues/435
This commit is contained in:
Martijn Dekker 2022-07-16 05:30:47 +02:00
parent a2c24282a7
commit 42fc5c4c0d
3 changed files with 15 additions and 55 deletions

View file

@ -109,7 +109,7 @@ const struct shtable2 shtab_variables[] =
"", 0, (char*)0
};
const char *nv_discnames[] = { "get", "set", "append", "unset", "getn", 0 };
const char *nv_discnames[] = { "get", "set", "append", "unset", 0 };
#if SHOPT_STATS
const Shtable_t shtab_stats[] =

View file

@ -154,16 +154,15 @@ void nv_putv(Namval_t *np, const char *value, int flags, register Namfun_t *nfp)
}
}
#define LOOKUPS 0
#define LOOKUP 0
#define ASSIGN 1
#define APPEND 2
#define UNASSIGN 3
#define LOOKUPN 4
struct vardisc
{
Namfun_t fun;
Namval_t *disc[5];
Namval_t *disc[4];
};
struct blocked
@ -290,8 +289,8 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
savelex = *lexp;
sh_lexopen(lexp, 0); /* needs full init (0), not what it calls reinit (1) */
block(bp,type);
if(bflag = (type==APPEND && !isblocked(bp,LOOKUPS)))
block(bp,LOOKUPS);
if(bflag = (type==APPEND && !isblocked(bp,LOOKUP)))
block(bp,LOOKUP);
sh_pushcontext(&checkpoint, 1);
jmpval = sigsetjmp(checkpoint.buff, 0);
if(!jmpval)
@ -301,7 +300,7 @@ static void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
sh_iorestore(checkpoint.topfd, jmpval);
unblock(bp,type);
if(bflag)
unblock(bp,LOOKUPS);
unblock(bp,LOOKUP);
if(!vp->disc[type])
chktfree(np,vp);
*lexp = savelex;
@ -378,15 +377,15 @@ done:
* This function executes a lookup disc and then performs
* the lookup on the given node <np>
*/
static char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
static char* lookup(Namval_t *np, Namfun_t *handle)
{
register struct vardisc *vp = (struct vardisc*)handle;
struct blocked block, *bp = block_info(np, &block);
register Namval_t *nq = vp->disc[type];
register Namval_t *nq = vp->disc[LOOKUP];
register char *cp=0;
Namval_t node;
union Value *up = np->nvalue.up;
if(nq && !isblocked(bp,type))
if(nq && !isblocked(bp,LOOKUP))
{
struct checkpt checkpoint;
int jmpval;
@ -401,12 +400,7 @@ static char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
nv_onattr(SH_VALNOD,NV_NOFREE);
_nv_unset(SH_VALNOD,0);
}
if(type==LOOKUPN)
{
nv_onattr(SH_VALNOD,NV_DOUBLE|NV_INTEGER);
nv_setsize(SH_VALNOD,10);
}
block(bp,type);
block(bp,LOOKUP);
block(bp, UNASSIGN); /* make sure nv_setdisc doesn't invalidate 'vp' by freeing it */
sh_pushcontext(&checkpoint, 1);
jmpval = sigsetjmp(checkpoint.buff, 0);
@ -416,15 +410,10 @@ static char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
if(sh.topfd != checkpoint.topfd)
sh_iorestore(checkpoint.topfd, jmpval);
unblock(bp,UNASSIGN);
unblock(bp,type);
if(!vp->disc[type])
unblock(bp,LOOKUP);
if(!vp->disc[LOOKUP])
chktfree(np,vp);
if(type==LOOKUPN)
{
cp = (char*)(SH_VALNOD->nvalue.cp);
*dp = nv_getnum(SH_VALNOD);
}
else if(cp = nv_getval(SH_VALNOD))
if(cp = nv_getval(SH_VALNOD))
cp = stkcopy(stkstd,cp);
_nv_unset(SH_VALNOD,NV_RDONLY);
if(!nv_isnull(&node))
@ -438,12 +427,7 @@ static char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
if(nv_isarray(np))
np->nvalue.up = up;
if(!cp)
{
if(type==LOOKUPS)
cp = nv_getv(np,handle);
else
*dp = nv_getn(np,handle);
}
cp = nv_getv(np,handle);
if(bp== &block)
block_done(bp);
if(nq && nq->nvalue.rp && nq->nvalue.rp->running==1)
@ -454,19 +438,6 @@ static char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
return(cp);
}
static char* lookups(Namval_t *np, Namfun_t *handle)
{
return(lookup(np,LOOKUPS,(Sfdouble_t*)0,handle));
}
static Sfdouble_t lookupn(Namval_t *np, Namfun_t *handle)
{
Sfdouble_t d;
lookup(np,LOOKUPN, &d ,handle);
return(d);
}
/*
* Set disc on given <event> to <action>
* If action==np, the current disc is returned
@ -561,10 +532,7 @@ char *nv_setdisc(register Namval_t* np,register const char *event,Namval_t *acti
else if(action && np!=SH_LEVELNOD)
{
Namdisc_t *dp = (Namdisc_t*)vp->fun.disc;
if(type==LOOKUPS)
dp->getval = lookups;
else if(type==LOOKUPN)
dp->getnum = lookupn;
dp->getval = lookup;
vp->disc[type] = action;
}
else

View file

@ -1368,14 +1368,6 @@ got=$("$SHELL" -c $'foo=baz; foo+=_foo "$SHELL" -c \'print $foo\'; print $foo')
[[ $exp == "$got" ]] || err_exit "using the += operator for invocation-local assignments changes variables outside of the invocation-local scope" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
# Crash when setting attribute after getn (numeric get) discipline
# https://github.com/ksh93/ksh/issues/435#issuecomment-1148813866
got=$("$SHELL" -c 'foo.getn() { .sh.value=2.3*4.5; }; typeset -F2 foo; typeset -p foo' 2>&1)
exp='typeset -F 2 foo=10.35'
[[ $got == "$exp" ]] || err_exit "Setting attribute after setting getn discipline fails" \
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
# ======
# As of 2022-07-12, the current scope is restored after changing .sh.level in a DEBUG trap
exp=$'a: 2 CHILD\nb: 1 PARENT\nc: 2 CHILD\nd: 1 PARENT'