much better solution: save tablep and hash value¹ in the struct tbl entry

① also saves time during texpand :D

XXX this doesn’t work well with the current indexed-array implementation
This commit is contained in:
tg 2009-08-28 20:30:59 +00:00
parent 7240c843ce
commit 4ccdfc8508
10 changed files with 108 additions and 110 deletions

5
edit.c
View File

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

4
eval.c
View File

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

27
exec.c
View File

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

4
expr.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/expr.c,v 1.30 2009/08/08 13:08:50 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/expr.c,v 1.31 2009/08/28 20:30:55 tg Exp $");
/* The order of these enums is constrained by the order of opinfo[] */ /* The order of these enums is constrained by the order of opinfo[] */
enum token { enum token {
@ -608,6 +608,8 @@ tempvar(void)
vp->flag = ISSET|INTEGER; vp->flag = ISSET|INTEGER;
vp->type = 0; vp->type = 0;
vp->areap = ATEMP; vp->areap = ATEMP;
vp->tablep = NULL;
vp->hval = 0;
vp->val.i = 0; vp->val.i = 0;
vp->name[0] = '\0'; vp->name[0] = '\0';
return (vp); return (vp);

16
funcs.c
View File

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

10
lex.c
View File

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

98
main.c
View File

@ -33,7 +33,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.139 2009/08/28 19:57:42 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.140 2009/08/28 20:30:57 tg Exp $");
extern char **environ; extern char **environ;
@ -1236,6 +1236,8 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
static void texpand(struct table *, size_t); static void texpand(struct table *, size_t);
static int tnamecmp(const void *, const void *); static int tnamecmp(const void *, const void *);
static struct tbl *ktscan(struct table *, const char *, uint32_t,
struct tbl ***);
/* Bob Jenkins' one-at-a-time hash */ /* Bob Jenkins' one-at-a-time hash */
uint32_t uint32_t
@ -1276,7 +1278,7 @@ texpand(struct table *tp, size_t nsize)
for (i = 0; i < osize; i++) for (i = 0; i < osize; i++)
if ((tblp = otblp[i]) != NULL) { if ((tblp = otblp[i]) != NULL) {
if ((tblp->flag & DEFINED)) { if ((tblp->flag & DEFINED)) {
for (p = &ntblp[hash(tblp->name) & for (p = &ntblp[tblp->hval &
(tp->size - 1)]; *p != NULL; p--) (tp->size - 1)]; *p != NULL; p--)
if (p == ntblp) /* wrap */ if (p == ntblp) /* wrap */
p += tp->size; p += tp->size;
@ -1299,48 +1301,39 @@ ktinit(struct table *tp, Area *ap, size_t tsize)
texpand(tp, tsize); texpand(tp, tsize);
} }
void /* table, name (key) to search for, hash(n) */
ktremove(struct table_entry *pte) static struct tbl *
ktscan(struct table *tp, const char *n, uint32_t h, struct tbl ***ppp)
{ {
struct tbl *p; struct tbl **pp, *p;
p = *(pte->ep); /* search for name in hashed table */
*(pte->ep) = NULL; for (pp = &tp->tbls[h & (tp->size - 1)]; (p = *pp) != NULL; pp--) {
++(pte->tp->nfree); if (p->hval == h && !strcmp(p->name, n) && (p->flag & DEFINED))
goto found;
if (pp == tp->tbls)
/* wrap */
pp += tp->size;
}
/* not found */
p = NULL;
afree(p, p->areap); found:
if (ppp)
*ppp = pp;
return (p);
} }
/* table, name (key) to search for, hash(n) */ /* table, name (key) to search for, hash(n) */
struct tbl * struct tbl *
ktsearch(struct table *tp, const char *n, uint32_t h, struct table_entry *pte) ktsearch(struct table *tp, const char *n, uint32_t h)
{ {
struct tbl **pp, *p; return (tp->size ? ktscan(tp, n, h, NULL) : NULL);
if (tp->size == 0)
return (NULL);
/* 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)) {
/* found */
if (pte) {
pte->tp = tp;
pte->ep = pp;
}
return (p);
}
if (pp == tp->tbls) /* wrap */
pp += tp->size;
}
return (NULL);
} }
/* table, name (key) to enter, hash(n) */ /* table, name (key) to enter, hash(n) */
struct tbl * struct tbl *
ktenter(struct table *tp, const char *n, uint32_t h, struct table_entry *pte) ktenter(struct table *tp, const char *n, uint32_t h)
{ {
struct tbl **pp, *p; struct tbl **pp, *p;
int len; int len;
@ -1348,30 +1341,23 @@ ktenter(struct table *tp, const char *n, uint32_t h, struct table_entry *pte)
if (tp->size == 0) if (tp->size == 0)
texpand(tp, INIT_TBLS); texpand(tp, INIT_TBLS);
Search: Search:
/* search for name in hashed table */ if ((p = ktscan(tp, n, h, &pp)))
for (pp = &tp->tbls[h & (tp->size - 1)]; (p = *pp) != NULL; pp--) {
if (*p->name == *n && strcmp(p->name, n) == 0) {
/* found */
if (pte) {
pte->tp = tp;
pte->ep = pp;
}
return (p); return (p);
}
if (pp == tp->tbls) /* wrap */
pp += tp->size;
}
if (tp->nfree <= 0) { /* too full */ if (tp->nfree <= 0) {
/* too full */
texpand(tp, 2 * tp->size); texpand(tp, 2 * tp->size);
goto Search; goto Search;
} }
/* create new tbl entry */ /* create new tbl entry */
len = strlen(n) + 1; len = strlen(n) + 1;
p = alloc(offsetof(struct tbl, name[0]) + len, tp->areap); p = alloc(offsetof(struct tbl, name[0]) + len, tp->areap);
p->flag = 0; p->flag = 0;
p->type = 0; p->type = 0;
p->areap = tp->areap; p->areap = tp->areap;
p->tablep = tp;
p->hval = h;
p->u2.field = 0; p->u2.field = 0;
p->u.array = NULL; p->u.array = NULL;
memcpy(p->name, n, len); memcpy(p->name, n, len);
@ -1379,13 +1365,27 @@ ktenter(struct table *tp, const char *n, uint32_t h, struct table_entry *pte)
/* enter in tp->tbls */ /* enter in tp->tbls */
tp->nfree--; tp->nfree--;
*pp = p; *pp = p;
if (pte) {
pte->tp = tp;
pte->ep = pp;
}
return (p); return (p);
} }
void
ktdelete(struct tbl *p)
{
struct tbl **pp;
if (p->tablep && p->tablep->size && ktscan(p->tablep, p->name,
p->hval, &pp) == p) {
/* ktremove p */
*pp = NULL;
p->tablep->nfree++;
/* get rid of p */
afree(p, p->areap);
} else {
/* mark p as free for garbage collection via texpand */
p->flag = 0;
}
}
void void
ktwalk(struct tstate *ts, struct table *tp) ktwalk(struct tstate *ts, struct table *tp)
{ {

17
sh.h
View File

@ -134,7 +134,7 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.327 2009/08/28 19:57:42 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.328 2009/08/28 20:30:58 tg Exp $");
#endif #endif
#define MKSH_VERSION "R39 2009/08/08" #define MKSH_VERSION "R39 2009/08/08"
@ -851,11 +851,6 @@ struct table {
short size, nfree; /* hash size (always 2^^n), free entries */ 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 */ struct tbl { /* table item */
Area *areap; /* area to allocate from */ Area *areap; /* area to allocate from */
union { union {
@ -869,6 +864,7 @@ struct tbl { /* table item */
struct tbl *array; /* array values */ struct tbl *array; /* array values */
const char *fpath; /* temporary path to undef function */ const char *fpath; /* temporary path to undef function */
} u; } u;
struct table *tablep; /* table we're ktenter'd in */
union { union {
int field; /* field with for -L/-R/-Z */ int field; /* field with for -L/-R/-Z */
int errno_; /* CEXEC/CTALIAS */ int errno_; /* CEXEC/CTALIAS */
@ -876,6 +872,7 @@ struct tbl { /* table item */
int type; /* command type (see below), base (if INTEGER), int type; /* command type (see below), base (if INTEGER),
* or offset from val.s of value (if EXPORT) */ * or offset from val.s of value (if EXPORT) */
Tflag flag; /* flags */ Tflag flag; /* flags */
uint32_t hval; /* hash(name) */
uint32_t index; /* index for an array */ uint32_t index; /* index for an array */
char name[4]; /* name -- variable length */ char name[4]; /* name -- variable length */
}; };
@ -1376,7 +1373,7 @@ int glob_str(char *, XPtrV *, int);
/* exec.c */ /* exec.c */
int execute(struct op * volatile, volatile int, volatile int * volatile); int execute(struct op * volatile, volatile int, volatile int * volatile);
int shcomexec(const char **); int shcomexec(const char **);
struct tbl *findfunc(const char *, uint32_t, bool, struct table_entry *); struct tbl *findfunc(const char *, uint32_t, bool);
int define(const char *, struct op *); int define(const char *, struct op *);
void builtin(const char *, int (*)(const char **)); void builtin(const char *, int (*)(const char **));
struct tbl *findcom(const char *, int); struct tbl *findcom(const char *, int);
@ -1545,9 +1542,9 @@ void coproc_cleanup(int);
struct temp *maketemp(Area *, Temp_type, struct temp **); struct temp *maketemp(Area *, Temp_type, struct temp **);
uint32_t hash(const char *); uint32_t hash(const char *);
void ktinit(struct table *, Area *, size_t); void ktinit(struct table *, Area *, size_t);
struct tbl *ktsearch(struct table *, const char *, uint32_t, struct table_entry *); struct tbl *ktsearch(struct table *, const char *, uint32_t);
struct tbl *ktenter(struct table *, const char *, uint32_t, struct table_entry *); struct tbl *ktenter(struct table *, const char *, uint32_t);
void ktremove(struct table_entry *); void ktdelete(struct tbl *);
void ktwalk(struct tstate *, struct table *); void ktwalk(struct tstate *, struct table *);
struct tbl *ktnext(struct tstate *); struct tbl *ktnext(struct tstate *);
struct tbl **ktsort(struct table *); struct tbl **ktsort(struct table *);

4
syn.c
View File

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

31
var.c
View File

@ -22,7 +22,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.79 2009/08/28 19:57:43 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.80 2009/08/28 20:30:59 tg Exp $");
/* /*
* Variables * Variables
@ -128,8 +128,7 @@ initvar(void)
ktinit(&specials, APERM, ktinit(&specials, APERM,
/* must be 80% of 2^n (currently 12 specials) */ 16); /* must be 80% of 2^n (currently 12 specials) */ 16);
for (i = 0; names[i].name; i++) { 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->flag = DEFINED|ISSET;
tp->type = names[i].v; tp->type = names[i].v;
} }
@ -226,7 +225,7 @@ global(const char *n)
return (vp); return (vp);
} }
for (l = e->loc; ; l = l->next) { for (l = e->loc; ; l = l->next) {
vp = ktsearch(&l->vars, n, h, NULL); vp = ktsearch(&l->vars, n, h);
if (vp != NULL) { if (vp != NULL) {
if (array) if (array)
return (arraysearch(vp, val)); return (arraysearch(vp, val));
@ -236,7 +235,7 @@ global(const char *n)
if (l->next == NULL) if (l->next == NULL)
break; break;
} }
vp = ktenter(&l->vars, n, h, NULL); vp = ktenter(&l->vars, n, h);
if (array) if (array)
vp = arraysearch(vp, val); vp = arraysearch(vp, val);
vp->flag |= DEFINED; vp->flag |= DEFINED;
@ -266,13 +265,12 @@ local(const char *n, bool copy)
vp->areap = ATEMP; vp->areap = ATEMP;
return (vp); return (vp);
} }
vp = ktenter(&l->vars, n, h, NULL); vp = ktenter(&l->vars, n, h);
if (copy && !(vp->flag & DEFINED)) { if (copy && !(vp->flag & DEFINED)) {
struct block *ll = l; struct block *ll = l;
struct tbl *vq = NULL; 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) { if (vq) {
vp->flag |= vq->flag & vp->flag |= vq->flag &
@ -894,8 +892,7 @@ makenv(void)
/* unexport any redefined instances */ /* unexport any redefined instances */
for (l2 = l->next; l2 != NULL; l2 = l2->next) { 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) if (vp2 != NULL)
vp2->flag &= ~EXPORT; vp2->flag &= ~EXPORT;
} }
@ -1029,7 +1026,7 @@ special(const char *name)
{ {
struct tbl *tp; struct tbl *tp;
tp = ktsearch(&specials, name, hash(name), NULL); tp = ktsearch(&specials, name, hash(name));
return (tp && (tp->flag & ISSET) ? tp->type : V_NONE); return (tp && (tp->flag & ISSET) ? tp->type : V_NONE);
} }
@ -1037,11 +1034,11 @@ special(const char *name)
static void static void
unspecial(const char *name) unspecial(const char *name)
{ {
struct table_entry te = { NULL, NULL }; struct tbl *tp;
ktsearch(&specials, name, hash(name), &te); tp = ktsearch(&specials, name, hash(name));
if (te.ep) if (tp)
ktremove(&te); ktdelete(tp);
} }
static time_t seconds; /* time SECONDS last set */ static time_t seconds; /* time SECONDS last set */
@ -1269,6 +1266,10 @@ arraysearch(struct tbl *vp, uint32_t val)
new->areap = vp->areap; new->areap = vp->areap;
new->u2.field = vp->u2.field; new->u2.field = vp->u2.field;
new->index = val; new->index = val;
/* XXX array indices must not be ktdelete'd, for now */
new->tablep = NULL;
new->hval = vp->hval;
if (curr != new) { /* not reusing old array entry */ if (curr != new) { /* not reusing old array entry */
prev->u.array = new; prev->u.array = new;
new->u.array = curr; new->u.array = curr;