ash: revert previous implementation of "A=1 A=2 B=$A cmd" code
Reverts this:
commit 0e6f661e23
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:
parent
d04fc712e3
commit
b8c0bc18f0
62
shell/ash.c
62
shell/ash.c
@ -6304,19 +6304,15 @@ expari(int flag)
|
||||
#endif
|
||||
|
||||
/* 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
|
||||
* characters to allow for further processing. Otherwise treat
|
||||
* $@ 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
|
||||
argstr(char *p, int flags, struct strlist *var_str_list)
|
||||
argstr(char *p, int flags)
|
||||
{
|
||||
static const char spclchars[] ALIGN1 = {
|
||||
'=',
|
||||
@ -6409,7 +6405,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
|
||||
inquotes ^= EXP_QUOTED;
|
||||
/* "$@" syntax adherence hack */
|
||||
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;
|
||||
}
|
||||
addquote:
|
||||
@ -6435,7 +6431,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
|
||||
goto addquote;
|
||||
case CTLVAR:
|
||||
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()));
|
||||
goto start;
|
||||
case CTLBACKQ:
|
||||
@ -6577,7 +6573,7 @@ varunset(const char *end, const char *var, const char *umsg, int varflags)
|
||||
|
||||
static const char *
|
||||
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;
|
||||
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);
|
||||
|
||||
argstr(p, EXP_TILDE | (subtype != VSASSIGN && subtype != VSQUESTION ?
|
||||
(flag & (EXP_QUOTED | EXP_QPAT) ? EXP_QPAT : EXP_CASE) : 0),
|
||||
var_str_list);
|
||||
(flag & (EXP_QUOTED | EXP_QPAT) ? EXP_QPAT : EXP_CASE) : 0)
|
||||
);
|
||||
STPUTC('\0', expdest);
|
||||
argbackq = saveargbackq;
|
||||
startp = (char *)stackblock() + startloc;
|
||||
@ -6873,7 +6869,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
||||
* ash -c 'echo ${#1#}' name:'1=#'
|
||||
*/
|
||||
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;
|
||||
int num;
|
||||
@ -6965,31 +6961,6 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int
|
||||
goto value;
|
||||
default:
|
||||
/* 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);
|
||||
value:
|
||||
if (!p)
|
||||
@ -7019,7 +6990,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int
|
||||
* input string.
|
||||
*/
|
||||
static char *
|
||||
evalvar(char *p, int flag, struct strlist *var_str_list)
|
||||
evalvar(char *p, int flag)
|
||||
{
|
||||
char varflags;
|
||||
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)?
|
||||
|
||||
again:
|
||||
varlen = varvalue(var, varflags, flag, var_str_list, "ed);
|
||||
varlen = varvalue(var, varflags, flag, "ed);
|
||||
if (varflags & VSNUL)
|
||||
varlen--;
|
||||
|
||||
@ -7057,8 +7028,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
|
||||
if (varlen < 0) {
|
||||
argstr(
|
||||
p,
|
||||
flag | EXP_TILDE | EXP_WORD,
|
||||
var_str_list
|
||||
flag | EXP_TILDE | EXP_WORD
|
||||
);
|
||||
goto end;
|
||||
}
|
||||
@ -7070,7 +7040,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
|
||||
goto record;
|
||||
|
||||
subevalvar(p, var, 0, subtype, startloc, varflags,
|
||||
flag & ~QUOTES_ESC, var_str_list);
|
||||
flag & ~QUOTES_ESC);
|
||||
varflags &= ~VSNUL;
|
||||
/*
|
||||
* Remove any recorded regions beyond
|
||||
@ -7123,7 +7093,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
|
||||
STPUTC('\0', expdest);
|
||||
patloc = expdest - (char *)stackblock();
|
||||
if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
|
||||
startloc, varflags, flag, var_str_list)) {
|
||||
startloc, varflags, flag)) {
|
||||
int amount = expdest - (
|
||||
(char *)stackblock() + patloc - 1
|
||||
);
|
||||
@ -7547,8 +7517,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
|
||||
argbackq = arg->narg.backquote;
|
||||
STARTSTACKSTR(expdest);
|
||||
TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
|
||||
argstr(arg->narg.text, flag,
|
||||
/* var_str_list: */ arglist ? arglist->list : NULL);
|
||||
argstr(arg->narg.text, flag);
|
||||
p = _STPUTC('\0', expdest);
|
||||
expdest = p - 1;
|
||||
if (arglist == NULL) {
|
||||
@ -7615,8 +7584,7 @@ casematch(union node *pattern, char *val)
|
||||
setstackmark(&smark);
|
||||
argbackq = pattern->narg.backquote;
|
||||
STARTSTACKSTR(expdest);
|
||||
argstr(pattern->narg.text, EXP_TILDE | EXP_CASE,
|
||||
/* var_str_list: */ NULL);
|
||||
argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
|
||||
STACKSTRNUL(expdest);
|
||||
ifsfree();
|
||||
result = patmatch(stackblock(), val);
|
||||
|
Loading…
Reference in New Issue
Block a user