aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2021-07-27 17:53:55 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2021-07-27 17:53:55 +0200
commit49cc3cac30c504abdbd2c075928f5711da4066e8 (patch)
tree83760d4340bd8a39225f76650d34372137de9ed7
parentc450437a4e631378cd6a2dc06a5923ce811a950d (diff)
downloadbusybox-w32-49cc3cac30c504abdbd2c075928f5711da4066e8.tar.gz
busybox-w32-49cc3cac30c504abdbd2c075928f5711da4066e8.tar.bz2
busybox-w32-49cc3cac30c504abdbd2c075928f5711da4066e8.zip
hush: optimize ${var/pattern/repl} for trivial patterns
function old new delta expand_one_var 2353 2507 +154 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/hush.c13
-rw-r--r--shell/match.c3
2 files changed, 14 insertions, 2 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 6b910569f..179155f66 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -6466,6 +6466,19 @@ static arith_t expand_and_evaluate_arith(const char *arg, const char **errmsg_p)
6466/* ${var/[/]pattern[/repl]} helpers */ 6466/* ${var/[/]pattern[/repl]} helpers */
6467static char *strstr_pattern(char *val, const char *pattern, int *size) 6467static char *strstr_pattern(char *val, const char *pattern, int *size)
6468{ 6468{
6469 if (!strpbrk(pattern, "*?[\\")) {
6470 /* Optimization for trivial patterns.
6471 * Testcase for very slow replace (performs about 22k replaces):
6472 * x=::::::::::::::::::::::
6473 * 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}
6474 * echo "${x//:/|}"
6475 */
6476 char *found = strstr(val, pattern);
6477 if (found)
6478 *size = strlen(pattern);
6479 return found;
6480 }
6481
6469 while (1) { 6482 while (1) {
6470 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF); 6483 char *end = scan_and_match(val, pattern, SCAN_MOVE_FROM_RIGHT + SCAN_MATCH_LEFT_HALF);
6471 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end); 6484 debug_printf_varexp("val:'%s' pattern:'%s' end:'%s'\n", val, pattern, end);
diff --git a/shell/match.c b/shell/match.c
index ee8abb2db..90f77546d 100644
--- a/shell/match.c
+++ b/shell/match.c
@@ -64,11 +64,10 @@ char* FAST_FUNC scan_and_match(char *string, const char *pattern, unsigned flags
64 } 64 }
65 65
66 while (loc != end) { 66 while (loc != end) {
67 char c;
68 int r; 67 int r;
69 68
70 c = *loc;
71 if (flags & SCAN_MATCH_LEFT_HALF) { 69 if (flags & SCAN_MATCH_LEFT_HALF) {
70 char c = *loc;
72 *loc = '\0'; 71 *loc = '\0';
73 r = fnmatch(pattern, string, 0); 72 r = fnmatch(pattern, string, 0);
74 //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r); 73 //bb_error_msg("fnmatch('%s','%s',0):%d", pattern, string, r);