ash: revert previous implementation of "A=1 A=2 B=$A cmd" code

Reverts this:

    commit 0e6f661e23d358cca104c24f8438d0ec64df32f1
    Date:   Fri Feb 15 15:02:15 2008 +0000
    ash: handle "A=1 A=2 B=$A; echo $B". closes bug 947.

A different fix from upstream has been imported by previous six commits.

Last seven commits, cumulative:

function                                             old     new   delta
poplocalvars                                           -     314    +314
mklocal                                                -     288    +288
pushlocalvars                                          -      48     +48
evalcommand                                         1372    1408     +36
unwindlocalvars                                        -      22     +22
ash_main                                            1022    1029      +7
setvar                                               167     172      +5
localvar_stack                                         -       4      +4
setvareq                                             303     302      -1
evalcase                                             271     269      -2
subevalvar                                          1202    1198      -4
localvars                                              4       -      -4
cmdenviron                                             4       -      -4
expandarg                                            984     973     -11
evalvar                                              589     574     -15
argstr                                              1164    1141     -23
dotcmd                                               335     303     -32
bltinlookup                                           51       5     -46
varvalue                                             709     596    -113
evalfun                                              456     270    -186
localcmd                                             364      44    -320
------------------------------------------------------------------------------
(add/remove: 5/2 grow/shrink: 3/11 up/down: 724/-761)         Total: -37 bytes
   text	   data	    bss	    dec	    hex	filename
 915353	    485	   6888	 922726	  e1466	busybox_old
 915320	    485	   6880	 922685	  e143d	busybox_unstripped

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2017-07-26 23:03:21 +02:00
parent d04fc712e3
commit b8c0bc18f0

View File

