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:
parent
7240c843ce
commit
4ccdfc8508
5
edit.c
5
edit.c
@ -25,7 +25,7 @@
|
||||
|
||||
#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 */
|
||||
typedef struct {
|
||||
@ -4161,8 +4161,7 @@ vi_cmd(int argcnt, const char *cmd)
|
||||
|
||||
/* lookup letter in alias list... */
|
||||
alias[1] = cmd[1];
|
||||
ap = ktsearch(&aliases, alias, hash(alias),
|
||||
NULL);
|
||||
ap = ktsearch(&aliases, alias, hash(alias));
|
||||
if (!cmd[1] || !ap || !(ap->flag & ISSET))
|
||||
return (-1);
|
||||
/* check if this is a recursive call... */
|
||||
|
4
eval.c
4
eval.c
@ -22,7 +22,7 @@
|
||||
|
||||
#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
|
||||
@ -1425,7 +1425,7 @@ homedir(char *name)
|
||||
{
|
||||
struct tbl *ap;
|
||||
|
||||
ap = ktenter(&homedirs, name, hash(name), NULL);
|
||||
ap = ktenter(&homedirs, name, hash(name));
|
||||
if (!(ap->flag & ISSET)) {
|
||||
struct passwd *pw;
|
||||
|
||||
|
27
exec.c
27
exec.c
@ -22,7 +22,7 @@
|
||||
|
||||
#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 **,
|
||||
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, NULL)) ||
|
||||
if (!(ftp = findfunc(cp, hash(cp), false)) ||
|
||||
!(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), NULL);
|
||||
tp = ktsearch(&builtins, *wp, hash(*wp));
|
||||
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, struct table_entry *pte)
|
||||
findfunc(const char *name, uint32_t h, bool create)
|
||||
{
|
||||
struct block *l;
|
||||
struct tbl *tp = NULL;
|
||||
|
||||
for (l = e->loc; l; l = l->next) {
|
||||
tp = ktsearch(&l->funs, name, h, pte);
|
||||
tp = ktsearch(&l->funs, name, h);
|
||||
if (tp)
|
||||
break;
|
||||
if (!l->next && create) {
|
||||
tp = ktenter(&l->funs, name, h, pte);
|
||||
tp = ktenter(&l->funs, name, h);
|
||||
tp->flag = DEFINED;
|
||||
tp->type = CFUNC;
|
||||
tp->val.t = NULL;
|
||||
@ -828,11 +828,10 @@ 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, &te);
|
||||
tp = findfunc(name, hash(name), true);
|
||||
|
||||
if (tp->flag & ISSET)
|
||||
was_set = true;
|
||||
@ -853,7 +852,7 @@ define(const char *name, struct op *t)
|
||||
}
|
||||
|
||||
if (t == NULL) { /* undefine */
|
||||
ktremove(&te);
|
||||
ktdelete(tp);
|
||||
return (was_set ? 0 : 1);
|
||||
}
|
||||
|
||||
@ -886,7 +885,7 @@ builtin(const char *name, int (*func) (const char **))
|
||||
break;
|
||||
}
|
||||
|
||||
tp = ktenter(&builtins, name, hash(name), NULL);
|
||||
tp = ktenter(&builtins, name, hash(name));
|
||||
tp->flag = DEFINED | flag;
|
||||
tp->type = CSHELL;
|
||||
tp->val.f = func;
|
||||
@ -912,14 +911,14 @@ findcom(const char *name, int flags)
|
||||
flags &= ~FC_FUNC;
|
||||
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 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, NULL);
|
||||
tp = findfunc(name, h, false);
|
||||
if (tp && !(tp->flag & ISSET)) {
|
||||
if ((fpath = str_val(global("FPATH"))) == null) {
|
||||
tp->u.fpath = NULL;
|
||||
@ -934,7 +933,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, NULL);
|
||||
tp = ktsearch(&taliases, name, h);
|
||||
if (tp && (tp->flag & ISSET) && access(tp->val.s, X_OK) != 0) {
|
||||
if (tp->flag & ALLOC) {
|
||||
tp->flag &= ~ALLOC;
|
||||
@ -949,7 +948,7 @@ findcom(const char *name, int flags)
|
||||
(flags & FC_PATH)) {
|
||||
if (!tp) {
|
||||
if (insert && !(flags & FC_DEFPATH)) {
|
||||
tp = ktenter(&taliases, name, h, NULL);
|
||||
tp = ktenter(&taliases, name, h);
|
||||
tp->type = CTALIAS;
|
||||
} else {
|
||||
tp = &temp;
|
||||
|
4
expr.c
4
expr.c
@ -22,7 +22,7 @@
|
||||
|
||||
#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[] */
|
||||
enum token {
|
||||
@ -608,6 +608,8 @@ tempvar(void)
|
||||
vp->flag = ISSET|INTEGER;
|
||||
vp->type = 0;
|
||||
vp->areap = ATEMP;
|
||||
vp->tablep = NULL;
|
||||
vp->hval = 0;
|
||||
vp->val.i = 0;
|
||||
vp->name[0] = '\0';
|
||||
return (vp);
|
||||
|
16
funcs.c
16
funcs.c
@ -25,7 +25,7 @@
|
||||
|
||||
#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
|
||||
/*
|
||||
@ -637,11 +637,13 @@ c_whence(const char **wp)
|
||||
fcflags &= ~(FC_BI | FC_FUNC);
|
||||
|
||||
while ((vflag || rv == 0) && (id = *wp++) != NULL) {
|
||||
uint32_t h = 0;
|
||||
|
||||
tp = NULL;
|
||||
if ((iam_whence || vflag) && !pflag)
|
||||
tp = ktsearch(&keywords, id, hash(id), NULL);
|
||||
tp = ktsearch(&keywords, id, h = hash(id));
|
||||
if (!tp && !pflag) {
|
||||
tp = ktsearch(&aliases, id, hash(id), NULL);
|
||||
tp = ktsearch(&aliases, id, h ? h : hash(id));
|
||||
if (tp && !(tp->flag & ISSET))
|
||||
tp = NULL;
|
||||
}
|
||||
@ -879,7 +881,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, NULL);
|
||||
(fset&UCASEV_AL) ? true : false);
|
||||
if (!f) {
|
||||
/* AT&T ksh does ++rv: bogus */
|
||||
rv = 1;
|
||||
@ -1138,7 +1140,7 @@ c_alias(const char **wp)
|
||||
}
|
||||
h = hash(alias);
|
||||
if (val == NULL && !tflag && !xflag) {
|
||||
ap = ktsearch(t, alias, h, NULL);
|
||||
ap = ktsearch(t, alias, h);
|
||||
if (ap != NULL && (ap->flag&ISSET)) {
|
||||
if (pflag)
|
||||
shf_puts("alias ", shl_stdout);
|
||||
@ -1154,7 +1156,7 @@ c_alias(const char **wp)
|
||||
}
|
||||
continue;
|
||||
}
|
||||
ap = ktenter(t, alias, h, NULL);
|
||||
ap = ktenter(t, alias, h);
|
||||
ap->type = tflag ? CTALIAS : CALIAS;
|
||||
/* Are we setting the value or just some flags? */
|
||||
if ((val && !tflag) || (!val && tflag && !Uflag)) {
|
||||
@ -1214,7 +1216,7 @@ c_unalias(const char **wp)
|
||||
wp += builtin_opt.optind;
|
||||
|
||||
for (; *wp != NULL; wp++) {
|
||||
ap = ktsearch(t, *wp, hash(*wp), NULL);
|
||||
ap = ktsearch(t, *wp, hash(*wp));
|
||||
if (ap == NULL) {
|
||||
rv = 1; /* POSIX */
|
||||
continue;
|
||||
|
10
lex.c
10
lex.c
@ -22,7 +22,7 @@
|
||||
|
||||
#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
|
||||
@ -909,17 +909,15 @@ 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, NULL)) &&
|
||||
if ((cf & KEYWORD) && (p = ktsearch(&keywords, ident, h)) &&
|
||||
(!(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, &te)) &&
|
||||
if ((cf & ALIAS) && (p = ktsearch(&aliases, ident, h)) &&
|
||||
(p->flag & ISSET)) {
|
||||
/*
|
||||
* this still points to the same character as the
|
||||
@ -946,7 +944,7 @@ yylex(int cf)
|
||||
* delete alias upon encountering function
|
||||
* definition
|
||||
*/
|
||||
ktremove(&te);
|
||||
ktdelete(p);
|
||||
else {
|
||||
Source *s = source;
|
||||
|
||||
|
100
main.c
100
main.c
@ -33,7 +33,7 @@
|
||||
#include <locale.h>
|
||||
#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;
|
||||
|
||||
@ -1236,6 +1236,8 @@ maketemp(Area *ap, Temp_type type, struct temp **tlist)
|
||||
|
||||
static void texpand(struct table *, size_t);
|
||||
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 */
|
||||
uint32_t
|
||||
@ -1276,7 +1278,7 @@ texpand(struct table *tp, size_t nsize)
|
||||
for (i = 0; i < osize; i++)
|
||||
if ((tblp = otblp[i]) != NULL) {
|
||||
if ((tblp->flag & DEFINED)) {
|
||||
for (p = &ntblp[hash(tblp->name) &
|
||||
for (p = &ntblp[tblp->hval &
|
||||
(tp->size - 1)]; *p != NULL; p--)
|
||||
if (p == ntblp) /* wrap */
|
||||
p += tp->size;
|
||||
@ -1299,48 +1301,39 @@ ktinit(struct table *tp, Area *ap, size_t tsize)
|
||||
texpand(tp, tsize);
|
||||
}
|
||||
|
||||
void
|
||||
ktremove(struct table_entry *pte)
|
||||
/* table, name (key) to search for, hash(n) */
|
||||
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);
|
||||
*(pte->ep) = NULL;
|
||||
++(pte->tp->nfree);
|
||||
/* search for name in hashed table */
|
||||
for (pp = &tp->tbls[h & (tp->size - 1)]; (p = *pp) != NULL; pp--) {
|
||||
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) */
|
||||
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;
|
||||
|
||||
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);
|
||||
return (tp->size ? ktscan(tp, n, h, NULL) : NULL);
|
||||
}
|
||||
|
||||
/* table, name (key) to enter, hash(n) */
|
||||
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;
|
||||
int len;
|
||||
@ -1348,30 +1341,23 @@ ktenter(struct table *tp, const char *n, uint32_t h, struct table_entry *pte)
|
||||
if (tp->size == 0)
|
||||
texpand(tp, INIT_TBLS);
|
||||
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) {
|
||||
/* found */
|
||||
if (pte) {
|
||||
pte->tp = tp;
|
||||
pte->ep = pp;
|
||||
}
|
||||
return (p);
|
||||
}
|
||||
if (pp == tp->tbls) /* wrap */
|
||||
pp += tp->size;
|
||||
}
|
||||
if ((p = ktscan(tp, n, h, &pp)))
|
||||
return (p);
|
||||
|
||||
if (tp->nfree <= 0) { /* too full */
|
||||
if (tp->nfree <= 0) {
|
||||
/* too full */
|
||||
texpand(tp, 2 * tp->size);
|
||||
goto Search;
|
||||
}
|
||||
|
||||
/* create new tbl entry */
|
||||
len = strlen(n) + 1;
|
||||
p = alloc(offsetof(struct tbl, name[0]) + len, tp->areap);
|
||||
p->flag = 0;
|
||||
p->type = 0;
|
||||
p->areap = tp->areap;
|
||||
p->tablep = tp;
|
||||
p->hval = h;
|
||||
p->u2.field = 0;
|
||||
p->u.array = NULL;
|
||||
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 */
|
||||
tp->nfree--;
|
||||
*pp = p;
|
||||
if (pte) {
|
||||
pte->tp = tp;
|
||||
pte->ep = pp;
|
||||
}
|
||||
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
|
||||
ktwalk(struct tstate *ts, struct table *tp)
|
||||
{
|
||||
|
17
sh.h
17
sh.h
@ -134,7 +134,7 @@
|
||||
#endif
|
||||
|
||||
#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
|
||||
#define MKSH_VERSION "R39 2009/08/08"
|
||||
|
||||
@ -851,11 +851,6 @@ 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 {
|
||||
@ -869,6 +864,7 @@ struct tbl { /* table item */
|
||||
struct tbl *array; /* array values */
|
||||
const char *fpath; /* temporary path to undef function */
|
||||
} u;
|
||||
struct table *tablep; /* table we're ktenter'd in */
|
||||
union {
|
||||
int field; /* field with for -L/-R/-Z */
|
||||
int errno_; /* CEXEC/CTALIAS */
|
||||
@ -876,6 +872,7 @@ struct tbl { /* table item */
|
||||
int type; /* command type (see below), base (if INTEGER),
|
||||
* or offset from val.s of value (if EXPORT) */
|
||||
Tflag flag; /* flags */
|
||||
uint32_t hval; /* hash(name) */
|
||||
uint32_t index; /* index for an array */
|
||||
char name[4]; /* name -- variable length */
|
||||
};
|
||||
@ -1376,7 +1373,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 table_entry *);
|
||||
struct tbl *findfunc(const char *, uint32_t, bool);
|
||||
int define(const char *, struct op *);
|
||||
void builtin(const char *, int (*)(const char **));
|
||||
struct tbl *findcom(const char *, int);
|
||||
@ -1545,9 +1542,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 table_entry *);
|
||||
struct tbl *ktenter(struct table *, const char *, uint32_t, struct table_entry *);
|
||||
void ktremove(struct table_entry *);
|
||||
struct tbl *ktsearch(struct table *, const char *, uint32_t);
|
||||
struct tbl *ktenter(struct table *, const char *, uint32_t);
|
||||
void ktdelete(struct tbl *);
|
||||
void ktwalk(struct tstate *, struct table *);
|
||||
struct tbl *ktnext(struct tstate *);
|
||||
struct tbl **ktsort(struct table *);
|
||||
|
4
syn.c
4
syn.c
@ -22,7 +22,7 @@
|
||||
|
||||
#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 {
|
||||
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), NULL);
|
||||
p = ktenter(&keywords, tt->name, hash(tt->name));
|
||||
p->flag |= DEFINED|ISSET;
|
||||
p->type = CKEYWD;
|
||||
p->val.i = tt->val;
|
||||
|
31
var.c
31
var.c
@ -22,7 +22,7 @@
|
||||
|
||||
#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
|
||||
@ -128,8 +128,7 @@ 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),
|
||||
NULL);
|
||||
tp = ktenter(&specials, names[i].name, hash(names[i].name));
|
||||
tp->flag = DEFINED|ISSET;
|
||||
tp->type = names[i].v;
|
||||
}
|
||||
@ -226,7 +225,7 @@ global(const char *n)
|
||||
return (vp);
|
||||
}
|
||||
for (l = e->loc; ; l = l->next) {
|
||||
vp = ktsearch(&l->vars, n, h, NULL);
|
||||
vp = ktsearch(&l->vars, n, h);
|
||||
if (vp != NULL) {
|
||||
if (array)
|
||||
return (arraysearch(vp, val));
|
||||
@ -236,7 +235,7 @@ global(const char *n)
|
||||
if (l->next == NULL)
|
||||
break;
|
||||
}
|
||||
vp = ktenter(&l->vars, n, h, NULL);
|
||||
vp = ktenter(&l->vars, n, h);
|
||||
if (array)
|
||||
vp = arraysearch(vp, val);
|
||||
vp->flag |= DEFINED;
|
||||
@ -266,13 +265,12 @@ local(const char *n, bool copy)
|
||||
vp->areap = ATEMP;
|
||||
return (vp);
|
||||
}
|
||||
vp = ktenter(&l->vars, n, h, NULL);
|
||||
vp = ktenter(&l->vars, n, h);
|
||||
if (copy && !(vp->flag & DEFINED)) {
|
||||
struct block *ll = l;
|
||||
struct tbl *vq = NULL;
|
||||
|
||||
while ((ll = ll->next) && !(vq = ktsearch(&ll->vars, n, h,
|
||||
NULL)))
|
||||
while ((ll = ll->next) && !(vq = ktsearch(&ll->vars, n, h)))
|
||||
;
|
||||
if (vq) {
|
||||
vp->flag |= vq->flag &
|
||||
@ -894,8 +892,7 @@ makenv(void)
|
||||
|
||||
/* unexport any redefined instances */
|
||||
for (l2 = l->next; l2 != NULL; l2 = l2->next) {
|
||||
vp2 = ktsearch(&l2->vars, vp->name, h,
|
||||
NULL);
|
||||
vp2 = ktsearch(&l2->vars, vp->name, h);
|
||||
if (vp2 != NULL)
|
||||
vp2->flag &= ~EXPORT;
|
||||
}
|
||||
@ -1029,7 +1026,7 @@ special(const char *name)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -1037,11 +1034,11 @@ special(const char *name)
|
||||
static void
|
||||
unspecial(const char *name)
|
||||
{
|
||||
struct table_entry te = { NULL, NULL };
|
||||
struct tbl *tp;
|
||||
|
||||
ktsearch(&specials, name, hash(name), &te);
|
||||
if (te.ep)
|
||||
ktremove(&te);
|
||||
tp = ktsearch(&specials, name, hash(name));
|
||||
if (tp)
|
||||
ktdelete(tp);
|
||||
}
|
||||
|
||||
static time_t seconds; /* time SECONDS last set */
|
||||
@ -1269,6 +1266,10 @@ arraysearch(struct tbl *vp, uint32_t val)
|
||||
new->areap = vp->areap;
|
||||
new->u2.field = vp->u2.field;
|
||||
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 */
|
||||
prev->u.array = new;
|
||||
new->u.array = curr;
|
||||
|
Loading…
x
Reference in New Issue
Block a user