summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko2018-07-31 10:36:29 +0200
committerDenys Vlasenko2018-07-31 10:36:29 +0200
commit54fdabda3b953087f669bfcba99b9ae3b0c09fec (patch)
tree04b891c27f69861cb263f39edb74f2ece63906b9 /shell/hush.c
parenta5db1d7354977fe295882ff557e8f5fb23741b13 (diff)
downloadbusybox-54fdabda3b953087f669bfcba99b9ae3b0c09fec.zip
busybox-54fdabda3b953087f669bfcba99b9ae3b0c09fec.tar.gz
hush: speed up ${var:+ARG} for literal ARGs
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@googlemail.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c58
1 files changed, 31 insertions, 27 deletions
diff --git a/shell/hush.c b/shell/hush.c
index d17f7f2..6852b5f 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);