hush: echo \2>file fix

diff --git a/shell/hush.c b/shell/hush.c
index d5c90a2..5594aae 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -4081,7 +4081,7 @@
  * the redirection expression. For example:
  * echo \2>a
  * writes the character 2 into file a"
- * I am not sure we do it right (and not sure we care)
+ * We are getting it right by setting ->o_quoted on any \<char>
  *
  * A -1 return means no valid number was found,
  * the caller should use the appropriate default for this redirection.
@@ -4141,6 +4141,9 @@
 	}
 }
 
+/* Look at entire parse tree for not-yet-loaded REDIRECT_HEREDOCs
+ * and load them all. There should be exactly heredoc_cnt of them.
+ */
 static int fetch_heredocs(int heredoc_cnt, struct parse_context *ctx, struct in_str *input)
 {
 	struct pipe *pi = ctx->list_head;
@@ -4161,14 +4164,18 @@
 				if (redir->rd_type == REDIRECT_HEREDOC) {
 					char *p;
 
-					if (heredoc_cnt <= 0)
+					if (heredoc_cnt <= 0) {
+						syntax("heredoc BUG 1");
 						return 1; /* error */
+					}
 					redir->rd_type = REDIRECT_HEREDOC2;
 					/* redir->dup is (ab)used to indicate <<- */
 					p = fetch_till_str(&ctx->as_string, input,
 						redir->rd_filename, redir->rd_dup & HEREDOC_SKIPTABS);
-					if (!p)
-						return 1; /* unexpected EOF */
+					if (!p) {
+						syntax("unexpected EOF in here document");
+						return 1;
+					}
 					free(redir->rd_filename);
 					redir->rd_filename = p;
 					heredoc_cnt--;
@@ -4180,6 +4187,8 @@
 		pi = pi->next;
 	}
 	/* Should be 0. If it isn't, it's a parse error */
+	if (heredoc_cnt)
+		syntax("heredoc BUG 2");
 	return heredoc_cnt;
 }
 
@@ -4673,12 +4682,12 @@
 	if (ch != EOF)
 		nommu_addchr(as_string, ch);
 	if (ch == dquote_end) { /* may be only '"' or EOF */
-		dest->o_quoted = 1;
 		if (dest->o_assignment == NOT_ASSIGNMENT)
 			dest->o_escape ^= 1;
 		debug_printf_parse("parse_stream_dquoted return 0\n");
 		return 0;
 	}
+	/* note: can't move it above ch == dquote_end check! */
 	if (ch == EOF) {
 		syntax("unterminated \"");
 		debug_printf_parse("parse_stream_dquoted return 1: unterminated \"\n");
@@ -4787,6 +4796,7 @@
 		redir_type redir_style;
 
 		if (is_in_dquote) {
+			/* dest.o_quoted = 1; - already is (see below) */
 			if (parse_stream_dquoted(&ctx.as_string, &dest, input, '"')) {
 				goto parse_error;
 			}
@@ -4863,8 +4873,9 @@
 				done_pipe(&ctx, PIPE_SEQ);
 				debug_printf_parse("heredoc_cnt:%d\n", heredoc_cnt);
 				if (heredoc_cnt) {
-					if (fetch_heredocs(heredoc_cnt, &ctx, input))
+					if (fetch_heredocs(heredoc_cnt, &ctx, input)) {
 						goto parse_error;
+					}
 					heredoc_cnt = 0;
 				}
 				dest.o_assignment = MAYBE_ASSIGNMENT;
@@ -4938,7 +4949,6 @@
 					i_getch(input);
 					/* note: we do not add it to &ctx.as_string */
 				}
-//TODO: go back one char?
 				nommu_addchr(&ctx.as_string, '\n');
 			} else {
 				o_addQchr(&dest, ch);
@@ -4951,8 +4961,11 @@
 			}
 			o_addchr(&dest, '\\');
 			ch = i_getch(input);
-			o_addchr(&dest, ch);
 			nommu_addchr(&ctx.as_string, ch);
+			o_addchr(&dest, ch);
+			/* Example: echo Hello \2>file
+			 * we need to know that word 2 is quoted */
+			dest.o_quoted = 1;
 			break;
 		case '$':
 			if (handle_dollar(&ctx.as_string, &dest, input) != 0) {
diff --git a/shell/hush_test/hush-misc/heredoc2.right b/shell/hush_test/hush-misc/heredoc2.right
index 66545ae..74110e3 100644
--- a/shell/hush_test/hush-misc/heredoc2.right
+++ b/shell/hush_test/hush-misc/heredoc2.right
@@ -6,3 +6,4 @@
  EOF-f
 EOF-f   f
 EOF-f 
+Ok
diff --git a/shell/hush_test/hush-misc/heredoc2.tests b/shell/hush_test/hush-misc/heredoc2.tests
index 19d9c96..e619bde 100755
--- a/shell/hush_test/hush-misc/heredoc2.tests
+++ b/shell/hush_test/hush-misc/heredoc2.tests
@@ -9,3 +9,4 @@
 EOF-f   f
 EOF-f 
 EOF-f
+echo Ok
diff --git a/shell/hush_test/hush-misc/heredoc3.right b/shell/hush_test/hush-misc/heredoc3.right
index 9b114fa..6ed517f 100644
--- a/shell/hush_test/hush-misc/heredoc3.right
+++ b/shell/hush_test/hush-misc/heredoc3.right
@@ -6,3 +6,4 @@
  EOF-f
 EOF-f   f
 EOF-f 
+Ok
diff --git a/shell/hush_test/hush-misc/heredoc3.tests b/shell/hush_test/hush-misc/heredoc3.tests
index 6391e49..938577a 100755
--- a/shell/hush_test/hush-misc/heredoc3.tests
+++ b/shell/hush_test/hush-misc/heredoc3.tests
@@ -9,3 +9,4 @@
 EOF-f   f
 EOF-f 
 EOF-f
+echo Ok
diff --git a/shell/hush_test/hush-misc/redir2.right b/shell/hush_test/hush-misc/redir2.right
new file mode 100644
index 0000000..7326d96
--- /dev/null
+++ b/shell/hush_test/hush-misc/redir2.right
@@ -0,0 +1 @@
+Ok
diff --git a/shell/hush_test/hush-misc/redir2.tests b/shell/hush_test/hush-misc/redir2.tests
new file mode 100755
index 0000000..81983ca
--- /dev/null
+++ b/shell/hush_test/hush-misc/redir2.tests
@@ -0,0 +1,2 @@
+echo NOT SHOWN \2>/dev/null
+echo Ok