hush: fix a bit different instance of "No EOL" bug,
add testsuite for that. Expand another testsuite.
diff --git a/shell/hush.c b/shell/hush.c
index 61c03f7..aab6ff3 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2836,14 +2836,13 @@
 
 static void initialize_context(struct p_context *ctx)
 {
-	ctx->pipe = NULL;
-	ctx->pending_redirect = NULL;
 	ctx->child = NULL;
-	ctx->list_head = new_pipe();
-	ctx->pipe = ctx->list_head;
+	ctx->pipe = ctx->list_head = new_pipe();
+	ctx->pending_redirect = NULL;
 	ctx->res_w = RES_NONE;
-	ctx->stack = NULL;
+	//only ctx->parse_type is not touched... is this intentional?
 	ctx->old_flag = 0;
+	ctx->stack = NULL;
 	done_command(ctx);   /* creates the memory for working child */
 }
 
@@ -2886,44 +2885,44 @@
 	const struct reserved_combo *r;
 
 	for (r = reserved_list;	r < reserved_list + NRES; r++) {
-		if (strcmp(dest->data, r->literal) == 0) {
-			debug_printf("found reserved word %s, code %d\n", r->literal, r->code);
-			if (r->flag & FLAG_START) {
-				struct p_context *new = xmalloc(sizeof(struct p_context));
-				debug_printf("push stack\n");
+		if (strcmp(dest->data, r->literal) != 0)
+			continue;
+		debug_printf("found reserved word %s, code %d\n", r->literal, r->code);
+		if (r->flag & FLAG_START) {
+			struct p_context *new;
+			debug_printf("push stack\n");
 #if ENABLE_HUSH_LOOPS
-				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))) {
+			if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) {
 				syntax();
 				ctx->res_w = RES_SNTX;
 				b_reset(dest);
 				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);
-			}
+#endif
+			new = xmalloc(sizeof(*new));
+			*new = *ctx;   /* physical copy */
+			initialize_context(ctx);
+			ctx->stack = new;
+		} else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->code))) {
+			syntax();
+			ctx->res_w = RES_SNTX;
 			b_reset(dest);
 			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;
 }
@@ -3155,7 +3154,8 @@
 
 	/* recursion to generate command */
 	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_pipe(&inner, PIPE_SEQ);
 	b_free(&result);
@@ -3357,9 +3357,15 @@
 
 	debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger);
 
-	while ((ch = b_getch(input)) != EOF) {
-		m = charmap[ch];
-		next = (ch == '\n') ? '\0' : b_peek(input);
+	while (1) {
+		ch = b_getch(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",
 						ch, ch, m, dest->quote);
 		if (m == CHAR_ORDINARY
@@ -3373,6 +3379,8 @@
 				debug_printf_parse("parse_stream return 1: done_word!=0\n");
 				return 1;
 			}
+			if (ch == EOF)
+				break;
 			/* If we aren't performing a substitution, treat
 			 * a newline as a command separator.
 			 * [why we don't handle it exactly like ';'? --vda] */