@ -6304,19 +6304,15 @@ expari(int flag)
#endif #endif
/* argstr needs it */ /* argstr needs it */
static char *evalvar(char *p, int flags, struct strlist *var_str_list); static char *evalvar(char *p, int flags);
/* /*
* Perform variable and command substitution. If EXP_FULL is set, output CTLESC * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
* characters to allow for further processing. Otherwise treat * characters to allow for further processing. Otherwise treat
* $@ like $* since no splitting will be performed. * $@ like $* since no splitting will be performed.
*
* var_str_list (can be NULL) is a list of "VAR=val" strings which take precedence
* over shell variables. Needed for "A=a B=$A; echo $B" case - we use it
* for correct expansion of "B=$A" word.
*/ */
static void static void
argstr(char *p, int flags, struct strlist *var_str_list) argstr(char *p, int flags)
{ {
static const char spclchars[] ALIGN1 = { static const char spclchars[] ALIGN1 = {
'=', '=',
@ -6409,7 +6405,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
inquotes ^= EXP_QUOTED; inquotes ^= EXP_QUOTED;
/* "$@" syntax adherence hack */ /* "$@" syntax adherence hack */
if (inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) { if (inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
p = evalvar(p + 1, flags | inquotes, /* var_str_list: */ NULL) + 1; p = evalvar(p + 1, flags | inquotes) + 1;
goto start; goto start;
} }
addquote: addquote:
@ -6435,7 +6431,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
goto addquote; goto addquote;
case CTLVAR: case CTLVAR:
TRACE(("argstr: evalvar('%s')\n", p)); TRACE(("argstr: evalvar('%s')\n", p));
p = evalvar(p, flags | inquotes, var_str_list); p = evalvar(p, flags | inquotes);
TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock())); TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
goto start; goto start;
case CTLBACKQ: case CTLBACKQ:
@ -6577,7 +6573,7 @@ varunset(const char *end, const char *var, const char *umsg, int varflags)
static const char * static const char *
subevalvar(char *p, char *varname, int strloc, int subtype, subevalvar(char *p, char *varname, int strloc, int subtype,
int startloc, int varflags, int flag, struct strlist *var_str_list) int startloc, int varflags, int flag)
{ {
struct nodelist *saveargbackq = argbackq; struct nodelist *saveargbackq = argbackq;
int quotes = flag & QUOTES_ESC; int quotes = flag & QUOTES_ESC;
@ -6595,8 +6591,8 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
// p, varname, strloc, subtype, startloc, varflags, quotes); // p, varname, strloc, subtype, startloc, varflags, quotes);
argstr(p, EXP_TILDE | (subtype != VSASSIGN && subtype != VSQUESTION ? argstr(p, EXP_TILDE | (subtype != VSASSIGN && subtype != VSQUESTION ?
(flag & (EXP_QUOTED | EXP_QPAT) ? EXP_QPAT : EXP_CASE) : 0), (flag & (EXP_QUOTED | EXP_QPAT) ? EXP_QPAT : EXP_CASE) : 0)
var_str_list); );
STPUTC('\0', expdest); STPUTC('\0', expdest);
argbackq = saveargbackq; argbackq = saveargbackq;
startp = (char *)stackblock() + startloc; startp = (char *)stackblock() + startloc;
@ -6873,7 +6869,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
* ash -c 'echo ${#1#}' name:'1=#' * ash -c 'echo ${#1#}' name:'1=#'
*/ */
static NOINLINE ssize_t static NOINLINE ssize_t
varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int *quotedp) varvalue(char *name, int varflags, int flags, int *quotedp)
{ {
const char *p; const char *p;
int num; int num;
@ -6965,31 +6961,6 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int
goto value; goto value;
default: default:
/* NB: name has form "VAR=..." */ /* NB: name has form "VAR=..." */
/* "A=a B=$A" case: var_str_list is a list of "A=a" strings
* which should be considered before we check variables. */
if (var_str_list) {
unsigned name_len = (strchrnul(name, '=') - name) + 1;
p = NULL;
do {
char *str, *eq;
str = var_str_list->text;
eq = strchr(str, '=');
if (!eq) /* stop at first non-assignment */
break;
eq++;
if (name_len == (unsigned)(eq - str)
&& strncmp(str, name, name_len) == 0
) {
p = eq;
/* goto value; - WRONG! */
/* think "A=1 A=2 B=$A" */
}
var_str_list = var_str_list->next;
} while (var_str_list);
if (p)
goto value;
}
p = lookupvar(name); p = lookupvar(name);
value: value:
if (!p) if (!p)
@ -7019,7 +6990,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int
* input string. * input string.
*/ */
static char * static char *
evalvar(char *p, int flag, struct strlist *var_str_list) evalvar(char *p, int flag)
{ {
char varflags; char varflags;
char subtype; char subtype;
@ -7043,7 +7014,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
p = strchr(p, '=') + 1; //TODO: use var_end(p)? p = strchr(p, '=') + 1; //TODO: use var_end(p)?
again: again:
varlen = varvalue(var, varflags, flag, var_str_list, &quoted); varlen = varvalue(var, varflags, flag, &quoted);
if (varflags & VSNUL) if (varflags & VSNUL)
varlen--; varlen--;
@ -7057,8 +7028,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
if (varlen < 0) { if (varlen < 0) {
argstr( argstr(
p, p,
flag | EXP_TILDE | EXP_WORD, flag | EXP_TILDE | EXP_WORD
var_str_list
); );
goto end; goto end;
} }
@ -7070,7 +7040,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
goto record; goto record;
subevalvar(p, var, 0, subtype, startloc, varflags, subevalvar(p, var, 0, subtype, startloc, varflags,
flag & ~QUOTES_ESC, var_str_list); flag & ~QUOTES_ESC);
varflags &= ~VSNUL; varflags &= ~VSNUL;
/* /*
* Remove any recorded regions beyond * Remove any recorded regions beyond
@ -7123,7 +7093,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
STPUTC('\0', expdest); STPUTC('\0', expdest);
patloc = expdest - (char *)stackblock(); patloc = expdest - (char *)stackblock();
if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
startloc, varflags, flag, var_str_list)) { startloc, varflags, flag)) {
int amount = expdest - ( int amount = expdest - (
(char *)stackblock() + patloc - 1 (char *)stackblock() + patloc - 1
); );
@ -7547,8 +7517,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
argbackq = arg->narg.backquote; argbackq = arg->narg.backquote;
STARTSTACKSTR(expdest); STARTSTACKSTR(expdest);
TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag)); TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
argstr(arg->narg.text, flag, argstr(arg->narg.text, flag);
/* var_str_list: */ arglist ? arglist->list : NULL);
p = _STPUTC('\0', expdest); p = _STPUTC('\0', expdest);
expdest = p - 1; expdest = p - 1;
if (arglist == NULL) { if (arglist == NULL) {
@ -7615,8 +7584,7 @@ casematch(union node *pattern, char *val)
setstackmark(&smark); setstackmark(&smark);
argbackq = pattern->narg.backquote; argbackq = pattern->narg.backquote;
STARTSTACKSTR(expdest); STARTSTACKSTR(expdest);
argstr(pattern->narg.text, EXP_TILDE | EXP_CASE, argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
/* var_str_list: */ NULL);
STACKSTRNUL(expdest); STACKSTRNUL(expdest);
ifsfree(); ifsfree();
result = patmatch(stackblock(), val); result = patmatch(stackblock(), val);