diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-08-05 17:19:27 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-08-05 17:19:27 +0200 |
commit | b0fbe4b5409b136e0c80788cf183ec24237e9c97 (patch) | |
tree | d5ef2215b48c894721801f0fe7184a347f91d669 | |
parent | e74d79866c6d125527e3ba69245a087a28fd19ce (diff) | |
download | busybox-w32-b0fbe4b5409b136e0c80788cf183ec24237e9c97.tar.gz busybox-w32-b0fbe4b5409b136e0c80788cf183ec24237e9c97.tar.bz2 busybox-w32-b0fbe4b5409b136e0c80788cf183ec24237e9c97.zip |
ash: add a testcase for bug 2281 (currently fails). Small code cleanups.
function old new delta
changepath 195 192 -3
subevalvar 1204 1200 -4
readtoken1 3247 3240 -7
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/3 up/down: 0/-14) Total: -14 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/ash.c | 83 | ||||
-rwxr-xr-x[-rw-r--r--] | shell/ash_test/ash-redir/redir9.tests | 0 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_bash3.right | 40 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_bash3.tests | 47 | ||||
-rw-r--r-- | shell/ash_test/ash-vars/var_bash4.right | 2 | ||||
-rwxr-xr-x | shell/ash_test/ash-vars/var_bash4.tests | 3 |
6 files changed, 104 insertions, 71 deletions
diff --git a/shell/ash.c b/shell/ash.c index d8becc37a..16783f2e8 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6296,13 +6296,14 @@ parse_sub_pattern(char *arg, int inquotes) | |||
6296 | #endif /* ENABLE_ASH_BASH_COMPAT */ | 6296 | #endif /* ENABLE_ASH_BASH_COMPAT */ |
6297 | 6297 | ||
6298 | static const char * | 6298 | static const char * |
6299 | subevalvar(char *p, char *str, int strloc, int subtype, | 6299 | subevalvar(char *p, char *varname, int strloc, int subtype, |
6300 | int startloc, int varflags, int quotes, struct strlist *var_str_list) | 6300 | int startloc, int varflags, int quotes, struct strlist *var_str_list) |
6301 | { | 6301 | { |
6302 | struct nodelist *saveargbackq = argbackq; | 6302 | struct nodelist *saveargbackq = argbackq; |
6303 | char *startp; | 6303 | char *startp; |
6304 | char *loc; | 6304 | char *loc; |
6305 | char *rmesc, *rmescend; | 6305 | char *rmesc, *rmescend; |
6306 | char *str; | ||
6306 | IF_ASH_BASH_COMPAT(const char *repl = NULL;) | 6307 | IF_ASH_BASH_COMPAT(const char *repl = NULL;) |
6307 | IF_ASH_BASH_COMPAT(int pos, len, orig_len;) | 6308 | IF_ASH_BASH_COMPAT(int pos, len, orig_len;) |
6308 | int saveherefd = herefd; | 6309 | int saveherefd = herefd; |
@@ -6310,6 +6311,9 @@ subevalvar(char *p, char *str, int strloc, int subtype, | |||
6310 | int zero; | 6311 | int zero; |
6311 | char *(*scan)(char*, char*, char*, char*, int, int); | 6312 | char *(*scan)(char*, char*, char*, char*, int, int); |
6312 | 6313 | ||
6314 | //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d", | ||
6315 | // p, varname, strloc, subtype, startloc, varflags, quotes); | ||
6316 | |||
6313 | herefd = -1; | 6317 | herefd = -1; |
6314 | argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0, | 6318 | argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0, |
6315 | var_str_list); | 6319 | var_str_list); |
@@ -6320,11 +6324,15 @@ subevalvar(char *p, char *str, int strloc, int subtype, | |||
6320 | 6324 | ||
6321 | switch (subtype) { | 6325 | switch (subtype) { |
6322 | case VSASSIGN: | 6326 | case VSASSIGN: |
6323 | setvar(str, startp, 0); | 6327 | setvar(varname, startp, 0); |
6324 | amount = startp - expdest; | 6328 | amount = startp - expdest; |
6325 | STADJUST(amount, expdest); | 6329 | STADJUST(amount, expdest); |
6326 | return startp; | 6330 | return startp; |
6327 | 6331 | ||
6332 | case VSQUESTION: | ||
6333 | varunset(p, varname, startp, varflags); | ||
6334 | /* NOTREACHED */ | ||
6335 | |||
6328 | #if ENABLE_ASH_BASH_COMPAT | 6336 | #if ENABLE_ASH_BASH_COMPAT |
6329 | case VSSUBSTR: | 6337 | case VSSUBSTR: |
6330 | loc = str = stackblock() + strloc; | 6338 | loc = str = stackblock() + strloc; |
@@ -6385,11 +6393,8 @@ subevalvar(char *p, char *str, int strloc, int subtype, | |||
6385 | STADJUST(amount, expdest); | 6393 | STADJUST(amount, expdest); |
6386 | return loc; | 6394 | return loc; |
6387 | #endif | 6395 | #endif |
6388 | |||
6389 | case VSQUESTION: | ||
6390 | varunset(p, str, startp, varflags); | ||
6391 | /* NOTREACHED */ | ||
6392 | } | 6396 | } |
6397 | |||
6393 | resetloc = expdest - (char *)stackblock(); | 6398 | resetloc = expdest - (char *)stackblock(); |
6394 | 6399 | ||
6395 | /* We'll comeback here if we grow the stack while handling | 6400 | /* We'll comeback here if we grow the stack while handling |
@@ -6423,13 +6428,14 @@ subevalvar(char *p, char *str, int strloc, int subtype, | |||
6423 | 6428 | ||
6424 | if (!repl) { | 6429 | if (!repl) { |
6425 | repl = parse_sub_pattern(str, varflags & VSQUOTE); | 6430 | repl = parse_sub_pattern(str, varflags & VSQUOTE); |
6431 | //bb_error_msg("repl:'%s'", repl); | ||
6426 | if (!repl) | 6432 | if (!repl) |
6427 | repl = nullstr; | 6433 | repl = nullstr; |
6428 | } | 6434 | } |
6429 | 6435 | ||
6430 | /* If there's no pattern to match, return the expansion unmolested */ | 6436 | /* If there's no pattern to match, return the expansion unmolested */ |
6431 | if (str[0] == '\0') | 6437 | if (str[0] == '\0') |
6432 | return 0; | 6438 | return NULL; |
6433 | 6439 | ||
6434 | len = 0; | 6440 | len = 0; |
6435 | idx = startp; | 6441 | idx = startp; |
@@ -6437,6 +6443,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, | |||
6437 | while (idx < end) { | 6443 | while (idx < end) { |
6438 | try_to_match: | 6444 | try_to_match: |
6439 | loc = scanright(idx, rmesc, rmescend, str, quotes, 1); | 6445 | loc = scanright(idx, rmesc, rmescend, str, quotes, 1); |
6446 | //bb_error_msg("scanright('%s'):'%s'", str, loc); | ||
6440 | if (!loc) { | 6447 | if (!loc) { |
6441 | /* No match, advance */ | 6448 | /* No match, advance */ |
6442 | char *restart_detect = stackblock(); | 6449 | char *restart_detect = stackblock(); |
@@ -6475,6 +6482,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, | |||
6475 | idx = loc; | 6482 | idx = loc; |
6476 | } | 6483 | } |
6477 | 6484 | ||
6485 | //bb_error_msg("repl:'%s'", repl); | ||
6478 | for (loc = (char*)repl; *loc; loc++) { | 6486 | for (loc = (char*)repl; *loc; loc++) { |
6479 | char *restart_detect = stackblock(); | 6487 | char *restart_detect = stackblock(); |
6480 | if (quotes && *loc == '\\') { | 6488 | if (quotes && *loc == '\\') { |
@@ -6510,6 +6518,7 @@ subevalvar(char *p, char *str, int strloc, int subtype, | |||
6510 | STPUTC('\0', expdest); | 6518 | STPUTC('\0', expdest); |
6511 | startp = (char *)stackblock() + startloc; | 6519 | startp = (char *)stackblock() + startloc; |
6512 | memmove(startp, (char *)stackblock() + workloc, len + 1); | 6520 | memmove(startp, (char *)stackblock() + workloc, len + 1); |
6521 | //bb_error_msg("startp:'%s'", startp); | ||
6513 | amount = expdest - (startp + len); | 6522 | amount = expdest - (startp + len); |
6514 | STADJUST(-amount, expdest); | 6523 | STADJUST(-amount, expdest); |
6515 | return startp; | 6524 | return startp; |
@@ -6810,7 +6819,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list) | |||
6810 | */ | 6819 | */ |
6811 | STPUTC('\0', expdest); | 6820 | STPUTC('\0', expdest); |
6812 | patloc = expdest - (char *)stackblock(); | 6821 | patloc = expdest - (char *)stackblock(); |
6813 | if (NULL == subevalvar(p, /* str: */ NULL, patloc, subtype, | 6822 | if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype, |
6814 | startloc, varflags, | 6823 | startloc, varflags, |
6815 | //TODO: | EXP_REDIR too? All other such places do it too | 6824 | //TODO: | EXP_REDIR too? All other such places do it too |
6816 | /* quotes: */ flags & (EXP_FULL | EXP_CASE), | 6825 | /* quotes: */ flags & (EXP_FULL | EXP_CASE), |
@@ -11114,8 +11123,11 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11114 | USTPUTC('\\', out); | 11123 | USTPUTC('\\', out); |
11115 | } | 11124 | } |
11116 | #endif | 11125 | #endif |
11117 | if (dblquote && c != '\\' | 11126 | /* Backslash is retained if we are in "str" and next char isn't special */ |
11118 | && c != '`' && c != '$' | 11127 | if (dblquote |
11128 | && c != '\\' | ||
11129 | && c != '`' | ||
11130 | && c != '$' | ||
11119 | && (c != '"' || eofmark != NULL) | 11131 | && (c != '"' || eofmark != NULL) |
11120 | ) { | 11132 | ) { |
11121 | USTPUTC(CTLESC, out); | 11133 | USTPUTC(CTLESC, out); |
@@ -11187,7 +11199,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs) | |||
11187 | } else { | 11199 | } else { |
11188 | /* | 11200 | /* |
11189 | * unbalanced parens | 11201 | * unbalanced parens |
11190 | * (don't 2nd guess - no error) | 11202 | * (don't 2nd guess - no error) |
11191 | */ | 11203 | */ |
11192 | pungetc(); | 11204 | pungetc(); |
11193 | USTPUTC(')', out); | 11205 | USTPUTC(')', out); |
@@ -11380,8 +11392,6 @@ parsesub: { | |||
11380 | unsigned char subtype; | 11392 | unsigned char subtype; |
11381 | int typeloc; | 11393 | int typeloc; |
11382 | int flags; | 11394 | int flags; |
11383 | char *p; | ||
11384 | static const char types[] ALIGN1 = "}-+?="; | ||
11385 | 11395 | ||
11386 | c = pgetc(); | 11396 | c = pgetc(); |
11387 | if (c > 255 /* PEOA or PEOF */ | 11397 | if (c > 255 /* PEOA or PEOF */ |
@@ -11394,7 +11404,8 @@ parsesub: { | |||
11394 | #endif | 11404 | #endif |
11395 | USTPUTC('$', out); | 11405 | USTPUTC('$', out); |
11396 | pungetc(); | 11406 | pungetc(); |
11397 | } else if (c == '(') { /* $(command) or $((arith)) */ | 11407 | } else if (c == '(') { |
11408 | /* $(command) or $((arith)) */ | ||
11398 | if (pgetc() == '(') { | 11409 | if (pgetc() == '(') { |
11399 | #if ENABLE_SH_MATH_SUPPORT | 11410 | #if ENABLE_SH_MATH_SUPPORT |
11400 | PARSEARITH(); | 11411 | PARSEARITH(); |
@@ -11406,6 +11417,7 @@ parsesub: { | |||
11406 | PARSEBACKQNEW(); | 11417 | PARSEBACKQNEW(); |
11407 | } | 11418 | } |
11408 | } else { | 11419 | } else { |
11420 | /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */ | ||
11409 | USTPUTC(CTLVAR, out); | 11421 | USTPUTC(CTLVAR, out); |
11410 | typeloc = out - (char *)stackblock(); | 11422 | typeloc = out - (char *)stackblock(); |
11411 | USTPUTC(VSNORMAL, out); | 11423 | USTPUTC(VSNORMAL, out); |
@@ -11415,76 +11427,85 @@ parsesub: { | |||
11415 | if (c == '#') { | 11427 | if (c == '#') { |
11416 | c = pgetc(); | 11428 | c = pgetc(); |
11417 | if (c == '}') | 11429 | if (c == '}') |
11418 | c = '#'; | 11430 | c = '#'; /* ${#} - same as $# */ |
11419 | else | 11431 | else |
11420 | subtype = VSLENGTH; | 11432 | subtype = VSLENGTH; /* ${#VAR} */ |
11421 | } else | 11433 | } else { |
11422 | subtype = 0; | 11434 | subtype = 0; |
11435 | } | ||
11423 | } | 11436 | } |
11424 | if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) { | 11437 | if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) { |
11438 | /* $[{[#]]NAME[}] */ | ||
11425 | do { | 11439 | do { |
11426 | STPUTC(c, out); | 11440 | STPUTC(c, out); |
11427 | c = pgetc(); | 11441 | c = pgetc(); |
11428 | } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c)); | 11442 | } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c)); |
11429 | } else if (isdigit(c)) { | 11443 | } else if (isdigit(c)) { |
11444 | /* $[{[#]]NUM[}] */ | ||
11430 | do { | 11445 | do { |
11431 | STPUTC(c, out); | 11446 | STPUTC(c, out); |
11432 | c = pgetc(); | 11447 | c = pgetc(); |
11433 | } while (isdigit(c)); | 11448 | } while (isdigit(c)); |
11434 | } else if (is_special(c)) { | 11449 | } else if (is_special(c)) { |
11450 | /* $[{[#]]<specialchar>[}] */ | ||
11435 | USTPUTC(c, out); | 11451 | USTPUTC(c, out); |
11436 | c = pgetc(); | 11452 | c = pgetc(); |
11437 | } else { | 11453 | } else { |
11438 | badsub: | 11454 | badsub: |
11439 | raise_error_syntax("bad substitution"); | 11455 | raise_error_syntax("bad substitution"); |
11440 | } | 11456 | } |
11441 | if (c != '}' && subtype == VSLENGTH) | 11457 | if (c != '}' && subtype == VSLENGTH) { |
11458 | /* ${#VAR didn't end with } */ | ||
11442 | goto badsub; | 11459 | goto badsub; |
11460 | } | ||
11443 | 11461 | ||
11444 | STPUTC('=', out); | 11462 | STPUTC('=', out); |
11445 | flags = 0; | 11463 | flags = 0; |
11446 | if (subtype == 0) { | 11464 | if (subtype == 0) { |
11465 | /* ${VAR...} but not $VAR or ${#VAR} */ | ||
11466 | /* c == first char after VAR */ | ||
11447 | switch (c) { | 11467 | switch (c) { |
11448 | case ':': | 11468 | case ':': |
11449 | c = pgetc(); | 11469 | c = pgetc(); |
11450 | #if ENABLE_ASH_BASH_COMPAT | 11470 | #if ENABLE_ASH_BASH_COMPAT |
11451 | if (c == ':' || c == '$' || isdigit(c)) { | 11471 | if (c == ':' || c == '$' || isdigit(c)) { |
11452 | pungetc(); | ||
11453 | subtype = VSSUBSTR; | 11472 | subtype = VSSUBSTR; |
11454 | break; | 11473 | pungetc(); |
11474 | break; /* "goto do_pungetc" is bigger (!) */ | ||
11455 | } | 11475 | } |
11456 | #endif | 11476 | #endif |
11457 | flags = VSNUL; | 11477 | flags = VSNUL; |
11458 | /*FALLTHROUGH*/ | 11478 | /*FALLTHROUGH*/ |
11459 | default: | 11479 | default: { |
11460 | p = strchr(types, c); | 11480 | static const char types[] ALIGN1 = "}-+?="; |
11481 | const char *p = strchr(types, c); | ||
11461 | if (p == NULL) | 11482 | if (p == NULL) |
11462 | goto badsub; | 11483 | goto badsub; |
11463 | subtype = p - types + VSNORMAL; | 11484 | subtype = p - types + VSNORMAL; |
11464 | break; | 11485 | break; |
11486 | } | ||
11465 | case '%': | 11487 | case '%': |
11466 | case '#': { | 11488 | case '#': { |
11467 | int cc = c; | 11489 | int cc = c; |
11468 | subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT; | 11490 | subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT); |
11469 | c = pgetc(); | 11491 | c = pgetc(); |
11470 | if (c == cc) | 11492 | if (c != cc) |
11471 | subtype++; | 11493 | goto do_pungetc; |
11472 | else | 11494 | subtype++; |
11473 | pungetc(); | ||
11474 | break; | 11495 | break; |
11475 | } | 11496 | } |
11476 | #if ENABLE_ASH_BASH_COMPAT | 11497 | #if ENABLE_ASH_BASH_COMPAT |
11477 | case '/': | 11498 | case '/': |
11478 | subtype = VSREPLACE; | 11499 | subtype = VSREPLACE; |
11479 | c = pgetc(); | 11500 | c = pgetc(); |
11480 | if (c == '/') | 11501 | if (c != '/') |
11481 | subtype++; /* VSREPLACEALL */ | 11502 | goto do_pungetc; |
11482 | else | 11503 | subtype++; /* VSREPLACEALL */ |
11483 | pungetc(); | ||
11484 | break; | 11504 | break; |
11485 | #endif | 11505 | #endif |
11486 | } | 11506 | } |
11487 | } else { | 11507 | } else { |
11508 | do_pungetc: | ||
11488 | pungetc(); | 11509 | pungetc(); |
11489 | } | 11510 | } |
11490 | if (dblquote || arinest) | 11511 | if (dblquote || arinest) |
diff --git a/shell/ash_test/ash-redir/redir9.tests b/shell/ash_test/ash-redir/redir9.tests index 8befa611c..8befa611c 100644..100755 --- a/shell/ash_test/ash-redir/redir9.tests +++ b/shell/ash_test/ash-redir/redir9.tests | |||
diff --git a/shell/ash_test/ash-vars/var_bash3.right b/shell/ash_test/ash-vars/var_bash3.right index f7f14791e..a97c850ea 100644 --- a/shell/ash_test/ash-vars/var_bash3.right +++ b/shell/ash_test/ash-vars/var_bash3.right | |||
@@ -1,20 +1,20 @@ | |||
1 | a041#c | 1 | 1 a041#c |
2 | a041#c | 2 | 2 a041#c |
3 | a\041#c | 3 | 3 a\041#c |
4 | a\041#c | 4 | 4 a\041#c |
5 | a\041#c | 5 | 5 a\041#c |
6 | a\041#c | 6 | 6 a\041#c |
7 | a\041#c | 7 | 7 a\041#c |
8 | a\041#c | 8 | 8 a\041#c |
9 | a\041#c | 9 | 9 a\041#c |
10 | a\c | 10 | 10 a\c |
11 | a\c | 11 | 11 a\c |
12 | a\c | 12 | 12 a\c |
13 | a\\c | 13 | 13 a\\c |
14 | a\\c | 14 | 14 a\\c |
15 | a\\c | 15 | 15 a\\c |
16 | a\tc | 16 | 16 a\tc |
17 | a\tc | 17 | 17 a\tc |
18 | a\tc | 18 | 18 a\tc |
19 | atc | 19 | 19 atc |
20 | a\tc | 20 | 20 a\tc |
diff --git a/shell/ash_test/ash-vars/var_bash3.tests b/shell/ash_test/ash-vars/var_bash3.tests index b9050279e..eca3318e2 100755 --- a/shell/ash_test/ash-vars/var_bash3.tests +++ b/shell/ash_test/ash-vars/var_bash3.tests | |||
@@ -1,41 +1,48 @@ | |||
1 | a='abc' | 1 | a='abc' |
2 | r=${a//b/\041#} | 2 | r=${a//b/\041#} |
3 | echo $r | 3 | echo 1 $r |
4 | echo ${a//b/\041#} | 4 | echo 2 ${a//b/\041#} |
5 | echo "${a//b/\041#}" | 5 | echo 3 "${a//b/\041#}" |
6 | # --- var_bash3.xx | ||
7 | # +++ var_bash3.right | ||
8 | # -1 a\041#c | ||
9 | # +1 a041#c | ||
10 | # 2 a041#c | ||
11 | # -3 a041#c | ||
12 | # +3 a\041#c | ||
6 | 13 | ||
7 | a='abc' | 14 | a='abc' |
8 | r=${a//b/\\041#} | 15 | r=${a//b/\\041#} |
9 | echo $r | 16 | echo 4 $r |
10 | echo ${a//b/\\041#} | 17 | echo 5 ${a//b/\\041#} |
11 | echo "${a//b/\\041#}" | 18 | echo 6 "${a//b/\\041#}" |
12 | 19 | ||
13 | a='abc' | 20 | a='abc' |
14 | b='\041#' | 21 | b='\041#' |
15 | r=${a//b/$b} | 22 | r=${a//b/$b} |
16 | echo $r | 23 | echo 7 $r |
17 | echo ${a//b/$b} | 24 | echo 8 ${a//b/$b} |
18 | echo "${a//b/$b}" | 25 | echo 9 "${a//b/$b}" |
19 | 26 | ||
20 | a='abc' | 27 | a='abc' |
21 | b='\' | 28 | b='\' |
22 | r="${a//b/$b}" | 29 | r="${a//b/$b}" |
23 | echo $r | 30 | echo 10 $r |
24 | echo ${a//b/$b} | 31 | echo 11 ${a//b/$b} |
25 | echo "${a//b/$b}" | 32 | echo 12 "${a//b/$b}" |
26 | 33 | ||
27 | a='abc' | 34 | a='abc' |
28 | b='\\' | 35 | b='\\' |
29 | r="${a//b/$b}" | 36 | r="${a//b/$b}" |
30 | echo $r | 37 | echo 13 $r |
31 | echo ${a//b/$b} | 38 | echo 14 ${a//b/$b} |
32 | echo "${a//b/$b}" | 39 | echo 15 "${a//b/$b}" |
33 | 40 | ||
34 | a='abc' | 41 | a='abc' |
35 | b='\t' | 42 | b='\t' |
36 | r="${a//b/$b}" | 43 | r="${a//b/$b}" |
37 | echo $r | 44 | echo 16 $r |
38 | echo ${a//b/$b} | 45 | echo 17 ${a//b/$b} |
39 | echo "${a//b/$b}" | 46 | echo 18 "${a//b/$b}" |
40 | echo ${a//b/\t} | 47 | echo 19 ${a//b/\t} |
41 | echo "${a//b/\t}" | 48 | echo 20 "${a//b/\t}" |
diff --git a/shell/ash_test/ash-vars/var_bash4.right b/shell/ash_test/ash-vars/var_bash4.right new file mode 100644 index 000000000..33a511238 --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash4.right | |||
@@ -0,0 +1,2 @@ | |||
1 | a*b-backslashstar- | ||
2 | Done: 0 | ||
diff --git a/shell/ash_test/ash-vars/var_bash4.tests b/shell/ash_test/ash-vars/var_bash4.tests new file mode 100755 index 000000000..304b3d91c --- /dev/null +++ b/shell/ash_test/ash-vars/var_bash4.tests | |||
@@ -0,0 +1,3 @@ | |||
1 | FOO='a*b\*c' | ||
2 | echo "${FOO//\\*/-backslashstar-}" | ||
3 | echo Done: $? | ||