diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-17 16:46:57 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-07-17 16:46:57 +0200 |
commit | e32b6503e75d5bcbf8ffff69cafb09523ff2b482 (patch) | |
tree | d0d68a95f68d55215b86f792e11e89b1e75b1ed1 /shell/hush.c | |
parent | 203fd7bc66b869e5022ad33d26065e69eaaaf66b (diff) | |
download | busybox-w32-e32b6503e75d5bcbf8ffff69cafb09523ff2b482.tar.gz busybox-w32-e32b6503e75d5bcbf8ffff69cafb09523ff2b482.tar.bz2 busybox-w32-e32b6503e75d5bcbf8ffff69cafb09523ff2b482.zip |
hush: support ${VAR:N:-M}
function old new delta
expand_one_var 1602 1615 +13
builtin_type 114 116 +2
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 48 |
1 files changed, 25 insertions, 23 deletions
diff --git a/shell/hush.c b/shell/hush.c index fd2a3d0f5..836f3b83c 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -5723,32 +5723,34 @@ static NOINLINE const char *expand_one_var(char **to_be_freed_pp, char *arg, cha | |||
5723 | if (errmsg) | 5723 | if (errmsg) |
5724 | goto arith_err; | 5724 | goto arith_err; |
5725 | debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len); | 5725 | debug_printf_varexp("len:'%s'=%lld\n", exp_word, (long long)len); |
5726 | if (len >= 0) { | 5726 | if (beg < 0) { |
5727 | if (beg < 0) { | 5727 | /* negative beg counts from the end */ |
5728 | /* negative beg counts from the end */ | 5728 | beg = (arith_t)strlen(val) + beg; |
5729 | beg = (arith_t)strlen(val) + beg; | 5729 | if (beg < 0) /* ${v: -999999} is "" */ |
5730 | if (beg < 0) /* ${v: -999999} is "" */ | 5730 | beg = len = 0; |
5731 | beg = len = 0; | 5731 | } |
5732 | } | 5732 | debug_printf_varexp("from val:'%s'\n", val); |
5733 | debug_printf_varexp("from val:'%s'\n", val); | 5733 | if (len < 0) { |
5734 | if (len == 0 || !val || beg >= strlen(val)) { | 5734 | /* in bash, len=-n means strlen()-n */ |
5735 | len = (arith_t)strlen(val) - beg + len; | ||
5736 | if (len < 0) /* bash compat */ | ||
5737 | die_if_script("%s: substring expression < 0", var); | ||
5738 | } | ||
5739 | if (len == 0 || !val || beg >= strlen(val)) { | ||
5735 | arith_err: | 5740 | arith_err: |
5736 | val = NULL; | ||
5737 | } else { | ||
5738 | /* Paranoia. What if user entered 9999999999999 | ||
5739 | * which fits in arith_t but not int? */ | ||
5740 | if (len >= INT_MAX) | ||
5741 | len = INT_MAX; | ||
5742 | val = to_be_freed = xstrndup(val + beg, len); | ||
5743 | } | ||
5744 | debug_printf_varexp("val:'%s'\n", val); | ||
5745 | } else | ||
5746 | //TODO: in bash, len=-n means strlen()-n | ||
5747 | #endif /* HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH */ | ||
5748 | { | ||
5749 | die_if_script("malformed ${%s:...}", var); | ||
5750 | val = NULL; | 5741 | val = NULL; |
5742 | } else { | ||
5743 | /* Paranoia. What if user entered 9999999999999 | ||
5744 | * which fits in arith_t but not int? */ | ||
5745 | if (len >= INT_MAX) | ||
5746 | len = INT_MAX; | ||
5747 | val = to_be_freed = xstrndup(val + beg, len); | ||
5751 | } | 5748 | } |
5749 | debug_printf_varexp("val:'%s'\n", val); | ||
5750 | #else /* not (HUSH_SUBSTR_EXPANSION && FEATURE_SH_MATH) */ | ||
5751 | die_if_script("malformed ${%s:...}", var); | ||
5752 | val = NULL; | ||
5753 | #endif | ||
5752 | } else { /* one of "-=+?" */ | 5754 | } else { /* one of "-=+?" */ |
5753 | /* Standard-mandated substitution ops: | 5755 | /* Standard-mandated substitution ops: |
5754 | * ${var?word} - indicate error if unset | 5756 | * ${var?word} - indicate error if unset |