aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-07-26 23:03:21 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-07-26 23:03:21 +0200
commitb8c0bc18f0cc31e3a2f41dd2c0b30426e4a77fc5 (patch)
tree593a170b42f42ef1aa8ca8e642a86cfaa40e41b1
parentd04fc712e30b681117afaad490fec2a747b390c6 (diff)
downloadbusybox-w32-b8c0bc18f0cc31e3a2f41dd2c0b30426e4a77fc5.tar.gz
busybox-w32-b8c0bc18f0cc31e3a2f41dd2c0b30426e4a77fc5.tar.bz2
busybox-w32-b8c0bc18f0cc31e3a2f41dd2c0b30426e4a77fc5.zip
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>
-rw-r--r--shell/ash.c62
1 files changed, 15 insertions, 47 deletions
diff --git a/shell/ash.c b/shell/ash.c
index 5bb59355c..faa42e28c 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -6304,19 +6304,15 @@ expari(int flag)
6304#endif 6304#endif
6305 6305
6306/* argstr needs it */ 6306/* argstr needs it */
6307static char *evalvar(char *p, int flags, struct strlist *var_str_list); 6307static char *evalvar(char *p, int flags);
6308 6308
6309/* 6309/*
6310 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC 6310 * Perform variable and command substitution. If EXP_FULL is set, output CTLESC
6311 * characters to allow for further processing. Otherwise treat 6311 * characters to allow for further processing. Otherwise treat
6312 * $@ like $* since no splitting will be performed. 6312 * $@ like $* since no splitting will be performed.
6313 *
6314 * var_str_list (can be NULL) is a list of "VAR=val" strings which take precedence
6315 * over shell variables. Needed for "A=a B=$A; echo $B" case - we use it
6316 * for correct expansion of "B=$A" word.
6317 */ 6313 */
6318static void 6314static void
6319argstr(char *p, int flags, struct strlist *var_str_list) 6315argstr(char *p, int flags)
6320{ 6316{
6321 static const char spclchars[] ALIGN1 = { 6317 static const char spclchars[] ALIGN1 = {
6322 '=', 6318 '=',
@@ -6409,7 +6405,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
6409 inquotes ^= EXP_QUOTED; 6405 inquotes ^= EXP_QUOTED;
6410 /* "$@" syntax adherence hack */ 6406 /* "$@" syntax adherence hack */
6411 if (inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) { 6407 if (inquotes && !memcmp(p, dolatstr + 1, DOLATSTRLEN - 1)) {
6412 p = evalvar(p + 1, flags | inquotes, /* var_str_list: */ NULL) + 1; 6408 p = evalvar(p + 1, flags | inquotes) + 1;
6413 goto start; 6409 goto start;
6414 } 6410 }
6415 addquote: 6411 addquote:
@@ -6435,7 +6431,7 @@ argstr(char *p, int flags, struct strlist *var_str_list)
6435 goto addquote; 6431 goto addquote;
6436 case CTLVAR: 6432 case CTLVAR:
6437 TRACE(("argstr: evalvar('%s')\n", p)); 6433 TRACE(("argstr: evalvar('%s')\n", p));
6438 p = evalvar(p, flags | inquotes, var_str_list); 6434 p = evalvar(p, flags | inquotes);
6439 TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock())); 6435 TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock()));
6440 goto start; 6436 goto start;
6441 case CTLBACKQ: 6437 case CTLBACKQ:
@@ -6577,7 +6573,7 @@ varunset(const char *end, const char *var, const char *umsg, int varflags)
6577 6573
6578static const char * 6574static const char *
6579subevalvar(char *p, char *varname, int strloc, int subtype, 6575subevalvar(char *p, char *varname, int strloc, int subtype,
6580 int startloc, int varflags, int flag, struct strlist *var_str_list) 6576 int startloc, int varflags, int flag)
6581{ 6577{
6582 struct nodelist *saveargbackq = argbackq; 6578 struct nodelist *saveargbackq = argbackq;
6583 int quotes = flag & QUOTES_ESC; 6579 int quotes = flag & QUOTES_ESC;
@@ -6595,8 +6591,8 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
6595 // p, varname, strloc, subtype, startloc, varflags, quotes); 6591 // p, varname, strloc, subtype, startloc, varflags, quotes);
6596 6592
6597 argstr(p, EXP_TILDE | (subtype != VSASSIGN && subtype != VSQUESTION ? 6593 argstr(p, EXP_TILDE | (subtype != VSASSIGN && subtype != VSQUESTION ?
6598 (flag & (EXP_QUOTED | EXP_QPAT) ? EXP_QPAT : EXP_CASE) : 0), 6594 (flag & (EXP_QUOTED | EXP_QPAT) ? EXP_QPAT : EXP_CASE) : 0)
6599 var_str_list); 6595 );
6600 STPUTC('\0', expdest); 6596 STPUTC('\0', expdest);
6601 argbackq = saveargbackq; 6597 argbackq = saveargbackq;
6602 startp = (char *)stackblock() + startloc; 6598 startp = (char *)stackblock() + startloc;
@@ -6873,7 +6869,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
6873 * ash -c 'echo ${#1#}' name:'1=#' 6869 * ash -c 'echo ${#1#}' name:'1=#'
6874 */ 6870 */
6875static NOINLINE ssize_t 6871static NOINLINE ssize_t
6876varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int *quotedp) 6872varvalue(char *name, int varflags, int flags, int *quotedp)
6877{ 6873{
6878 const char *p; 6874 const char *p;
6879 int num; 6875 int num;
@@ -6965,31 +6961,6 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int
6965 goto value; 6961 goto value;
6966 default: 6962 default:
6967 /* NB: name has form "VAR=..." */ 6963 /* NB: name has form "VAR=..." */
6968
6969 /* "A=a B=$A" case: var_str_list is a list of "A=a" strings
6970 * which should be considered before we check variables. */
6971 if (var_str_list) {
6972 unsigned name_len = (strchrnul(name, '=') - name) + 1;
6973 p = NULL;
6974 do {
6975 char *str, *eq;
6976 str = var_str_list->text;
6977 eq = strchr(str, '=');
6978 if (!eq) /* stop at first non-assignment */
6979 break;
6980 eq++;
6981 if (name_len == (unsigned)(eq - str)
6982 && strncmp(str, name, name_len) == 0
6983 ) {
6984 p = eq;
6985 /* goto value; - WRONG! */
6986 /* think "A=1 A=2 B=$A" */
6987 }
6988 var_str_list = var_str_list->next;
6989 } while (var_str_list);
6990 if (p)
6991 goto value;
6992 }
6993 p = lookupvar(name); 6964 p = lookupvar(name);
6994 value: 6965 value:
6995 if (!p) 6966 if (!p)
@@ -7019,7 +6990,7 @@ varvalue(char *name, int varflags, int flags, struct strlist *var_str_list, int
7019 * input string. 6990 * input string.
7020 */ 6991 */
7021static char * 6992static char *
7022evalvar(char *p, int flag, struct strlist *var_str_list) 6993evalvar(char *p, int flag)
7023{ 6994{
7024 char varflags; 6995 char varflags;
7025 char subtype; 6996 char subtype;
@@ -7043,7 +7014,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
7043 p = strchr(p, '=') + 1; //TODO: use var_end(p)? 7014 p = strchr(p, '=') + 1; //TODO: use var_end(p)?
7044 7015
7045 again: 7016 again:
7046 varlen = varvalue(var, varflags, flag, var_str_list, &quoted); 7017 varlen = varvalue(var, varflags, flag, &quoted);
7047 if (varflags & VSNUL) 7018 if (varflags & VSNUL)
7048 varlen--; 7019 varlen--;
7049 7020
@@ -7057,8 +7028,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
7057 if (varlen < 0) { 7028 if (varlen < 0) {
7058 argstr( 7029 argstr(
7059 p, 7030 p,
7060 flag | EXP_TILDE | EXP_WORD, 7031 flag | EXP_TILDE | EXP_WORD
7061 var_str_list
7062 ); 7032 );
7063 goto end; 7033 goto end;
7064 } 7034 }
@@ -7070,7 +7040,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
7070 goto record; 7040 goto record;
7071 7041
7072 subevalvar(p, var, 0, subtype, startloc, varflags, 7042 subevalvar(p, var, 0, subtype, startloc, varflags,
7073 flag & ~QUOTES_ESC, var_str_list); 7043 flag & ~QUOTES_ESC);
7074 varflags &= ~VSNUL; 7044 varflags &= ~VSNUL;
7075 /* 7045 /*
7076 * Remove any recorded regions beyond 7046 * Remove any recorded regions beyond
@@ -7123,7 +7093,7 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
7123 STPUTC('\0', expdest); 7093 STPUTC('\0', expdest);
7124 patloc = expdest - (char *)stackblock(); 7094 patloc = expdest - (char *)stackblock();
7125 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, 7095 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
7126 startloc, varflags, flag, var_str_list)) { 7096 startloc, varflags, flag)) {
7127 int amount = expdest - ( 7097 int amount = expdest - (
7128 (char *)stackblock() + patloc - 1 7098 (char *)stackblock() + patloc - 1
7129 ); 7099 );
@@ -7547,8 +7517,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
7547 argbackq = arg->narg.backquote; 7517 argbackq = arg->narg.backquote;
7548 STARTSTACKSTR(expdest); 7518 STARTSTACKSTR(expdest);
7549 TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag)); 7519 TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag));
7550 argstr(arg->narg.text, flag, 7520 argstr(arg->narg.text, flag);
7551 /* var_str_list: */ arglist ? arglist->list : NULL);
7552 p = _STPUTC('\0', expdest); 7521 p = _STPUTC('\0', expdest);
7553 expdest = p - 1; 7522 expdest = p - 1;
7554 if (arglist == NULL) { 7523 if (arglist == NULL) {
@@ -7615,8 +7584,7 @@ casematch(union node *pattern, char *val)
7615 setstackmark(&smark); 7584 setstackmark(&smark);
7616 argbackq = pattern->narg.backquote; 7585 argbackq = pattern->narg.backquote;
7617 STARTSTACKSTR(expdest); 7586 STARTSTACKSTR(expdest);
7618 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE, 7587 argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
7619 /* var_str_list: */ NULL);
7620 STACKSTRNUL(expdest); 7588 STACKSTRNUL(expdest);
7621 ifsfree(); 7589 ifsfree();
7622 result = patmatch(stackblock(), val); 7590 result = patmatch(stackblock(), val);