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 | |
| 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')
| -rw-r--r-- | shell/hush.c | 84 | ||||
| -rw-r--r-- | shell/hush_test/hush-parsing/noeol2.right | 1 | ||||
| -rwxr-xr-x | shell/hush_test/hush-parsing/noeol2.tests | 7 | ||||
| -rw-r--r-- | shell/hush_test/hush-vars/star.right | 1 | ||||
| -rwxr-xr-x | shell/hush_test/hush-vars/star.tests | 4 |
5 files changed, 57 insertions, 40 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] */ |
diff --git a/shell/hush_test/hush-parsing/noeol2.right b/shell/hush_test/hush-parsing/noeol2.right new file mode 100644 index 000000000..d00491fd7 --- /dev/null +++ b/shell/hush_test/hush-parsing/noeol2.right | |||
| @@ -0,0 +1 @@ | |||
| 1 | |||
diff --git a/shell/hush_test/hush-parsing/noeol2.tests b/shell/hush_test/hush-parsing/noeol2.tests new file mode 100755 index 000000000..1220f056f --- /dev/null +++ b/shell/hush_test/hush-parsing/noeol2.tests | |||
| @@ -0,0 +1,7 @@ | |||
| 1 | # last line has no EOL! | ||
| 2 | if true | ||
| 3 | then | ||
| 4 | echo 1 | ||
| 5 | else | ||
| 6 | echo 2 | ||
| 7 | fi \ No newline at end of file | ||
diff --git a/shell/hush_test/hush-vars/star.right b/shell/hush_test/hush-vars/star.right index b33b176b2..0ecc55bc2 100644 --- a/shell/hush_test/hush-vars/star.right +++ b/shell/hush_test/hush-vars/star.right | |||
| @@ -3,3 +3,4 @@ | |||
| 3 | .d. | 3 | .d. |
| 4 | .e. | 4 | .e. |
| 5 | .f. | 5 | .f. |
| 6 | .1 abc d e f. | ||
diff --git a/shell/hush_test/hush-vars/star.tests b/shell/hush_test/hush-vars/star.tests index 1914dde44..5554c4090 100755 --- a/shell/hush_test/hush-vars/star.tests +++ b/shell/hush_test/hush-vars/star.tests | |||
| @@ -4,5 +4,5 @@ fi | |||
| 4 | # 'd e f' should be split into 3 separate args: | 4 | # 'd e f' should be split into 3 separate args: |
| 5 | for a in $*; do echo ".$a."; done | 5 | for a in $*; do echo ".$a."; done |
| 6 | 6 | ||
| 7 | # must produce .1 abc d e f. Currently does not | 7 | # must produce .1 abc d e f. |
| 8 | #for a in "$*"; do echo ".$a."; done | 8 | for a in "$*"; do echo ".$a."; done |
