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 */