ash: remove one redundant function, improve string sharing, better field names

function                                             old     new   delta
var_end                                                -      15     +15
changepath                                           194     192      -2
setvareq                                             222     218      -4
lookupvar                                             57      51      -6
bltinlookup                                           57      51      -6
evalfun                                              452     443      -9
varequal                                              14       -     -14
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 0/5 up/down: 15/-41)            Total: -26 bytes

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2010-06-02 12:56:18 +02:00
parent 8376bfae58
commit 8837c5dec4

View File

@ -279,6 +279,14 @@ static int isdigit_str9(const char *str)
return (*str == '\0');
}
static const char *var_end(const char *var)
{
while (*var)
if (*var++ == '=')
break;
return var;
}
/* ============ Interrupts / exceptions */
/*
@ -1712,8 +1720,8 @@ static void FAST_FUNC getoptsreset(const char *value);
struct var {
struct var *next; /* next entry in hash list */
int flags; /* flags are defined above */
const char *text; /* name=value */
void (*func)(const char *) FAST_FUNC; /* function to be called when */
const char *var_text; /* name=value */
void (*var_func)(const char *) FAST_FUNC; /* function to be called when */
/* the variable gets set/unset */
};
@ -1767,13 +1775,13 @@ static void change_random(const char *) FAST_FUNC;
static const struct {
int flags;
const char *text;
void (*func)(const char *) FAST_FUNC;
const char *var_text;
void (*var_func)(const char *) FAST_FUNC;
} varinit_data[] = {
{ VSTRFIXED|VTEXTFIXED , defifsvar , NULL },
#if ENABLE_ASH_MAIL
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL\0" , changemail },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH\0", changemail },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL" , changemail },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH" , changemail },
#endif
{ VSTRFIXED|VTEXTFIXED , bb_PATH_root_path, changepath },
{ VSTRFIXED|VTEXTFIXED , "PS1=$ " , NULL },
@ -1783,14 +1791,14 @@ static const struct {
{ VSTRFIXED|VTEXTFIXED , "OPTIND=1" , getoptsreset },
#endif
#if ENABLE_ASH_RANDOM_SUPPORT
{ VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM\0", change_random },
{ VSTRFIXED|VTEXTFIXED|VUNSET|VDYNAMIC, "RANDOM", change_random },
#endif
#if ENABLE_LOCALE_SUPPORT
{ VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL\0" , change_lc_all },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE\0", change_lc_ctype },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "LC_ALL" , change_lc_all },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "LC_CTYPE" , change_lc_ctype },
#endif
#if ENABLE_FEATURE_EDITING_SAVEHISTORY
{ VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE\0", NULL },
{ VSTRFIXED|VTEXTFIXED|VUNSET, "HISTFILE" , NULL },
#endif
};
@ -1817,9 +1825,9 @@ extern struct globals_var *const ash_ptr_to_globals_var;
(*(struct globals_var**)&ash_ptr_to_globals_var) = xzalloc(sizeof(G_var)); \
barrier(); \
for (i = 0; i < ARRAY_SIZE(varinit_data); i++) { \
varinit[i].flags = varinit_data[i].flags; \
varinit[i].text = varinit_data[i].text; \
varinit[i].func = varinit_data[i].func; \
varinit[i].flags = varinit_data[i].flags; \
varinit[i].var_text = varinit_data[i].var_text; \
varinit[i].var_func = varinit_data[i].var_func; \
} \
} while (0)
@ -1850,19 +1858,19 @@ extern struct globals_var *const ash_ptr_to_globals_var;
* They have to skip over the name. They return the null string
* for unset variables.
*/
#define ifsval() (vifs.text + 4)
#define ifsval() (vifs.var_text + 4)
#define ifsset() ((vifs.flags & VUNSET) == 0)
#if ENABLE_ASH_MAIL
# define mailval() (vmail.text + 5)
# define mpathval() (vmpath.text + 9)
# define mailval() (vmail.var_text + 5)
# define mpathval() (vmpath.var_text + 9)
# define mpathset() ((vmpath.flags & VUNSET) == 0)
#endif
#define pathval() (vpath.text + 5)
#define ps1val() (vps1.text + 4)
#define ps2val() (vps2.text + 4)
#define ps4val() (vps4.text + 4)
#define pathval() (vpath.var_text + 5)
#define ps1val() (vps1.var_text + 4)
#define ps2val() (vps2.var_text + 4)
#define ps4val() (vps4.var_text + 4)
#if ENABLE_ASH_GETOPTS
# define optindval() (voptind.text + 7)
# define optindval() (voptind.var_text + 7)
#endif
@ -1921,12 +1929,6 @@ varcmp(const char *p, const char *q)
return c - d;
}
static int
varequal(const char *a, const char *b)
{
return !varcmp(a, b);
}
/*
* Find the appropriate entry in the hash table from the name.
*/
@ -1961,15 +1963,15 @@ initvar(void)
* PS1 depends on uid
*/
#if ENABLE_FEATURE_EDITING && ENABLE_FEATURE_EDITING_FANCY_PROMPT
vps1.text = "PS1=\\w \\$ ";
vps1.var_text = "PS1=\\w \\$ ";
#else
if (!geteuid())
vps1.text = "PS1=# ";
vps1.var_text = "PS1=# ";
#endif
vp = varinit;
end = vp + ARRAY_SIZE(varinit);
do {
vpp = hashvar(vp->text);
vpp = hashvar(vp->var_text);
vp->next = *vpp;
*vpp = vp;
} while (++vp < end);
@ -1979,7 +1981,7 @@ static struct var **
findvar(struct var **vpp, const char *name)
{
for (; *vpp; vpp = &(*vpp)->next) {
if (varequal((*vpp)->text, name)) {
if (varcmp((*vpp)->var_text, name) == 0) {
break;
}
}
@ -2003,11 +2005,11 @@ lookupvar(const char *name)
* As soon as they're unset, they're no longer dynamic, and dynamic
* lookup will no longer happen at that point. -- PFM.
*/
if ((v->flags & VDYNAMIC))
(*v->func)(NULL);
if (v->flags & VDYNAMIC)
v->var_func(NULL);
#endif
if (!(v->flags & VUNSET))
return strchrnul(v->text, '=') + 1;
return var_end(v->var_text);
}
return NULL;
}
@ -2021,8 +2023,8 @@ bltinlookup(const char *name)
struct strlist *sp;
for (sp = cmdenviron; sp; sp = sp->next) {
if (varequal(sp->text, name))
return strchrnul(sp->text, '=') + 1;
if (varcmp(sp->text, name) == 0)
return var_end(sp->text);
}
return lookupvar(name);
}
@ -2048,24 +2050,24 @@ setvareq(char *s, int flags)
if (flags & VNOSAVE)
free(s);
n = vp->text;
n = vp->var_text;
ash_msg_and_raise_error("%.*s: is read only", strchrnul(n, '=') - n, n);
}
if (flags & VNOSET)
return;
if (vp->func && (flags & VNOFUNC) == 0)
(*vp->func)(strchrnul(s, '=') + 1);
if (vp->var_func && !(flags & VNOFUNC))
vp->var_func(var_end(s));
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
free((char*)vp->text);
if (!(vp->flags & (VTEXTFIXED|VSTACK)))
free((char*)vp->var_text);
flags |= vp->flags & ~(VTEXTFIXED|VSTACK|VNOSAVE|VUNSET);
} else {
/* variable s is not found */
if (flags & VNOSET)
return;
/* not found */
vp = ckzalloc(sizeof(*vp));
vp->next = *vpp;
/*vp->func = NULL; - ckzalloc did it */
@ -2073,7 +2075,7 @@ setvareq(char *s, int flags)
}
if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
s = ckstrdup(s);
vp->text = s;
vp->var_text = s;
vp->flags = flags;
}
@ -2171,7 +2173,7 @@ unsetvar(const char *s)
if ((flags & VSTRFIXED) == 0) {
INT_OFF;
if ((flags & (VTEXTFIXED|VSTACK)) == 0)
free((char*)vp->text);
free((char*)vp->var_text);
*vpp = vp->next;
free(vp);
INT_ON;
@ -2223,7 +2225,7 @@ listvars(int on, int off, char ***end)
if ((vp->flags & mask) == on) {
if (ep == stackstrend())
ep = growstackstr();
*ep++ = (char *) vp->text;
*ep++ = (char*)vp->var_text;
}
}
} while (++vpp < vartab + VTABSIZE);
@ -6591,7 +6593,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
var = p;
easy = (!quoted || (*var == '@' && shellparam.nparam));
startloc = expdest - (char *)stackblock();
p = strchr(p, '=') + 1;
p = strchr(p, '=') + 1; //TODO: use var_end(p)?
again:
varlen = varvalue(var, varflags, flags, var_str_list);
@ -8637,14 +8639,14 @@ poplocalvars(void)
free((char*)lvp->text);
optschanged();
} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
unsetvar(vp->text);
unsetvar(vp->var_text);
} else {
if (vp->func)
(*vp->func)(strchrnul(lvp->text, '=') + 1);
if (vp->var_func)
vp->var_func(var_end(lvp->text));
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
free((char*)vp->text);
free((char*)vp->var_text);
vp->flags = lvp->flags;
vp->text = lvp->text;
vp->var_text = lvp->text;
}
free(lvp);
}
@ -8763,7 +8765,7 @@ mklocal(char *name)
vp = *vpp; /* the new variable */
lvp->flags = VUNSET;
} else {
lvp->text = vp->text;
lvp->text = vp->var_text;
lvp->flags = vp->flags;
vp->flags |= VSTRFIXED|VTEXTFIXED;
if (eq)
@ -9073,7 +9075,7 @@ evalcommand(union node *cmd, int flags)
expredir(cmd->ncmd.redirect);
status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
path = vpath.text;
path = vpath.var_text;
for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
struct strlist **spp;
char *p;
@ -9086,7 +9088,7 @@ evalcommand(union node *cmd, int flags)
* is present
*/
p = (*spp)->text;
if (varequal(p, path))
if (varcmp(p, path) == 0)
path = p;
}
@ -10113,7 +10115,7 @@ change_random(const char *value)
/* "get", generate */
t = next_random(&random_gen);
/* set without recursion */
setvar(vrandom.text, utoa(t), VNOFUNC);
setvar(vrandom.var_text, utoa(t), VNOFUNC);
vrandom.flags &= ~VNOFUNC;
} else {
/* set/reset */