- val = dyn_val = xstrdup(val);
- loc = scan(dyn_val, exp_word, match_at_left);
- if (match_at_left) /* # or ## */
- val = loc;
- else if (loc) /* % or %% and match was found */
- *loc = '\0';
+ val = to_be_freed = xstrdup(val);
+ {
+ char *exp_exp_word = expand_pseudo_dquoted(exp_word);
+ if (exp_exp_word)
+ exp_word = exp_exp_word;
+ loc = scan(to_be_freed, exp_word, match_at_left);
+ //bb_error_msg("op:%c str:'%s' pat:'%s' res:'%s'",
+ // exp_op, to_be_freed, exp_word, loc);
+ free(exp_exp_word);
+ }
+ if (loc) { /* match was found */
+ if (match_at_left) /* # or ## */
+ val = loc;
+ else /* % or %% */
+ *loc = '\0';
+ }
+ }
+ } else if (!strchr("%#:-=+?"+3, exp_op)) {
+#if ENABLE_HUSH_BASH_COMPAT
+ /* exp_op is ':' and next char isn't a subst operator.
+ * Assuming it's ${var:[N][:M]} bashism.
+ * TODO: N, M can be expressions similar to $((EXPR)): 2+2, 2+var etc
+ */
+ char *end;
+ unsigned len = INT_MAX;
+ unsigned beg = 0;
+ end = --exp_word;
+ if (*exp_word != ':') /* not ${var::...} */
+ beg = bb_strtou(exp_word, &end, 0);
+ //bb_error_msg("beg:'%s'=%u end:'%s'", exp_word, beg, end);
+ if (*end == ':') {
+ if (end[1] != '\0') /* not ${var:NUM:} */
+ len = bb_strtou(end + 1, &end, 0);
+ else {
+ len = 0;
+ end++;
+ }
+ //bb_error_msg("len:%u end:'%s'", len, end);