diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-23 00:32:25 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-23 00:32:25 +0000 |
commit | 1a7358612ff2dfdfc9fa461faa946c577666787f (patch) | |
tree | 3edf610e1f0bab6f33e90716fc1550f0c9060991 /shell/hush.c | |
parent | 94dace30160131fc3f45b3f486463c49cda05204 (diff) | |
download | busybox-w32-1a7358612ff2dfdfc9fa461faa946c577666787f.tar.gz busybox-w32-1a7358612ff2dfdfc9fa461faa946c577666787f.tar.bz2 busybox-w32-1a7358612ff2dfdfc9fa461faa946c577666787f.zip |
hush: fix a bit different instance of "No EOL" bug,
add testsuite for that. Expand another testsuite.
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/shell/hush.c b/shell/hush.c index 61c03f703..aab6ff3a3 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -2836,14 +2836,13 @@ static struct pipe *new_pipe(void) | |||
2836 | 2836 | ||
2837 | static void initialize_context(struct p_context *ctx) | 2837 | static void initialize_context(struct p_context *ctx) |
2838 | { | 2838 | { |
2839 | ctx->pipe = NULL; | ||
2840 | ctx->pending_redirect = NULL; | ||
2841 | ctx->child = NULL; | 2839 | ctx->child = NULL; |
2842 | ctx->list_head = new_pipe(); | 2840 | ctx->pipe = ctx->list_head = new_pipe(); |
2843 | ctx->pipe = ctx->list_head; | 2841 | ctx->pending_redirect = NULL; |
2844 | ctx->res_w = RES_NONE; | 2842 | ctx->res_w = RES_NONE; |
2845 | ctx->stack = NULL; | 2843 | //only ctx->parse_type is not touched... is this intentional? |
2846 | ctx->old_flag = 0; | 2844 | ctx->old_flag = 0; |
2845 | ctx->stack = NULL; | ||
2847 | done_command(ctx); /* creates the memory for working child */ | 2846 | done_command(ctx); /* creates the memory for working child */ |
2848 | } | 2847 | } |
2849 | 2848 | ||
@@ -2886,44 +2885,44 @@ static int reserved_word(o_string *dest, struct p_context *ctx) | |||
2886 | const struct reserved_combo *r; | 2885 | const struct reserved_combo *r; |
2887 | 2886 | ||
2888 | for (r = reserved_list; r < reserved_list + NRES; r++) { | 2887 | for (r = reserved_list; r < reserved_list + NRES; r++) { |
2889 | if (strcmp(dest->data, r->literal) == 0) { | 2888 | if (strcmp(dest->data, r->literal) != 0) |
2890 | debug_printf("found reserved word %s, code %d\n", r->literal, r->code); | 2889 | continue; |
2891 | if (r->flag & FLAG_START) { | 2890 | debug_printf("found reserved word %s, code %d\n", r->literal, r->code); |
2892 | struct p_context *new = xmalloc(sizeof(struct p_context)); | 2891 | if (r->flag & FLAG_START) { |
2893 | debug_printf("push stack\n"); | 2892 | struct p_context *new; |
2893 | debug_printf("push stack\n"); | ||
2894 | #if ENABLE_HUSH_LOOPS | 2894 | #if ENABLE_HUSH_LOOPS |
2895 | if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) { | 2895 | if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) { |
2896 | syntax(); | ||
2897 | free(new); | ||
2898 | ctx->res_w = RES_SNTX; | ||
2899 | b_reset(dest); | ||
2900 | return 1; | ||
2901 | } | ||
2902 | #endif | ||
2903 | *new = *ctx; /* physical copy */ | ||
2904 | initialize_context(ctx); | ||
2905 | ctx->stack = new; | ||
2906 | } else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) { | ||
2907 | syntax(); | 2896 | syntax(); |
2908 | ctx->res_w = RES_SNTX; | 2897 | ctx->res_w = RES_SNTX; |
2909 | b_reset(dest); | 2898 | b_reset(dest); |
2910 | return 1; | 2899 | return 1; |
2911 | } | 2900 | } |
2912 | ctx->res_w = r->code; | 2901 | #endif |
2913 | ctx->old_flag = r->flag; | 2902 | new = xmalloc(sizeof(*new)); |
2914 | if (ctx->old_flag & FLAG_END) { | 2903 | *new = *ctx; /* physical copy */ |
2915 | struct p_context *old; | 2904 | initialize_context(ctx); |
2916 | debug_printf("pop stack\n"); | 2905 | ctx->stack = new; |
2917 | done_pipe(ctx, PIPE_SEQ); | 2906 | } else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) { |
2918 | old = ctx->stack; | 2907 | syntax(); |
2919 | old->child->group = ctx->list_head; | 2908 | ctx->res_w = RES_SNTX; |
2920 | old->child->subshell = 0; | ||
2921 | *ctx = *old; /* physical copy */ | ||
2922 | free(old); | ||
2923 | } | ||
2924 | b_reset(dest); | 2909 | b_reset(dest); |
2925 | return 1; | 2910 | return 1; |
2926 | } | 2911 | } |
2912 | ctx->res_w = r->code; | ||
2913 | ctx->old_flag = r->flag; | ||
2914 | if (ctx->old_flag & FLAG_END) { | ||
2915 | struct p_context *old; | ||
2916 | debug_printf("pop stack\n"); | ||
2917 | done_pipe(ctx, PIPE_SEQ); | ||
2918 | old = ctx->stack; | ||
2919 | old->child->group = ctx->list_head; | ||
2920 | old->child->subshell = 0; | ||
2921 | *ctx = *old; /* physical copy */ | ||
2922 | free(old); | ||
2923 | } | ||
2924 | b_reset(dest); | ||
2925 | return 1; | ||
2927 | } | 2926 | } |
2928 | return 0; | 2927 | return 0; |
2929 | } | 2928 | } |
@@ -3155,7 +3154,8 @@ static int process_command_subs(o_string *dest, struct p_context *ctx, | |||
3155 | 3154 | ||
3156 | /* recursion to generate command */ | 3155 | /* recursion to generate command */ |
3157 | retcode = parse_stream(&result, &inner, input, subst_end); | 3156 | retcode = parse_stream(&result, &inner, input, subst_end); |
3158 | if (retcode != 0) return retcode; /* syntax error or EOF */ | 3157 | if (retcode != 0) |
3158 | return retcode; /* syntax error or EOF */ | ||
3159 | done_word(&result, &inner); | 3159 | done_word(&result, &inner); |
3160 | done_pipe(&inner, PIPE_SEQ); | 3160 | done_pipe(&inner, PIPE_SEQ); |
3161 | b_free(&result); | 3161 | b_free(&result); |
@@ -3357,9 +3357,15 @@ static int parse_stream(o_string *dest, struct p_context *ctx, | |||
3357 | 3357 | ||
3358 | debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger); | 3358 | debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger); |
3359 | 3359 | ||
3360 | while ((ch = b_getch(input)) != EOF) { | 3360 | while (1) { |
3361 | m = charmap[ch]; | 3361 | ch = b_getch(input); |
3362 | next = (ch == '\n') ? '\0' : b_peek(input); | 3362 | m = CHAR_IFS; |
3363 | next = '\0'; | ||
3364 | if (ch != EOF) { | ||
3365 | m = charmap[ch]; | ||
3366 | if (ch != '\n') | ||
3367 | next = b_peek(input); | ||
3368 | } | ||
3363 | debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n", | 3369 | debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n", |
3364 | ch, ch, m, dest->quote); | 3370 | ch, ch, m, dest->quote); |
3365 | if (m == CHAR_ORDINARY | 3371 | if (m == CHAR_ORDINARY |
@@ -3373,6 +3379,8 @@ static int parse_stream(o_string *dest, struct p_context *ctx, | |||
3373 | debug_printf_parse("parse_stream return 1: done_word!=0\n"); | 3379 | debug_printf_parse("parse_stream return 1: done_word!=0\n"); |
3374 | return 1; | 3380 | return 1; |
3375 | } | 3381 | } |
3382 | if (ch == EOF) | ||
3383 | break; | ||
3376 | /* If we aren't performing a substitution, treat | 3384 | /* If we aren't performing a substitution, treat |
3377 | * a newline as a command separator. | 3385 | * a newline as a command separator. |
3378 | * [why we don't handle it exactly like ';'? --vda] */ | 3386 | * [why we don't handle it exactly like ';'? --vda] */ |