hush: fix last hush-bugs testcase (disappearing "", $empty"" etc)
This commit is contained in:
parent
4954d47ab0
commit
c1c63b622d
37
shell/hush.c
37
shell/hush.c
@ -2354,7 +2354,6 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
|
|||||||
switch (first_ch & 0x7f) {
|
switch (first_ch & 0x7f) {
|
||||||
/* Highest bit in first_ch indicates that var is double-quoted */
|
/* Highest bit in first_ch indicates that var is double-quoted */
|
||||||
case '$': /* pid */
|
case '$': /* pid */
|
||||||
/* FIXME: (echo $$) should still print pid of main shell */
|
|
||||||
val = utoa(root_pid);
|
val = utoa(root_pid);
|
||||||
break;
|
break;
|
||||||
case '!': /* bg pid */
|
case '!': /* bg pid */
|
||||||
@ -2406,8 +2405,13 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case SPECIAL_VAR_SYMBOL: /* <SPECIAL_VAR_SYMBOL><SPECIAL_VAR_SYMBOL> */
|
||||||
|
/* "Empty variable", used to make "" etc to not disappear */
|
||||||
|
arg++;
|
||||||
|
ored_ch = 0x80;
|
||||||
|
break;
|
||||||
#if ENABLE_HUSH_TICK
|
#if ENABLE_HUSH_TICK
|
||||||
case '`': {
|
case '`': { /* <SPECIAL_VAR_SYMBOL>`cmd<SPECIAL_VAR_SYMBOL> */
|
||||||
struct in_str input;
|
struct in_str input;
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
arg++;
|
arg++;
|
||||||
@ -2420,7 +2424,7 @@ static int expand_vars_to_list(o_string *output, int n, char *arg, char or_mask)
|
|||||||
goto store_val;
|
goto store_val;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
default:
|
default: /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
arg[0] = first_ch & 0x7f;
|
arg[0] = first_ch & 0x7f;
|
||||||
if (isdigit(arg[0])) {
|
if (isdigit(arg[0])) {
|
||||||
@ -2856,9 +2860,11 @@ static int done_word(o_string *word, struct p_context *ctx)
|
|||||||
char ***glob_target;
|
char ***glob_target;
|
||||||
|
|
||||||
debug_printf_parse("done_word entered: '%s' %p\n", word->data, child);
|
debug_printf_parse("done_word entered: '%s' %p\n", word->data, child);
|
||||||
if (word->length == 0 && !word->nonnull) {
|
if (word->length == 0) {
|
||||||
debug_printf_parse("done_word return 0: true null, ignored\n");
|
if (!word->nonnull) {
|
||||||
return 0;
|
debug_printf_parse("done_word return 0: true null, ignored\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (ctx->pending_redirect) {
|
if (ctx->pending_redirect) {
|
||||||
glob_target = &ctx->pending_redirect->glob_word;
|
glob_target = &ctx->pending_redirect->glob_word;
|
||||||
@ -2868,7 +2874,7 @@ static int done_word(o_string *word, struct p_context *ctx)
|
|||||||
debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n");
|
debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!child->argv) {
|
if (!child->argv) { /* if it's the first word... */
|
||||||
debug_printf_parse(": checking '%s' for reserved-ness\n", word->data);
|
debug_printf_parse(": checking '%s' for reserved-ness\n", word->data);
|
||||||
if (reserved_word(word, ctx)) {
|
if (reserved_word(word, ctx)) {
|
||||||
o_reset(word);
|
o_reset(word);
|
||||||
@ -2876,10 +2882,18 @@ static int done_word(o_string *word, struct p_context *ctx)
|
|||||||
return (ctx->res_w == RES_SNTX);
|
return (ctx->res_w == RES_SNTX);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (word->nonnull) {
|
||||||
|
/* Insert "empty variable" reference, this makes e.g. "", '',
|
||||||
|
* $empty"" etc to not disappear */
|
||||||
|
o_addchr(word, SPECIAL_VAR_SYMBOL);
|
||||||
|
o_addchr(word, SPECIAL_VAR_SYMBOL);
|
||||||
|
}
|
||||||
glob_target = &child->argv;
|
glob_target = &child->argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (word->length || word->nonnull) {
|
//FIXME: we had globbing here, but now it's moved! Do we glob in e.g. ">*.tmp" now!?
|
||||||
|
|
||||||
|
/*if (word->length || word->nonnull) - true */ {
|
||||||
*glob_target = add_malloced_string_to_strings(*glob_target, xstrdup(word->data));
|
*glob_target = add_malloced_string_to_strings(*glob_target, xstrdup(word->data));
|
||||||
debug_print_strings("glob_target appended", *glob_target);
|
debug_print_strings("glob_target appended", *glob_target);
|
||||||
}
|
}
|
||||||
@ -3026,11 +3040,10 @@ static int redirect_opt_num(o_string *o)
|
|||||||
if (o->length == 0)
|
if (o->length == 0)
|
||||||
return -1;
|
return -1;
|
||||||
for (num = 0; num < o->length; num++) {
|
for (num = 0; num < o->length; num++) {
|
||||||
if (!isdigit(*(o->data + num))) {
|
if (!isdigit(o->data[num])) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* reuse num (and save an int) */
|
|
||||||
num = atoi(o->data);
|
num = atoi(o->data);
|
||||||
o_reset(o);
|
o_reset(o);
|
||||||
return num;
|
return num;
|
||||||
@ -3668,8 +3681,8 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
|
|||||||
free(ctx.stack);
|
free(ctx.stack);
|
||||||
o_reset(&temp);
|
o_reset(&temp);
|
||||||
}
|
}
|
||||||
temp.nonnull = 0;
|
/*temp.nonnull = 0; - o_free does it below */
|
||||||
temp.o_quote = 0;
|
/*temp.o_quote = 0; - o_free does it below */
|
||||||
free_pipe_list(ctx.list_head, /* indent: */ 0);
|
free_pipe_list(ctx.list_head, /* indent: */ 0);
|
||||||
/* Discard all unprocessed line input, force prompt on */
|
/* Discard all unprocessed line input, force prompt on */
|
||||||
inp->p = NULL;
|
inp->p = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user