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:
parent
aa2644ab84
commit
cc4927529b
21 changed files with 708 additions and 210 deletions
|
|
@ -52,11 +52,13 @@ static int htable(Dt_t* dt)
|
|||
if((n = hash->tblz) > 0 && (hash->type&H_FIXED) )
|
||||
return 0; /* fixed size table */
|
||||
|
||||
if(n == 0 && disc && disc->eventf) /* let user have input */
|
||||
if(disc && disc->eventf) /* let user have input */
|
||||
{ if((*disc->eventf)(dt, DT_HASHSIZE, &n, disc) > 0 )
|
||||
{ if(n < 0) /* fix table size */
|
||||
{ hash->type |= H_FIXED;
|
||||
n = -n;
|
||||
n = -n; /* desired table size */
|
||||
if(hash->tblz >= n ) /* table size is fixed now */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -234,12 +236,13 @@ static Void_t* hstat(Dt_t* dt, Dtstat_t* st)
|
|||
|
||||
for(endt = (t = hash->htbl) + hash->tblz; t < endt; ++t)
|
||||
{ for(n = 0, l = *t; l; l = l->_rght)
|
||||
{ if(n < DT_MAXSIZE)
|
||||
st->lsize[n] += 1;
|
||||
n += 1;
|
||||
}
|
||||
st->mlev = n > st->mlev ? n : st->mlev;
|
||||
if(n < DT_MAXSIZE) /* if chain length is small */
|
||||
{ st->msize = n > st->msize ? n : st->msize;
|
||||
st->lsize[n] += n;
|
||||
}
|
||||
st->msize = n > st->msize ? n : st->msize;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +313,7 @@ int type;
|
|||
hsh = _DTHSH(dt,key,disc);
|
||||
|
||||
tbl = hash->htbl + (hsh & (hash->tblz-1));
|
||||
pp = ll = NIL(Dtlink_t*);
|
||||
pp = ll = NIL(Dtlink_t*); /* pp is the before, ll is the here */
|
||||
for(p = NIL(Dtlink_t*), l = *tbl; l; p = l, l = l->_rght)
|
||||
{ if(hsh == l->_hash)
|
||||
{ o = _DTOBJ(disc,l); k = _DTKEY(disc,o);
|
||||
|
|
@ -342,20 +345,41 @@ int type;
|
|||
_dtfree(dt, ll, type);
|
||||
DTRETURN(obj, _DTOBJ(disc,ll));
|
||||
}
|
||||
else if(type & DT_INSTALL )
|
||||
{ if(dt->meth->type&DT_BAG)
|
||||
goto do_insert;
|
||||
else if(!(lnk = _dtmake(dt, obj, type)) )
|
||||
DTRETURN(obj, NIL(Void_t*) );
|
||||
else /* replace old object with new one */
|
||||
{ if(pp) /* remove old object */
|
||||
pp->_rght = ll->_rght;
|
||||
else *tbl = ll->_rght;
|
||||
o = _DTOBJ(disc,ll);
|
||||
_dtfree(dt, ll, DT_DELETE);
|
||||
DTANNOUNCE(dt, o, DT_DELETE);
|
||||
|
||||
goto do_insert;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /**/DEBUG_ASSERT(type&(DT_INSERT|DT_ATTACH|DT_APPEND|DT_RELINK));
|
||||
if(!(dt->meth->type&DT_BAG) )
|
||||
if((dt->meth->type&DT_BAG) )
|
||||
goto do_insert;
|
||||
else
|
||||
{ if(type&(DT_INSERT|DT_APPEND|DT_ATTACH) )
|
||||
type |= DT_SEARCH; /* for announcement */
|
||||
type |= DT_MATCH; /* for announcement */
|
||||
else if(lnk && (type&DT_RELINK) )
|
||||
{ /* remove a duplicate */
|
||||
o = _DTOBJ(disc, lnk);
|
||||
_dtfree(dt, lnk, DT_DELETE);
|
||||
DTANNOUNCE(dt, o, DT_DELETE);
|
||||
}
|
||||
DTRETURN(obj, _DTOBJ(disc,ll));
|
||||
}
|
||||
else goto do_insert;
|
||||
}
|
||||
}
|
||||
else /* no matching object */
|
||||
{ if(!(type&(DT_INSERT|DT_APPEND|DT_ATTACH|DT_RELINK)) )
|
||||
{ if(!(type&(DT_INSERT|DT_INSTALL|DT_APPEND|DT_ATTACH|DT_RELINK)) )
|
||||
DTRETURN(obj, NIL(Void_t*));
|
||||
|
||||
do_insert: /* inserting a new object */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue