diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-13 10:01:16 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-08-13 10:01:16 +0200 |
| commit | 187f24b4907e76fa15cd4f96ac090dd92772d21b (patch) | |
| tree | da5386277a23ff85cfd9eba28e2131db6aeaf6bb /shell | |
| parent | a5cf673c9cf53a3a4bcb127875d4bc544965862e (diff) | |
| download | busybox-w32-187f24b4907e76fa15cd4f96ac090dd92772d21b.tar.gz busybox-w32-187f24b4907e76fa15cd4f96ac090dd92772d21b.tar.bz2 busybox-w32-187f24b4907e76fa15cd4f96ac090dd92772d21b.zip | |
hush: ~5% faster parsing of typical shell scripts
0-9,A-Z,a-z are never special and just go into the current word.
function old new delta
parse_stream 2476 2565 +89
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/shell/hush.c b/shell/hush.c index 10ade0b9e..ecdb5eea9 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -2743,7 +2743,7 @@ static const char *setup_prompt_string(void) | |||
| 2743 | debug_printf("prompt_str '%s'\n", prompt_str); | 2743 | debug_printf("prompt_str '%s'\n", prompt_str); |
| 2744 | return prompt_str; | 2744 | return prompt_str; |
| 2745 | } | 2745 | } |
| 2746 | static int get_user_input(struct in_str *i) | 2746 | static int get_interactive_input(struct in_str *i) |
| 2747 | { | 2747 | { |
| 2748 | # if ENABLE_FEATURE_EDITING | 2748 | # if ENABLE_FEATURE_EDITING |
| 2749 | /* In EDITING case, this function reads next input line, | 2749 | /* In EDITING case, this function reads next input line, |
| @@ -2853,7 +2853,7 @@ static int fgetc_interactive(struct in_str *i) | |||
| 2853 | /* If it's interactive stdin, get new line. */ | 2853 | /* If it's interactive stdin, get new line. */ |
| 2854 | if (G_interactive_fd && i->file == G.HFILE_stdin) { | 2854 | if (G_interactive_fd && i->file == G.HFILE_stdin) { |
| 2855 | /* Returns first char (or EOF), the rest is in i->p[] */ | 2855 | /* Returns first char (or EOF), the rest is in i->p[] */ |
| 2856 | ch = get_user_input(i); | 2856 | ch = get_interactive_input(i); |
| 2857 | G.promptmode = 1; /* PS2 */ | 2857 | G.promptmode = 1; /* PS2 */ |
| 2858 | debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode); | 2858 | debug_printf_prompt("%s promptmode=%d\n", __func__, G.promptmode); |
| 2859 | } else { | 2859 | } else { |
| @@ -2880,14 +2880,7 @@ static int i_getch(struct in_str *i) | |||
| 2880 | ch = (unsigned char)*i->p; | 2880 | ch = (unsigned char)*i->p; |
| 2881 | if (ch != '\0') { | 2881 | if (ch != '\0') { |
| 2882 | i->p++; | 2882 | i->p++; |
| 2883 | i->last_char = ch; | 2883 | goto out1; |
| 2884 | #if ENABLE_HUSH_LINENO_VAR | ||
| 2885 | if (ch == '\n') { | ||
| 2886 | G.parse_lineno++; | ||
| 2887 | debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno); | ||
| 2888 | } | ||
| 2889 | #endif | ||
| 2890 | return ch; | ||
| 2891 | } | 2884 | } |
| 2892 | return EOF; | 2885 | return EOF; |
| 2893 | } | 2886 | } |
| @@ -2915,13 +2908,14 @@ static int i_getch(struct in_str *i) | |||
| 2915 | ch = fgetc_interactive(i); | 2908 | ch = fgetc_interactive(i); |
| 2916 | out: | 2909 | out: |
| 2917 | debug_printf("file_get: got '%c' %d\n", ch, ch); | 2910 | debug_printf("file_get: got '%c' %d\n", ch, ch); |
| 2918 | i->last_char = ch; | 2911 | out1: |
| 2919 | #if ENABLE_HUSH_LINENO_VAR | 2912 | #if ENABLE_HUSH_LINENO_VAR |
| 2920 | if (ch == '\n') { | 2913 | if (ch == '\n') { |
| 2921 | G.parse_lineno++; | 2914 | G.parse_lineno++; |
| 2922 | debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno); | 2915 | debug_printf_parse("G.parse_lineno++ = %u\n", G.parse_lineno); |
| 2923 | } | 2916 | } |
| 2924 | #endif | 2917 | #endif |
| 2918 | i->last_char = ch; | ||
| 2925 | return ch; | 2919 | return ch; |
| 2926 | } | 2920 | } |
| 2927 | 2921 | ||
| @@ -3077,7 +3071,7 @@ static void o_grow_by(o_string *o, int len) | |||
| 3077 | } | 3071 | } |
| 3078 | } | 3072 | } |
| 3079 | 3073 | ||
| 3080 | static void o_addchr(o_string *o, int ch) | 3074 | static ALWAYS_INLINE void INLINED_o_addchr(o_string *o, int ch) |
| 3081 | { | 3075 | { |
| 3082 | debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o); | 3076 | debug_printf("o_addchr: '%c' o->length=%d o=%p\n", ch, o->length, o); |
| 3083 | if (o->length < o->maxlen) { | 3077 | if (o->length < o->maxlen) { |
| @@ -3091,6 +3085,10 @@ static void o_addchr(o_string *o, int ch) | |||
| 3091 | o_grow_by(o, 1); | 3085 | o_grow_by(o, 1); |
| 3092 | goto add; | 3086 | goto add; |
| 3093 | } | 3087 | } |
| 3088 | static void o_addchr(o_string *o, int ch) | ||
| 3089 | { | ||
| 3090 | INLINED_o_addchr(o, ch); | ||
| 3091 | } | ||
| 3094 | 3092 | ||
| 3095 | #if 0 | 3093 | #if 0 |
| 3096 | /* Valid only if we know o_string is not empty */ | 3094 | /* Valid only if we know o_string is not empty */ |
| @@ -5623,6 +5621,14 @@ static struct pipe *parse_stream(char **pstring, | |||
| 5623 | ch = i_getch(input); | 5621 | ch = i_getch(input); |
| 5624 | debug_printf_parse(": ch:%c (%d) globprotect:%d\n", | 5622 | debug_printf_parse(": ch:%c (%d) globprotect:%d\n", |
| 5625 | ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_GLOBPROTECT_CHARS)); | 5623 | ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_GLOBPROTECT_CHARS)); |
| 5624 | # if ENABLE_HUSH_NEED_FOR_SPEED | ||
| 5625 | if (isalnum(ch)) { | ||
| 5626 | /* 0-9A-Za-z are never special and just go into the current word */ | ||
| 5627 | /* ~5% faster parsing of typical shell scripts */ | ||
| 5628 | INLINED_o_addchr(&ctx.word, ch); | ||
| 5629 | continue; | ||
| 5630 | } | ||
| 5631 | #endif | ||
| 5626 | if (ch == EOF) | 5632 | if (ch == EOF) |
| 5627 | break; | 5633 | break; |
| 5628 | 5634 | ||
| @@ -8223,7 +8229,7 @@ static void restore_redirects(struct squirrel *sq) | |||
| 8223 | * Redirect moves ->fd to e.g. 10, | 8229 | * Redirect moves ->fd to e.g. 10, |
| 8224 | * and it is not restored above (we do not restore script fds | 8230 | * and it is not restored above (we do not restore script fds |
| 8225 | * after redirects, we just use new, "moved" fds). | 8231 | * after redirects, we just use new, "moved" fds). |
| 8226 | * However for stdin, get_user_input() -> read_line_input(), | 8232 | * However for stdin, get_interactive_input() -> read_line_input(), |
| 8227 | * and read builtin, depend on fd == STDIN_FILENO. | 8233 | * and read builtin, depend on fd == STDIN_FILENO. |
| 8228 | */ | 8234 | */ |
| 8229 | debug_printf_redir("restoring %d to stdin\n", G.HFILE_stdin->fd); | 8235 | debug_printf_redir("restoring %d to stdin\n", G.HFILE_stdin->fd); |
