diff options
author | Denys Vlasenko | 2021-10-09 03:52:04 +0200 |
---|---|---|
committer | Denys Vlasenko | 2021-10-09 03:52:04 +0200 |
commit | 49bcf9f40cff1320a761d674cf89a0c0ab97ef49 (patch) | |
tree | c687441c2bf142649e8010b44e3192aadae4e47a /shell | |
parent | 5aaeb550b76f063ffddef8587d9d91f7fddc4406 (diff) | |
download | busybox-49bcf9f40cff1320a761d674cf89a0c0ab97ef49.zip busybox-49bcf9f40cff1320a761d674cf89a0c0ab97ef49.tar.gz |
hush: speed up ${x//\*/|} too
function old new delta
expand_one_var 2502 2544 +42
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
-rw-r--r-- | shell/hush.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/shell/hush.c b/shell/hush.c index 6d47233..87fc2f4 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -6472,16 +6472,21 @@ 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) { - int sz = strcspn(pattern, "*?[\\"); - if (pattern[sz] == '\0') { + int first_escaped = (pattern[0] == '\\' && pattern[1]); + /* "first_escaped" trick allows to treat e.g. "\*no_glob_chars" + * as literal too (as it is semi-common, and easy to accomodate + * by just using str + 1). + */ + int sz = strcspn(pattern + first_escaped * 2, "*?[\\"); + if ((pattern + first_escaped * 2)[sz] == '\0') { /* 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//:/|}" */ - *size = sz; - return strstr(val, pattern); + *size = sz + first_escaped; + return strstr(val, pattern + first_escaped); } while (1) { |