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>
diff --git a/shell/ash.c b/shell/ash.c
index 9e7da1e..d77d9d3 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -279,6 +279,14 @@
return (*str == '\0');
}
+static const char *var_end(const char *var)
+{
+ while (*var)
+ if (*var++ == '=')
+ break;
+ return var;
+}
+
/* ============ Interrupts / exceptions */
/*
@@ -1712,8 +1720,8 @@
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 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 @@
{ 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 @@
(*(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 @@
* 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 @@
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 @@
* 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 @@
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 @@
* 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 @@
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 @@
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 @@
}
if (!(flags & (VTEXTFIXED|VSTACK|VNOSAVE)))
s = ckstrdup(s);
- vp->text = s;
+ vp->var_text = s;
vp->flags = flags;
}
@@ -2171,7 +2173,7 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
* is present
*/
p = (*spp)->text;
- if (varequal(p, path))
+ if (varcmp(p, path) == 0)
path = p;
}
@@ -10113,7 +10115,7 @@
/* "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 */