hush: optimization: do not glob words "[" and "[["
No binary (build failed)
—
(log yok)
| @@ -115,6 +115,11 @@ | |
| //config:# It's only needed to get "nice" menuconfig indenting. | |
| //config:if SHELL_HUSH || HUSH || SH_IS_HUSH || BASH_IS_HUSH | |
| //config: | |
| + | //config:config HUSH_NEED_FOR_SPEED |
| + | //config: bool "Faster, but larger code" |
| + | //config: default y |
| + | //config: depends on SHELL_HUSH |
| + | //config: |
| //config:config HUSH_BASH_COMPAT | |
| //config: bool "bash-compatible extensions" | |
| //config: default y | |
| @@ -3381,6 +3386,24 @@ static int o_get_last_ptr(o_string *o, int n) | |
| /* Helper */ | |
| static int glob_needed(const char *s) | |
| { | |
| + | # if ENABLE_HUSH_NEED_FOR_SPEED |
| + | char c = *s; |
| + | if (c == '[' /*|| c == '{'*/) { |
| + | /* Special-case words consisting entirely of [. |
| + | * Optimization to avoid glob() |
| + | * on "[ COND ]" and "[[ COND ]]": |
| + | * strace hush -c 'i=0; while [ $((++i)) != 50000 ]; do :; done' |
| + | * shouldn't be doing 50000 stat("["). |
| + | * (Can do it for "{" too, but it's not a common case). |
| + | */ |
| + | const char *p = s; |
| + | while (*++p == c) |
| + | continue; |
| + | if (*p == '\0') |
| + | return 0; |
| + | } |
| + | # endif |
| + | |
| while (*s) { | |
| if (*s == '\\') { | |
| if (!s[1]) | |
| @@ -3572,6 +3595,23 @@ static int perform_glob(o_string *o, int n) | |
| /* Helper */ | |
| static int glob_needed(const char *s) | |
| { | |
| + | # if ENABLE_HUSH_NEED_FOR_SPEED |
| + | char c = *s; |
| + | if (c == '[') { |
| + | /* Special-case words consisting entirely of [. |
| + | * Optimization to avoid glob() |
| + | * on "[ COND ]" and "[[ COND ]]": |
| + | * strace hush -c 'i=0; while [ $((++i)) != 50000 ]; do :; done' |
| + | * shouldn't be doing 50000 stat("["). |
| + | */ |
| + | const char *p = s; |
| + | while (*++p == c) |
| + | continue; |
| + | if (*p == '\0') |
| + | return 0; |
| + | } |
| + | # endif |
| + | |
| while (*s) { | |
| if (*s == '\\') { | |
| if (!s[1]) | |