aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-08-13 10:01:16 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-08-13 10:01:16 +0200
commit187f24b4907e76fa15cd4f96ac090dd92772d21b (patch)
treeda5386277a23ff85cfd9eba28e2131db6aeaf6bb /shell
parenta5cf673c9cf53a3a4bcb127875d4bc544965862e (diff)
downloadbusybox-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.c32
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}
2746static int get_user_input(struct in_str *i) 2746static 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
3080static void o_addchr(o_string *o, int ch) 3074static 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}
3088static 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);