[git commit] hush: speed up ${var:+ARG} for literal ARGs

Denys Vlasenko vda.linux at googlemail.com
Tue Jul 31 08:36:29 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=54fdabda3b953087f669bfcba99b9ae3b0c09fec
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
first_special_char_in_vararg                           -      52     +52
expand_one_var                                      2248    2296     +48
encode_then_expand_vararg                            357     336     -21
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 100/-21)            Total: 79 bytes

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/hush.c | 58 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 31 insertions(+), 27 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index d17f7f29e..6852b5f79 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5913,6 +5913,26 @@ static char *encode_then_expand_string(const char *str)
 	return exp_str;
 }
 
+static const char *first_special_char_in_vararg(const char *cp)
+{
+	for (;;) {
+		if (!*cp) return NULL; /* string has no special chars */
+		if (*cp == '$') return cp;
+		if (*cp == '\\') return cp;
+		if (*cp == '\'') return cp;
+		if (*cp == '"') return cp;
+#if ENABLE_HUSH_TICK
+		if (*cp == '`') return cp;
+#endif
+		/* dquoted "${x:+ARG}" should not glob, therefore
+		 * '*' et al require some non-literal processing: */
+		if (*cp == '*') return cp;
+		if (*cp == '?') return cp;
+		if (*cp == '[') return cp;
+		cp++;
+	}
+}
+
 /* Expanding ARG in ${var#ARG}, ${var%ARG}, or ${var/ARG/ARG}.
  * These can contain single- and double-quoted strings,
  * and treated as if the ARG string is initially unquoted. IOW:
@@ -5932,19 +5952,10 @@ static char *encode_then_expand_vararg(const char *str, int handle_squotes, int
 	char *exp_str;
 	struct in_str input;
 	o_string dest = NULL_O_STRING;
-	const char *cp;
 
-	cp = str;
-	for (;;) {
-		if (!*cp) return NULL; /* string has no special chars */
-		if (*cp == '$') break;
-		if (*cp == '\\') break;
-		if (*cp == '\'') break;
-		if (*cp == '"') break;
-#if ENABLE_HUSH_TICK
-		if (*cp == '`') break;
-#endif
-		cp++;
+	if (!first_special_char_in_vararg(str)) {
+		/* string has no special chars */
+		return NULL;
 	}
 
 	setup_string_in_str(&input, str);
@@ -6025,26 +6036,19 @@ static char *encode_then_expand_vararg(const char *str, int handle_squotes, int
 /* Expanding ARG in ${var+ARG}, ${var-ARG}
  */
 static int encode_then_append_var_plusminus(o_string *output, int n,
-		const char *str, int dquoted)
+		char *str, int dquoted)
 {
 	struct in_str input;
 	o_string dest = NULL_O_STRING;
 
-#if 0 //todo?
-	const char *cp;
-	cp = str;
-	for (;;) {
-		if (!*cp) return NULL; /* string has no special chars */
-		if (*cp == '$') break;
-		if (*cp == '\\') break;
-		if (*cp == '\'') break;
-		if (*cp == '"') break;
-#if ENABLE_HUSH_TICK
-		if (*cp == '`') break;
-#endif
-		cp++;
+	if (!first_special_char_in_vararg(str)
+	 && '\0' == str[strcspn(str, G.ifs)]
+	) {
+		/* string has no special chars
+		 * && string has no $IFS chars
+		 */
+		return expand_vars_to_list(output, n, str);
 	}
-#endif
 
 	setup_string_in_str(&input, str);
 


More information about the busybox-cvs mailing list