hush: fix a bit different instance of "No EOL" bug,
add testsuite for that. Expand another testsuite.
This commit is contained in:
parent
94dace3016
commit
1a7358612f
84
shell/hush.c
84
shell/hush.c
@ -2836,14 +2836,13 @@ static struct pipe *new_pipe(void)
|
|||||||
|
|
||||||
static void initialize_context(struct p_context *ctx)
|
static void initialize_context(struct p_context *ctx)
|
||||||
{
|
{
|
||||||
ctx->pipe = NULL;
|
|
||||||
ctx->pending_redirect = NULL;
|
|
||||||
ctx->child = NULL;
|
ctx->child = NULL;
|
||||||
ctx->list_head = new_pipe();
|
ctx->pipe = ctx->list_head = new_pipe();
|
||||||
ctx->pipe = ctx->list_head;
|
ctx->pending_redirect = NULL;
|
||||||
ctx->res_w = RES_NONE;
|
ctx->res_w = RES_NONE;
|
||||||
ctx->stack = NULL;
|
//only ctx->parse_type is not touched... is this intentional?
|
||||||
ctx->old_flag = 0;
|
ctx->old_flag = 0;
|
||||||
|
ctx->stack = NULL;
|
||||||
done_command(ctx); /* creates the memory for working child */
|
done_command(ctx); /* creates the memory for working child */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2886,44 +2885,44 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
|
|||||||
const struct reserved_combo *r;
|
const struct reserved_combo *r;
|
||||||
|
|
||||||
for (r = reserved_list; r < reserved_list + NRES; r++) {
|
for (r = reserved_list; r < reserved_list + NRES; r++) {
|
||||||
if (strcmp(dest->data, r->literal) == 0) {
|
if (strcmp(dest->data, r->literal) != 0)
|
||||||
debug_printf("found reserved word %s, code %d\n", r->literal, r->code);
|
continue;
|
||||||
if (r->flag & FLAG_START) {
|
debug_printf("found reserved word %s, code %d\n", r->literal, r->code);
|
||||||
struct p_context *new = xmalloc(sizeof(struct p_context));
|
if (r->flag & FLAG_START) {
|
||||||
debug_printf("push stack\n");
|
struct p_context *new;
|
||||||
|
debug_printf("push stack\n");
|
||||||
#if ENABLE_HUSH_LOOPS
|
#if ENABLE_HUSH_LOOPS
|
||||||
if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) {
|
if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) {
|
||||||
syntax();
|
|
||||||
free(new);
|
|
||||||
ctx->res_w = RES_SNTX;
|
|
||||||
b_reset(dest);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
*new = *ctx; /* physical copy */
|
|
||||||
initialize_context(ctx);
|
|
||||||
ctx->stack = new;
|
|
||||||
} else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) {
|
|
||||||
syntax();
|
syntax();
|
||||||
ctx->res_w = RES_SNTX;
|
ctx->res_w = RES_SNTX;
|
||||||
b_reset(dest);
|
b_reset(dest);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ctx->res_w = r->code;
|
#endif
|
||||||
ctx->old_flag = r->flag;
|
new = xmalloc(sizeof(*new));
|
||||||
if (ctx->old_flag & FLAG_END) {
|
*new = *ctx; /* physical copy */
|
||||||
struct p_context *old;
|
initialize_context(ctx);
|
||||||
debug_printf("pop stack\n");
|
ctx->stack = new;
|
||||||
done_pipe(ctx, PIPE_SEQ);
|
} else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) {
|
||||||
old = ctx->stack;
|
syntax();
|
||||||
old->child->group = ctx->list_head;
|
ctx->res_w = RES_SNTX;
|
||||||
old->child->subshell = 0;
|
|
||||||
*ctx = *old; /* physical copy */
|
|
||||||
free(old);
|
|
||||||
}
|
|
||||||
b_reset(dest);
|
b_reset(dest);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
ctx->res_w = r->code;
|
||||||
|
ctx->old_flag = r->flag;
|
||||||
|
if (ctx->old_flag & FLAG_END) {
|
||||||
|
struct p_context *old;
|
||||||
|
debug_printf("pop stack\n");
|
||||||
|
done_pipe(ctx, PIPE_SEQ);
|
||||||
|
old = ctx->stack;
|
||||||
|
old->child->group = ctx->list_head;
|
||||||
|
old->child->subshell = 0;
|
||||||
|
*ctx = *old; /* physical copy */
|
||||||
|
free(old);
|
||||||
|
}
|
||||||
|
b_reset(dest);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -3155,7 +3154,8 @@ static int process_command_subs(o_string *dest, struct p_context *ctx,
|
|||||||
|
|
||||||
/* recursion to generate command */
|
/* recursion to generate command */
|
||||||
retcode = parse_stream(&result, &inner, input, subst_end);
|
retcode = parse_stream(&result, &inner, input, subst_end);
|
||||||
if (retcode != 0) return retcode; /* syntax error or EOF */
|
if (retcode != 0)
|
||||||
|
return retcode; /* syntax error or EOF */
|
||||||
done_word(&result, &inner);
|
done_word(&result, &inner);
|
||||||
done_pipe(&inner, PIPE_SEQ);
|
done_pipe(&inner, PIPE_SEQ);
|
||||||
b_free(&result);
|
b_free(&result);
|
||||||
@ -3357,9 +3357,15 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
|
|||||||
|
|
||||||
debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger);
|
debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger);
|
||||||
|
|
||||||
while ((ch = b_getch(input)) != EOF) {
|
while (1) {
|
||||||
m = charmap[ch];
|
ch = b_getch(input);
|
||||||
next = (ch == '\n') ? '\0' : b_peek(input);
|
m = CHAR_IFS;
|
||||||
|
next = '\0';
|
||||||
|
if (ch != EOF) {
|
||||||
|
m = charmap[ch];
|
||||||
|
if (ch != '\n')
|
||||||
|
next = b_peek(input);
|
||||||
|
}
|
||||||
debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n",
|
debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n",
|
||||||
ch, ch, m, dest->quote);
|
ch, ch, m, dest->quote);
|
||||||
if (m == CHAR_ORDINARY
|
if (m == CHAR_ORDINARY
|
||||||
@ -3373,6 +3379,8 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
|
|||||||
debug_printf_parse("parse_stream return 1: done_word!=0\n");
|
debug_printf_parse("parse_stream return 1: done_word!=0\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
if (ch == EOF)
|
||||||
|
break;
|
||||||
/* If we aren't performing a substitution, treat
|
/* If we aren't performing a substitution, treat
|
||||||
* a newline as a command separator.
|
* a newline as a command separator.
|
||||||
* [why we don't handle it exactly like ';'? --vda] */
|
* [why we don't handle it exactly like ';'? --vda] */
|
||||||
|
1
shell/hush_test/hush-parsing/noeol2.right
Normal file
1
shell/hush_test/hush-parsing/noeol2.right
Normal file
@ -0,0 +1 @@
|
|||||||
|
1
|
7
shell/hush_test/hush-parsing/noeol2.tests
Executable file
7
shell/hush_test/hush-parsing/noeol2.tests
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
# last line has no EOL!
|
||||||
|
if true
|
||||||
|
then
|
||||||
|
echo 1
|
||||||
|
else
|
||||||
|
echo 2
|
||||||
|
fi
|
@ -3,3 +3,4 @@
|
|||||||
.d.
|
.d.
|
||||||
.e.
|
.e.
|
||||||
.f.
|
.f.
|
||||||
|
.1 abc d e f.
|
||||||
|
@ -4,5 +4,5 @@ fi
|
|||||||
# 'd e f' should be split into 3 separate args:
|
# 'd e f' should be split into 3 separate args:
|
||||||
for a in $*; do echo ".$a."; done
|
for a in $*; do echo ".$a."; done
|
||||||
|
|
||||||
# must produce .1 abc d e f. Currently does not
|
# must produce .1 abc d e f.
|
||||||
#for a in "$*"; do echo ".$a."; done
|
for a in "$*"; do echo ".$a."; done
|
||||||
|
Loading…
Reference in New Issue
Block a user