From 54fdabda3b953087f669bfcba99b9ae3b0c09fec Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 31 Jul 2018 10:36:29 +0200 Subject: [PATCH] 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 --- 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);