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>
This commit is contained in:
		
							
								
								
									
										13
									
								
								shell/hush.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								shell/hush.c
									
									
									
									
									
								
							| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user