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

libast: Update cdt(3): Allow empty strings in (dt)trees

This backports most of the Cdt (container data types) mechanism
from the ksh 93v- beta, based on ground work done by OpenSUSE:
https://build.opensuse.org/package/view_file/shells/ksh/ksh93-dttree-crash.dif
plus adaptations to match ksh 93u+m and an updated manual page
(src/lib/libast/man/cdt.3) added directly from the 93v- sources.

| Thu Dec 20 12:48:02 UTC 2012 - werner@suse.de
|
| - Add ksh93-dttree-crash.dif - Allow empty strings in (dt)trees
|   (bnc#795324)
|
| Fri Oct 25 14:07:57 UTC 2013 - werner@suse.de
|
| - Rework patch ksh93-dttree-crash.dif

As usual, precious little information is available because the
OpenSUSE bug report is currently closed to the public:
https://bugzilla.opensuse.org/show_bug.cgi?id=795324

However, a cursory inspection suggests that this code contains
improvements to do with concurrent processing and related
robustness. The new cdt.3 manual page adds a lot about that.

This has been in production use on OpenSUSE for a long time,
so hopefully this will make ksh a little more stable again.
Only one way to find out: let's commit and test this...

BTW, to get a nice manual, use groff and ghostscript's ps2pdf:
$ groff -tman src/lib/libast/man/cdt.3 | ps2pdf - cdt.3.pdf
This commit is contained in:
Martijn Dekker 2021-01-28 02:29:55 +00:00
parent aa2644ab84
commit cc4927529b
21 changed files with 708 additions and 210 deletions

View file

@ -184,7 +184,10 @@ static Namval_t *scope(register Namval_t *np,register struct lval *lvalue,int as
{
ap = nv_arrayptr(np);
if(ap && !ap->table)
{
ap->table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->table,shp,1);
}
if(ap && ap->table && (nq=nv_search(nv_getsub(np),ap->table,NV_ADD)))
nq->nvenv = (char*)np;
if(nq && nv_isnull(nq))

View file

@ -95,6 +95,7 @@ static Namarr_t *array_scope(Namval_t *np, Namarr_t *ap, int flags)
if(is_associative(aq))
{
aq->scope = (void*)dtopen(&_Nvdisc,Dtoset);
dtuserdata(aq->scope,&sh,1);
dtview((Dt_t*)aq->scope,aq->table);
aq->table = (Dt_t*)aq->scope;
return(aq);
@ -373,7 +374,10 @@ static Namval_t *array_find(Namval_t *np,Namarr_t *arp, int flag)
{
char *cp;
if(!ap->header.table)
{
ap->header.table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->header.table,&sh,1);
}
sfprintf(sh.strbuf,"%d",ap->cur);
cp = sfstruse(sh.strbuf);
mp = nv_search(cp, ap->header.table, NV_ADD);
@ -410,7 +414,10 @@ int nv_arraysettype(Namval_t *np, Namval_t *tp, const char *sub, int flags)
av[1] = 0;
sh.last_table = 0;
if(!ap->table)
{
ap->table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->table,&sh,1);
}
if(nq = nv_search(sub, ap->table, NV_ADD))
{
if(!nq->nvfun && nq->nvalue.cp && *nq->nvalue.cp==0)
@ -452,7 +459,6 @@ static Namfun_t *array_clone(Namval_t *np, Namval_t *mp, int flags, Namfun_t *fp
int nelem, skipped=0;
Dt_t *otable=ap->table;
struct index_array *aq = (struct index_array*)ap, *ar;
Shell_t *shp = sh_getinterp();
if(flags&NV_MOVE)
{
if((flags&NV_COMVAR) && nv_putsub(np,NIL(char*),ARRAY_SCAN))
@ -485,6 +491,7 @@ static Namfun_t *array_clone(Namval_t *np, Namval_t *mp, int flags, Namfun_t *fp
if(ap->table)
{
ap->table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->table,&sh,1);
if(ap->scope && !(flags&NV_COMVAR))
{
ap->scope = ap->table;
@ -855,6 +862,7 @@ static struct index_array *array_grow(Namval_t *np, register struct index_array
if(nv_hasdisc(np,&array_disc) || (nv_type(np) && nv_isvtree(np)))
{
ap->header.table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->header.table,&sh,1);
mp = nv_search("0", ap->header.table,NV_ADD);
if(mp && nv_isnull(mp))
{
@ -1180,7 +1188,6 @@ Namval_t *nv_putsub(Namval_t *np,register char *sp,register long mode)
{
if(sp)
{
Shell_t *shp = sh_getinterp();
if(ap && ap->xp && !strmatch(sp,"+([0-9])"))
{
Namval_t *mp = nv_namptr(ap->xp,0);
@ -1188,7 +1195,7 @@ Namval_t *nv_putsub(Namval_t *np,register char *sp,register long mode)
size = nv_getnum(mp);
}
else
size = (int)sh_arith(shp,(char*)sp);
size = (int)sh_arith(&sh,(char*)sp);
}
if(size <0 && ap)
size += array_maxindex(np);
@ -1242,7 +1249,10 @@ Namval_t *nv_putsub(Namval_t *np,register char *sp,register long mode)
char *cp;
Namval_t *mp;
if(!ap->header.table)
{
ap->header.table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->header.table,&sh,1);
}
sfprintf(sh.strbuf,"%d",ap->cur);
cp = sfstruse(sh.strbuf);
mp = nv_search(cp, ap->header.table, NV_ADD);
@ -1379,7 +1389,6 @@ static void array_fixed_setdata(Namval_t *np,Namarr_t* ap,struct fixed_array* fp
static int array_fixed_init(Namval_t *np, char *sub, char *cp)
{
Shell_t *shp=sh_getinterp();
Namarr_t *ap;
struct fixed_array *fp;
int n=1,sz;
@ -1403,12 +1412,12 @@ static int array_fixed_init(Namval_t *np, char *sub, char *cp)
fp->max = (int*)(fp+1);
fp->incr = fp->max+n;
fp->cur = fp->incr+n;
fp->max[0] = (int)sh_arith(shp,(char*)sub);
fp->max[0] = (int)sh_arith(&sh,(char*)sub);
for(n=1,ep=cp;*ep=='['; ep=cp)
{
cp = nv_endsubscript(np,ep,0);
cp[-1]=0;
fp->max[n++] = sz = (int)sh_arith(shp,(char*)ep+1);
fp->max[n++] = sz = (int)sh_arith(&sh,(char*)ep+1);
if(sz<0)
{
free((void*)ap);
@ -1429,7 +1438,6 @@ static int array_fixed_init(Namval_t *np, char *sub, char *cp)
static char *array_fixed(Namval_t *np, char *sub, char *cp,int mode)
{
Shell_t *shp=sh_getinterp();
Namarr_t *ap = nv_arrayptr(np);
struct fixed_array *fp = (struct fixed_array*)ap->fixed;
char *ep;
@ -1447,7 +1455,7 @@ static char *array_fixed(Namval_t *np, char *sub, char *cp,int mode)
}
else
fp->curi = 0;
size = (int)sh_arith(shp,(char*)sub);
size = (int)sh_arith(&sh,(char*)sub);
fp->cur[n] = size;
if(size >= fp->max[n] || (size < 0))
errormsg(SH_DICT,ERROR_exit(1),e_subscript, nv_name(np));
@ -1459,7 +1467,7 @@ static char *array_fixed(Namval_t *np, char *sub, char *cp,int mode)
errormsg(SH_DICT,ERROR_exit(1),e_subscript, nv_name(np));
cp = nv_endsubscript(np,ep,0);
cp[-1]=0;
size = (int)sh_arith(shp,(char*)ep+1);
size = (int)sh_arith(&sh,(char*)ep+1);
if(size >= fp->max[n] || (size < 0))
errormsg(SH_DICT,ERROR_exit(1),e_subscript, nv_name(np));
fp->cur[n] = size;
@ -1658,6 +1666,7 @@ void *nv_associative(register Namval_t *np,const char *sp,int mode)
if(ap = (struct assoc_array*)calloc(1,sizeof(struct assoc_array)))
{
ap->header.table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->header.table,&sh,1);
ap->cur = 0;
ap->pos = 0;
ap->header.hdr.disc = &array_disc;
@ -1730,8 +1739,7 @@ void *nv_associative(register Namval_t *np,const char *sp,int mode)
case NV_ANAME:
if(ap->cur)
{
Shell_t *shp = sh_getinterp();
if(!shp->instance && nv_isnull(ap->cur))
if(!sh.instance && nv_isnull(ap->cur))
return(NIL(void*));
return((void*)ap->cur->nvname);
}

View file

@ -1812,9 +1812,13 @@ static Init_t *nv_init(Shell_t *shp)
(OPTINDNOD)->nvalue.lp = (&shp->st.optindex);
/* set up the seconds clock */
shp->alias_tree = dtopen(&_Nvdisc,Dtoset);
dtuserdata(shp->alias_tree,shp,1);
shp->track_tree = dtopen(&_Nvdisc,Dtset);
dtuserdata(shp->track_tree,shp,1);
shp->bltin_tree = sh_inittree(shp,(const struct shtable2*)shtab_builtins);
dtuserdata(shp->bltin_tree,shp,1);
shp->fun_tree = dtopen(&_Nvdisc,Dtoset);
dtuserdata(shp->fun_tree,shp,1);
dtview(shp->fun_tree,shp->bltin_tree);
nv_mount(DOTSHNOD, "type", shp->typedict=dtopen(&_Nvdisc,Dtoset));
nv_adddisc(DOTSHNOD, shdiscnames, (Namval_t**)0);
@ -1857,6 +1861,7 @@ Dt_t *sh_inittree(Shell_t *shp,const struct shtable2 *name_vals)
nbltins = n;
}
base_treep = treep = dtopen(&_Nvdisc,Dtoset);
dtuserdata(treep,shp,1);
treep->user = (void*)shp;
for(tp=name_vals;*tp->sh_name;tp++,np++)
{

View file

@ -2738,7 +2738,10 @@ static char *sh_tilde(Shell_t *shp,register const char *string)
skip:
#endif /* _WINIX */
if(!logins_tree)
{
logins_tree = dtopen(&_Nvdisc,Dtbag);
dtuserdata(logins_tree,shp,1);
}
if(np=nv_search(string,logins_tree,NV_ADD))
{
save = shp->subshell;

View file

@ -181,6 +181,7 @@ int sh_main(int ac, char *av[], Shinit_f userinit)
/* preset aliases for interactive non-POSIX ksh */
dtclose(shp->alias_tree);
shp->alias_tree = sh_inittree(shp,shtab_aliases);
dtuserdata(shp->alias_tree,shp,1);
}
}
#if SHOPT_REMOTE

View file

@ -789,6 +789,7 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
{
Dt_t *dp = dtview(shp->var_tree,(Dt_t*)0);
rp->sdict = dtopen(&_Nvdisc,Dtoset);
dtuserdata(rp->sdict,shp,1);
dtview(rp->sdict,dp);
dtview(shp->var_tree,rp->sdict);
}
@ -1131,7 +1132,10 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
ap = nv_arrayptr(np);
}
if(n && ap && !ap->table)
{
ap->table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->table,shp,1);
}
if(ap && ap->table && (nq=nv_search(sub,ap->table,n)))
nq->nvenv = (char*)np;
if(nq && nv_isnull(nq))
@ -2285,6 +2289,7 @@ void sh_scope(Shell_t *shp, struct argnod *envlist, int fun)
newroot = nv_dict(shp->namespace);
#endif /* SHOPT_NAMESPACE */
newscope = dtopen(&_Nvdisc,Dtoset);
dtuserdata(newscope,shp,1);
if(envlist)
{
dtview(newscope,(Dt_t*)shp->var_tree);
@ -3277,7 +3282,10 @@ int nv_rename(register Namval_t *np, int flags)
if(ap=nv_arrayptr(np))
{
if(!ap->table)
{
ap->table = dtopen(&_Nvdisc,Dtoset);
dtuserdata(ap->table,shp,1);
}
if(ap->table)
mp = nv_search(nv_getsub(np),ap->table,NV_ADD);
nv_arraychild(np,mp,0);

View file

@ -1299,6 +1299,7 @@ static Namfun_t *clone_table(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp
Dt_t *oroot=tp->dict,*nroot=dtopen(&_Nvdisc,Dtoset);
if(!nroot)
return(0);
dtuserdata(nroot,dtuserdata(oroot,0,0),1);
memcpy((void*)ntp,(void*)fp,sizeof(struct table));
ntp->dict = nroot;
ntp->parent = nv_lastdict();

View file

@ -404,6 +404,7 @@ Dt_t *sh_subtracktree(int create)
if(create && sh.subshell && !sh.subshare && sp && !sp->strack)
{
sp->strack = dtopen(&_Nvdisc,Dtset);
dtuserdata(sp->strack,&sh,1);
dtview(sp->strack,sh.track_tree);
sh.track_tree = sp->strack;
}
@ -420,6 +421,7 @@ Dt_t *sh_subfuntree(int create)
if(create && sh.subshell && !sh.subshare && sp && !sp->sfun)
{
sp->sfun = dtopen(&_Nvdisc,Dtoset);
dtuserdata(sp->sfun,&sh,1);
dtview(sp->sfun,sh.fun_tree);
sh.fun_tree = sp->sfun;
}

View file

@ -2429,6 +2429,7 @@ int sh_exec(register const Shnode_t *t, int flags)
else
{
root = dtopen(&_Nvdisc,Dtoset);
dtuserdata(root,shp,1);
nv_mount(np, (char*)0, root);
np->nvalue.cp = Empty;
dtview(root,shp->var_base);
@ -2484,11 +2485,6 @@ int sh_exec(register const Shnode_t *t, int flags)
slp = (struct slnod*)np->nvenv;
sh_funstaks(slp->slchild,-1);
stakdelete(slp->slptr);
if(shp->funload)
{
free((void*)np->nvalue.rp);
np->nvalue.rp = 0;
}
if(rp->sdict)
{
Namval_t *mp, *nq;
@ -2502,6 +2498,12 @@ int sh_exec(register const Shnode_t *t, int flags)
dtclose(rp->sdict);
rp->sdict = 0;
}
if(shp->funload)
{
if(!shp->fpathdict)
free((void*)np->nvalue.rp);
np->nvalue.rp = 0;
}
}
if(!np->nvalue.rp)
{
@ -2540,7 +2542,10 @@ int sh_exec(register const Shnode_t *t, int flags)
if(!shp->fpathdict)
shp->fpathdict = dtopen(&_Rpdisc,Dtobag);
if(shp->fpathdict)
{
dtuserdata(shp->fpathdict,shp,1);
dtinsert(shp->fpathdict,rp);
}
}
}
else