summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-05-23 00:32:25 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-05-23 00:32:25 +0000
commit1a7358612ff2dfdfc9fa461faa946c577666787f (patch)
tree3edf610e1f0bab6f33e90716fc1550f0c9060991 /shell/hush.c
parent94dace30160131fc3f45b3f486463c49cda05204 (diff)
downloadbusybox-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.c84
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
2837static void initialize_context(struct p_context *ctx) 2837static 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] */