this is a rather stupid diff: give ktsearch/ktenter the capability to

return information needed to do a real ktremove instead of the pseudo
ktdelete operation which merely unsets the DEFINED flag to mark it as
eligible for texpand garbage collection (even worse, !DEFINED entries
are still counted)
This commit is contained in:
tg 2009-08-28 19:57:43 +00:00
parent cd7f3fd836
commit 7240c843ce
9 changed files with 95 additions and 55 deletions

5
edit.c
View File

@ -25,7 +25,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.173 2009/08/01 20:32:43 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/edit.c,v 1.174 2009/08/28 19:57:39 tg Exp $");
/* tty driver characters we are interested in */
typedef struct {
@ -4161,7 +4161,8 @@ vi_cmd(int argcnt, const char *cmd)
/* lookup letter in alias list... */
alias[1] = cmd[1];
ap = ktsearch(&aliases, alias, hash(alias));
ap = ktsearch(&aliases, alias, hash(alias),
NULL);
if (!cmd[1] || !ap || !(ap->flag & ISSET))
return (-1);
/* check if this is a recursive call... */

4
eval.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.64 2009/08/01 19:31:02 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.65 2009/08/28 19:57:40 tg Exp $");
/*
* string expansion
@ -1425,7 +1425,7 @@ homedir(char *name)
{
struct tbl *ap;
ap = ktenter(&homedirs, name, hash(name));
ap = ktenter(&homedirs, name, hash(name), NULL);
if (!(ap->flag & ISSET)) {
struct passwd *pw;

27
exec.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.62 2009/08/28 19:16:17 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/exec.c,v 1.63 2009/08/28 19:57:40 tg Exp $");
static int comexec(struct op *, struct tbl *volatile, const char **,
int volatile, volatile int *);
@ -567,7 +567,7 @@ comexec(struct op *t, struct tbl *volatile tp, const char **ap,
rv = 127;
break;
}
if (!(ftp = findfunc(cp, hash(cp), false)) ||
if (!(ftp = findfunc(cp, hash(cp), false, NULL)) ||
!(ftp->flag & ISSET)) {
warningf(true,
"%s: function not defined by %s",
@ -789,7 +789,7 @@ shcomexec(const char **wp)
{
struct tbl *tp;
tp = ktsearch(&builtins, *wp, hash(*wp));
tp = ktsearch(&builtins, *wp, hash(*wp), NULL);
if (tp == NULL)
internal_errorf("shcomexec: %s", *wp);
return (call_builtin(tp, wp));
@ -800,17 +800,17 @@ shcomexec(const char **wp)
* is created if none is found.
*/
struct tbl *
findfunc(const char *name, uint32_t h, bool create)
findfunc(const char *name, uint32_t h, bool create, struct table_entry *pte)
{
struct block *l;
struct tbl *tp = NULL;
for (l = e->loc; l; l = l->next) {
tp = ktsearch(&l->funs, name, h);
tp = ktsearch(&l->funs, name, h, pte);
if (tp)
break;
if (!l->next && create) {
tp = ktenter(&l->funs, name, h);
tp = ktenter(&l->funs, name, h, pte);
tp->flag = DEFINED;
tp->type = CFUNC;
tp->val.t = NULL;
@ -828,10 +828,11 @@ int
define(const char *name, struct op *t)
{
struct tbl *tp;
struct table_entry te;
bool was_set = false;
while (1) {
tp = findfunc(name, hash(name), true);
tp = findfunc(name, hash(name), true, &te);
if (tp->flag & ISSET)
was_set = true;
@ -852,7 +853,7 @@ define(const char *name, struct op *t)
}
if (t == NULL) { /* undefine */
ktdelete(tp);
ktremove(&te);
return (was_set ? 0 : 1);
}
@ -885,7 +886,7 @@ builtin(const char *name, int (*func) (const char **))
break;
}
tp = ktenter(&builtins, name, hash(name));
tp = ktenter(&builtins, name, hash(name), NULL);
tp->flag = DEFINED | flag;
tp->type = CSHELL;
tp->val.f = func;
@ -911,14 +912,14 @@ findcom(const char *name, int flags)
flags &= ~FC_FUNC;
goto Search;
}
tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h) : NULL;
tbi = (flags & FC_BI) ? ktsearch(&builtins, name, h, NULL) : NULL;
/* POSIX says special builtins first, then functions, then
* POSIX regular builtins, then search path...
*/
if ((flags & FC_SPECBI) && tbi && (tbi->flag & SPEC_BI))
tp = tbi;
if (!tp && (flags & FC_FUNC)) {
tp = findfunc(name, h, false);
tp = findfunc(name, h, false, NULL);
if (tp && !(tp->flag & ISSET)) {
if ((fpath = str_val(global("FPATH"))) == null) {
tp->u.fpath = NULL;
@ -933,7 +934,7 @@ findcom(const char *name, int flags)
if (!tp && (flags & FC_UNREGBI) && tbi)
tp = tbi;
if (!tp && (flags & FC_PATH) && !(flags & FC_DEFPATH)) {
tp = ktsearch(&taliases, name, h);
tp = ktsearch(&taliases, name, h, NULL);
if (tp && (tp->flag & ISSET) && access(tp->val.s, X_OK) != 0) {
if (tp->flag & ALLOC) {
tp->flag &= ~ALLOC;
@ -948,7 +949,7 @@ findcom(const char *name, int flags)
(flags & FC_PATH)) {
if (!tp) {
if (insert && !(flags & FC_DEFPATH)) {
tp = ktenter(&taliases, name, h);
tp = ktenter(&taliases, name, h, NULL);
tp->type = CTALIAS;
} else {
tp = &temp;

14
funcs.c
View File

@ -25,7 +25,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.121 2009/08/28 18:53:58 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/funcs.c,v 1.122 2009/08/28 19:57:40 tg Exp $");
#if HAVE_KILLPG
/*
@ -639,9 +639,9 @@ c_whence(const char **wp)
while ((vflag || rv == 0) && (id = *wp++) != NULL) {
tp = NULL;
if ((iam_whence || vflag) && !pflag)
tp = ktsearch(&keywords, id, hash(id));
tp = ktsearch(&keywords, id, hash(id), NULL);
if (!tp && !pflag) {
tp = ktsearch(&aliases, id, hash(id));
tp = ktsearch(&aliases, id, hash(id), NULL);
if (tp && !(tp->flag & ISSET))
tp = NULL;
}
@ -879,7 +879,7 @@ c_typeset(const char **wp)
for (i = builtin_opt.optind; wp[i]; i++) {
if (func) {
f = findfunc(wp[i], hash(wp[i]),
(fset&UCASEV_AL) ? true : false);
(fset&UCASEV_AL) ? true : false, NULL);
if (!f) {
/* AT&T ksh does ++rv: bogus */
rv = 1;
@ -1138,7 +1138,7 @@ c_alias(const char **wp)
}
h = hash(alias);
if (val == NULL && !tflag && !xflag) {
ap = ktsearch(t, alias, h);
ap = ktsearch(t, alias, h, NULL);
if (ap != NULL && (ap->flag&ISSET)) {
if (pflag)
shf_puts("alias ", shl_stdout);
@ -1154,7 +1154,7 @@ c_alias(const char **wp)
}
continue;
}
ap = ktenter(t, alias, h);
ap = ktenter(t, alias, h, NULL);
ap->type = tflag ? CTALIAS : CALIAS;
/* Are we setting the value or just some flags? */
if ((val && !tflag) || (!val && tflag && !Uflag)) {
@ -1214,7 +1214,7 @@ c_unalias(const char **wp)
wp += builtin_opt.optind;
for (; *wp != NULL; wp++) {
ap = ktsearch(t, *wp, hash(*wp));
ap = ktsearch(t, *wp, hash(*wp), NULL);
if (ap == NULL) {
rv = 1; /* POSIX */
continue;

10
lex.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.90 2009/08/28 18:53:58 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.91 2009/08/28 19:57:41 tg Exp $");
/*
* states while lexing word
@ -909,15 +909,17 @@ yylex(int cf)
if (*ident != '\0' && (cf&(KEYWORD|ALIAS))) {
struct tbl *p;
struct table_entry te;
uint32_t h = hash(ident);
/* { */
if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&
if ((cf & KEYWORD) &&
(p = ktsearch(&keywords, ident, h, NULL)) &&
(!(cf & ESACONLY) || p->val.i == ESAC || p->val.i == '}')) {
afree(yylval.cp, ATEMP);
return (p->val.i);
}
if ((cf & ALIAS) && (p = ktsearch(&aliases, ident, h)) &&
if ((cf & ALIAS) && (p = ktsearch(&aliases, ident, h, &te)) &&
(p->flag & ISSET)) {
/*
* this still points to the same character as the
@ -944,7 +946,7 @@ yylex(int cf)
* delete alias upon encountering function
* definition
*/
ktdelete(p);
ktremove(&te);
else {
Source *s = source;

40
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h>
#endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.138 2009/08/28 18:53:59 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.139 2009/08/28 19:57:42 tg Exp $");
extern char **environ;
@ -1299,9 +1299,21 @@ ktinit(struct table *tp, Area *ap, size_t tsize)
texpand(tp, tsize);
}
void
ktremove(struct table_entry *pte)
{
struct tbl *p;
p = *(pte->ep);
*(pte->ep) = NULL;
++(pte->tp->nfree);
afree(p, p->areap);
}
/* table, name (key) to search for, hash(n) */
struct tbl *
ktsearch(struct table *tp, const char *n, uint32_t h)
ktsearch(struct table *tp, const char *n, uint32_t h, struct table_entry *pte)
{
struct tbl **pp, *p;
@ -1311,8 +1323,14 @@ ktsearch(struct table *tp, const char *n, uint32_t h)
/* search for name in hashed table */
for (pp = &tp->tbls[h & (tp->size - 1)]; (p = *pp) != NULL; pp--) {
if (*p->name == *n && strcmp(p->name, n) == 0 &&
(p->flag & DEFINED))
(p->flag & DEFINED)) {
/* found */
if (pte) {
pte->tp = tp;
pte->ep = pp;
}
return (p);
}
if (pp == tp->tbls) /* wrap */
pp += tp->size;
}
@ -1322,7 +1340,7 @@ ktsearch(struct table *tp, const char *n, uint32_t h)
/* table, name (key) to enter, hash(n) */
struct tbl *
ktenter(struct table *tp, const char *n, uint32_t h)
ktenter(struct table *tp, const char *n, uint32_t h, struct table_entry *pte)
{
struct tbl **pp, *p;
int len;
@ -1332,8 +1350,14 @@ ktenter(struct table *tp, const char *n, uint32_t h)
Search:
/* search for name in hashed table */
for (pp = &tp->tbls[h & (tp->size - 1)]; (p = *pp) != NULL; pp--) {
if (*p->name == *n && strcmp(p->name, n) == 0)
return (p); /* found */
if (*p->name == *n && strcmp(p->name, n) == 0) {
/* found */
if (pte) {
pte->tp = tp;
pte->ep = pp;
}
return (p);
}
if (pp == tp->tbls) /* wrap */
pp += tp->size;
}
@ -1355,6 +1379,10 @@ ktenter(struct table *tp, const char *n, uint32_t h)
/* enter in tp->tbls */
tp->nfree--;
*pp = p;
if (pte) {
pte->tp = tp;
pte->ep = pp;
}
return (p);
}

15
sh.h
View File

@ -134,7 +134,7 @@
#endif
#ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.326 2009/08/28 19:16:16 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.327 2009/08/28 19:57:42 tg Exp $");
#endif
#define MKSH_VERSION "R39 2009/08/08"
@ -851,6 +851,11 @@ struct table {
short size, nfree; /* hash size (always 2^^n), free entries */
};
struct table_entry {
struct table *tp; /* table this entry is in */
struct tbl **ep; /* entry pointer (&tp->tbls[i]) */
};
struct tbl { /* table item */
Area *areap; /* area to allocate from */
union {
@ -1371,7 +1376,7 @@ int glob_str(char *, XPtrV *, int);
/* exec.c */
int execute(struct op * volatile, volatile int, volatile int * volatile);
int shcomexec(const char **);
struct tbl *findfunc(const char *, uint32_t, bool);
struct tbl *findfunc(const char *, uint32_t, bool, struct table_entry *);
int define(const char *, struct op *);
void builtin(const char *, int (*)(const char **));
struct tbl *findcom(const char *, int);
@ -1540,9 +1545,9 @@ void coproc_cleanup(int);
struct temp *maketemp(Area *, Temp_type, struct temp **);
uint32_t hash(const char *);
void ktinit(struct table *, Area *, size_t);
struct tbl *ktsearch(struct table *, const char *, uint32_t);
struct tbl *ktenter(struct table *, const char *, uint32_t);
#define ktdelete(p) do { p->flag = 0; } while (/* CONSTCOND */ 0)
struct tbl *ktsearch(struct table *, const char *, uint32_t, struct table_entry *);
struct tbl *ktenter(struct table *, const char *, uint32_t, struct table_entry *);
void ktremove(struct table_entry *);
void ktwalk(struct tstate *, struct table *);
struct tbl *ktnext(struct tstate *);
struct tbl **ktsort(struct table *);

4
syn.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.39 2009/08/28 18:54:00 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/syn.c,v 1.40 2009/08/28 19:57:43 tg Exp $");
struct nesting_state {
int start_token; /* token than began nesting (eg, FOR) */
@ -743,7 +743,7 @@ initkeywords(void)
/* must be 80% of 2^n (currently 20 keywords) */ 32);
for (tt = tokentab; tt->name; tt++) {
if (tt->reserved) {
p = ktenter(&keywords, tt->name, hash(tt->name));
p = ktenter(&keywords, tt->name, hash(tt->name), NULL);
p->flag |= DEFINED|ISSET;
p->type = CKEYWD;
p->val.i = tt->val;

31
var.c
View File

@ -22,7 +22,7 @@
#include "sh.h"
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.78 2009/08/28 18:54:01 tg Exp $");
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.79 2009/08/28 19:57:43 tg Exp $");
/*
* Variables
@ -128,7 +128,8 @@ initvar(void)
ktinit(&specials, APERM,
/* must be 80% of 2^n (currently 12 specials) */ 16);
for (i = 0; names[i].name; i++) {
tp = ktenter(&specials, names[i].name, hash(names[i].name));
tp = ktenter(&specials, names[i].name, hash(names[i].name),
NULL);
tp->flag = DEFINED|ISSET;
tp->type = names[i].v;
}
@ -225,7 +226,7 @@ global(const char *n)
return (vp);
}
for (l = e->loc; ; l = l->next) {
vp = ktsearch(&l->vars, n, h);
vp = ktsearch(&l->vars, n, h, NULL);
if (vp != NULL) {
if (array)
return (arraysearch(vp, val));
@ -235,7 +236,7 @@ global(const char *n)
if (l->next == NULL)
break;
}
vp = ktenter(&l->vars, n, h);
vp = ktenter(&l->vars, n, h, NULL);
if (array)
vp = arraysearch(vp, val);
vp->flag |= DEFINED;
@ -265,12 +266,13 @@ local(const char *n, bool copy)
vp->areap = ATEMP;
return (vp);
}
vp = ktenter(&l->vars, n, h);
vp = ktenter(&l->vars, n, h, NULL);
if (copy && !(vp->flag & DEFINED)) {
struct block *ll = l;
struct tbl *vq = NULL;
while ((ll = ll->next) && !(vq = ktsearch(&ll->vars, n, h)))
while ((ll = ll->next) && !(vq = ktsearch(&ll->vars, n, h,
NULL)))
;
if (vq) {
vp->flag |= vq->flag &
@ -892,7 +894,8 @@ makenv(void)
/* unexport any redefined instances */
for (l2 = l->next; l2 != NULL; l2 = l2->next) {
vp2 = ktsearch(&l2->vars, vp->name, h);
vp2 = ktsearch(&l2->vars, vp->name, h,
NULL);
if (vp2 != NULL)
vp2->flag &= ~EXPORT;
}
@ -1026,7 +1029,7 @@ special(const char *name)
{
struct tbl *tp;
tp = ktsearch(&specials, name, hash(name));
tp = ktsearch(&specials, name, hash(name), NULL);
return (tp && (tp->flag & ISSET) ? tp->type : V_NONE);
}
@ -1034,15 +1037,15 @@ special(const char *name)
static void
unspecial(const char *name)
{
struct tbl *tp;
struct table_entry te = { NULL, NULL };
tp = ktsearch(&specials, name, hash(name));
if (tp)
ktdelete(tp);
ktsearch(&specials, name, hash(name), &te);
if (te.ep)
ktremove(&te);
}
static time_t seconds; /* time SECONDS last set */
static int user_lineno; /* what user set $LINENO to */
static time_t seconds; /* time SECONDS last set */
static int user_lineno; /* what user set $LINENO to */
static void
getspec(struct tbl *vp)