[git commit] hush: fix heredoc_bkslash_newline1.tests failure

Denys Vlasenko vda.linux at googlemail.com
Sat Mar 31 18:16:31 UTC 2018


commit: https://git.busybox.net/busybox/commit/?id=a94eeb0b4222de7f05594c93ffdd84faea5b8e2d
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

function                                             old     new   delta
parse_stream                                        2787    2827     +40
builtin_type                                         117     115      -2

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 shell/hush.c | 77 +++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 42 insertions(+), 35 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index 01d8f5935..533d45ac3 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2694,6 +2694,42 @@ static int i_peek2(struct in_str *i)
 	return ch;
 }
 
+static int i_getch_and_eat_bkslash_nl(struct in_str *input)
+{
+	for (;;) {
+		int ch, ch2;
+
+		ch = i_getch(input);
+		if (ch != '\\')
+			return ch;
+		ch2 = i_peek(input);
+		if (ch2 != '\n')
+			return ch;
+		/* backslash+newline, skip it */
+		i_getch(input);
+	}
+}
+
+/* Note: this function _eats_ \<newline> pairs, safe to use plain
+ * i_getch() after it instead of i_getch_and_eat_bkslash_nl().
+ */
+static int i_peek_and_eat_bkslash_nl(struct in_str *input)
+{
+	for (;;) {
+		int ch, ch2;
+
+		ch = i_peek(input);
+		if (ch != '\\')
+			return ch;
+		ch2 = i_peek2(input);
+		if (ch2 != '\n')
+			return ch;
+		/* backslash+newline, skip it */
+		i_getch(input);
+		i_getch(input);
+	}
+}
+
 static void setup_file_in_str(struct in_str *i, FILE *f)
 {
 	memset(i, 0, sizeof(*i));
@@ -4014,7 +4050,7 @@ static int parse_redirect(struct parse_context *ctx,
 		if (dup_num == REDIRFD_SYNTAX_ERR)
 			return 1;
 	} else {
-		int ch = i_peek(input);
+		int ch = i_peek_and_eat_bkslash_nl(input);
 		dup_num = (ch == '-'); /* HEREDOC_SKIPTABS bit is 1 */
 		if (dup_num) { /* <<-... */
 			ch = i_getch(input);
@@ -4024,7 +4060,7 @@ static int parse_redirect(struct parse_context *ctx,
 	}
 
 	if (style == REDIRECT_OVERWRITE && dup_num == REDIRFD_TO_FILE) {
-		int ch = i_peek(input);
+		int ch = i_peek_and_eat_bkslash_nl(input);
 		if (ch == '|') {
 			/* >|FILE redirect ("clobbering" >).
 			 * Since we do not support "set -o noclobber" yet,
@@ -4343,39 +4379,6 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
 	/* command remains "open", available for possible redirects */
 }
 
-static int i_getch_and_eat_bkslash_nl(struct in_str *input)
-{
-	for (;;) {
-		int ch, ch2;
-
-		ch = i_getch(input);
-		if (ch != '\\')
-			return ch;
-		ch2 = i_peek(input);
-		if (ch2 != '\n')
-			return ch;
-		/* backslash+newline, skip it */
-		i_getch(input);
-	}
-}
-
-static int i_peek_and_eat_bkslash_nl(struct in_str *input)
-{
-	for (;;) {
-		int ch, ch2;
-
-		ch = i_peek(input);
-		if (ch != '\\')
-			return ch;
-		ch2 = i_peek2(input);
-		if (ch2 != '\n')
-			return ch;
-		/* backslash+newline, skip it */
-		i_getch(input);
-		i_getch(input);
-	}
-}
-
 #if ENABLE_HUSH_TICK || ENABLE_FEATURE_SH_MATH || ENABLE_HUSH_DOLLAR_OPS
 /* Subroutines for copying $(...) and `...` things */
 static int add_till_backquote(o_string *dest, struct in_str *input, int in_dquote);
@@ -5181,6 +5184,8 @@ static struct pipe *parse_stream(char **pstring,
 				goto parse_error;
 			}
 			redir_style = REDIRECT_OVERWRITE;
+			if (next == '\\')
+				next = i_peek_and_eat_bkslash_nl(input);
 			if (next == '>') {
 				redir_style = REDIRECT_APPEND;
 				ch = i_getch(input);
@@ -5201,6 +5206,8 @@ static struct pipe *parse_stream(char **pstring,
 				goto parse_error;
 			}
 			redir_style = REDIRECT_INPUT;
+			if (next == '\\')
+				next = i_peek_and_eat_bkslash_nl(input);
 			if (next == '<') {
 				redir_style = REDIRECT_HEREDOC;
 				heredoc_cnt++;


More information about the busybox-cvs mailing list