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"
|
#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
4
eval.c
@ -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
27
exec.c
@ -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
4
expr.c
@ -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
16
funcs.c
@ -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
10
lex.c
@ -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
98
main.c
@ -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
17
sh.h
@ -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
4
syn.c
@ -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
31
var.c
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user