aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-18 09:20:35 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-18 09:20:35 +0000
commitc1c63b622dfc863798e0873feba6ccd1677394aa (patch)
tree08196e8b604f1335ff1784e6913c88b40aadbb6e
parent4954d47ab01624855fdf4bcf0a86fb86f6381638 (diff)
downloadbusybox-w32-c1c63b622dfc863798e0873feba6ccd1677394aa.tar.gz
busybox-w32-c1c63b622dfc863798e0873feba6ccd1677394aa.tar.bz2
busybox-w32-c1c63b622dfc863798e0873feba6ccd1677394aa.zip
hush: fix last hush-bugs testcase (disappearing "", $empty"" etc)
-rw-r--r--shell/hush.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/shell/hush.c b/shell/hush.c
index e49e6e9b2..cb289769e 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2354,7 +2354,6 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2354 switch (first_ch & 0x7f) { 2354 switch (first_ch & 0x7f) {
2355 /* Highest bit in first_ch indicates that var is double-quoted */ 2355 /* Highest bit in first_ch indicates that var is double-quoted */
2356 case '$': /* pid */ 2356 case '$': /* pid */
2357 /* FIXME: (echo $$) should still print pid of main shell */
2358 val = utoa(root_pid); 2357 val = utoa(root_pid);
2359 break; 2358 break;
2360 case '!': /* bg pid */ 2359 case '!': /* bg pid */
@@ -2406,8 +2405,13 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2406 } 2405 }
2407 } 2406 }
2408 break; 2407 break;
2408 case SPECIAL_VAR_SYMBOL: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
2409 /* "Empty variable", used to make "" etc to not disappear */
2410 arg++;
2411 ored_ch = 0x80;
2412 break;
2409#if ENABLE_HUSH_TICK 2413#if ENABLE_HUSH_TICK
2410 case '`': { 2414 case '`': { /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
2411 struct in_str input; 2415 struct in_str input;
2412 *p = '\0'; 2416 *p = '\0';
2413 arg++; 2417 arg++;
@@ -2420,7 +2424,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
2420 goto store_val; 2424 goto store_val;
2421 } 2425 }
2422#endif 2426#endif
2423 default: 2427 default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
2424 *p = '\0'; 2428 *p = '\0';
2425 arg[0] = first_ch & 0x7f; 2429 arg[0] = first_ch & 0x7f;
2426 if (isdigit(arg[0])) { 2430 if (isdigit(arg[0])) {
@@ -2856,9 +2860,11 @@ static int done_word(o_string *word, struct p_context *ctx)
2856 char ***glob_target; 2860 char ***glob_target;
2857 2861
2858 debug_printf_parse("done_word entered: '%s' %p\n", word->data, child); 2862 debug_printf_parse("done_word entered: '%s' %p\n", word->data, child);
2859 if (word->length == 0 && !word->nonnull) { 2863 if (word->length == 0) {
2860 debug_printf_parse("done_word return 0: true null, ignored\n"); 2864 if (!word->nonnull) {
2861 return 0; 2865 debug_printf_parse("done_word return 0: true null, ignored\n");
2866 return 0;
2867 }
2862 } 2868 }
2863 if (ctx->pending_redirect) { 2869 if (ctx->pending_redirect) {
2864 glob_target = &ctx->pending_redirect->glob_word; 2870 glob_target = &ctx->pending_redirect->glob_word;
@@ -2868,7 +2874,7 @@ static int done_word(o_string *word, struct p_context *ctx)
2868 debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n"); 2874 debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n");
2869 return 1; 2875 return 1;
2870 } 2876 }
2871 if (!child->argv) { 2877 if (!child->argv) { /* if it's the first word... */
2872 debug_printf_parse(": checking '%s' for reserved-ness\n", word->data); 2878 debug_printf_parse(": checking '%s' for reserved-ness\n", word->data);
2873 if (reserved_word(word, ctx)) { 2879 if (reserved_word(word, ctx)) {
2874 o_reset(word); 2880 o_reset(word);
@@ -2876,10 +2882,18 @@ static int done_word(o_string *word, struct p_context *ctx)
2876 return (ctx->res_w == RES_SNTX); 2882 return (ctx->res_w == RES_SNTX);
2877 } 2883 }
2878 } 2884 }
2885 if (word->nonnull) {
2886 /* Insert "empty variable" reference, this makes e.g. "", '',
2887 * $empty"" etc to not disappear */
2888 o_addchr(word, SPECIAL_VAR_SYMBOL);
2889 o_addchr(word, SPECIAL_VAR_SYMBOL);
2890 }
2879 glob_target = &child->argv; 2891 glob_target = &child->argv;
2880 } 2892 }
2881 2893
2882 if (word->length || word->nonnull) { 2894//FIXME: we had globbing here, but now it's moved! Do we glob in e.g. ">*.tmp" now!?
2895
2896 /*if (word->length || word->nonnull) - true */ {
2883 *glob_target = add_malloced_string_to_strings(*glob_target, xstrdup(word->data)); 2897 *glob_target = add_malloced_string_to_strings(*glob_target, xstrdup(word->data));
2884 debug_print_strings("glob_target appended", *glob_target); 2898 debug_print_strings("glob_target appended", *glob_target);
2885 } 2899 }
@@ -3026,11 +3040,10 @@ static int redirect_opt_num(o_string *o)
3026 if (o->length == 0) 3040 if (o->length == 0)
3027 return -1; 3041 return -1;
3028 for (num = 0; num < o->length; num++) { 3042 for (num = 0; num < o->length; num++) {
3029 if (!isdigit(*(o->data + num))) { 3043 if (!isdigit(o->data[num])) {
3030 return -1; 3044 return -1;
3031 } 3045 }
3032 } 3046 }
3033 /* reuse num (and save an int) */
3034 num = atoi(o->data); 3047 num = atoi(o->data);
3035 o_reset(o); 3048 o_reset(o);
3036 return num; 3049 return num;
@@ -3668,8 +3681,8 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
3668 free(ctx.stack); 3681 free(ctx.stack);
3669 o_reset(&temp); 3682 o_reset(&temp);
3670 } 3683 }
3671 temp.nonnull = 0; 3684 /*temp.nonnull = 0; - o_free does it below */
3672 temp.o_quote = 0; 3685 /*temp.o_quote = 0; - o_free does it below */
3673 free_pipe_list(ctx.list_head, /* indent: */ 0); 3686 free_pipe_list(ctx.list_head, /* indent: */ 0);
3674 /* Discard all unprocessed line input, force prompt on */ 3687 /* Discard all unprocessed line input, force prompt on */
3675 inp->p = NULL; 3688 inp->p = NULL;