hush: optimize ${var/pattern/repl} for trivial patterns
No binary (build failed)
—
(log yok)
| @@ -6466,6 +6466,19 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p) | |
| /* ${var/[/]pattern[/repl]} helpers */ | |
| static char *strstr_pattern(char *val, const char *pattern, int *size) | |
| { | |
| + | if (!strpbrk(pattern, "*?[\\")) { |
| + | /* Optimization for trivial patterns. |
| + | * Testcase for very slow replace (performs about 22k replaces): |
| + | * x=:::::::::::::::::::::: |
| + | * x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;x=$x$x;echo ${#x} |
| + | * echo "${x//:/|}" |
| + | */ |
| + | char *found = strstr(val, pattern); |
| + | if (found) |
| + | *size = strlen(pattern); |
| + | return found; |
| + | } |
| + | |
| while (1) { | |
| char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF); | |
| debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end); | |
| @@ -64,11 +64,10 @@ char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags | |
| } | |
| while (loc != end) { | |
| - | char c; |
| int r; | |
| - | c = *loc; |
| if (flags & SCAN_MATCH_LEFT_HALF) { | |
| + | char c = *loc; |
| *loc = '\0'; | |
| r = fnmatch(pattern, string, 0); | |
| //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); | |