[git commit] hush: simplify \<newline> code, part 3

Denys Vlasenko vda.linux at googlemail.com
Tue Apr 10 12:27:08 UTC 2018


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

function                                             old     new   delta
parse_stream                                        2780    2762     -18

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

diff --git a/shell/hush.c b/shell/hush.c
index 3c6718648..6cd85cc4d 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -5052,19 +5052,43 @@ static struct pipe *parse_stream(char **pstring,
 		}
 		nommu_addchr(&ctx.as_string, ch);
 
+		if (ch == '\'') {
+			ctx.word.has_quoted_part = 1;
+			next = i_getch(input);
+			if (next == '\'' && !ctx.pending_redirect)
+				goto insert_empty_quoted_str_marker;
+
+			ch = next;
+			while (1) {
+				if (ch == EOF) {
+					syntax_error_unterm_ch('\'');
+					goto parse_error;
+				}
+				nommu_addchr(&ctx.as_string, ch);
+				if (ch == '\'')
+					break;
+				if (ch == SPECIAL_VAR_SYMBOL) {
+					/* Convert raw ^C to corresponding special variable reference */
+					o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
+					o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
+				}
+				o_addqchr(&ctx.word, ch);
+				ch = i_getch(input);
+			}
+			continue; /* get next char */
+		}
+
 		next = '\0';
-		if (ch != '\n') {
-			/* Do not break this case:
-			 *  echo '\
-			 *  '
-			 * and
-			 *  echo z\\
+		if (ch != '\n' && ch != '\\') {
+			/* Not on '\': do not break the case of "echo z\\":
+			 * on 2nd '\', i_peek_and_eat_bkslash_nl()
+			 * would stop and try to read next line,
+			 * not letting the command to execute.
 			 */
-			next = (ch == '\'' || ch == '\\') ? i_peek(input) : i_peek_and_eat_bkslash_nl(input);
-///
+			next = i_peek_and_eat_bkslash_nl(input);
 		}
 
-		is_special = "{}<>;&|()#'" /* special outside of "str" */
+		is_special = "{}<>;&|()#" /* special outside of "str" */
 				"\\$\"" IF_HUSH_TICK("`") /* always special */
 				SPECIAL_VAR_SYMBOL_STR;
 		/* Are { and } special here? */
@@ -5252,7 +5276,7 @@ static struct pipe *parse_stream(char **pstring,
 				return ctx.list_head;
 			}
 		}
- skip_end_trigger:
+
 		if (is_blank)
 			continue;
 
@@ -5278,7 +5302,7 @@ static struct pipe *parse_stream(char **pstring,
 #endif
 			if (parse_redirect(&ctx, redir_fd, redir_style, input))
 				goto parse_error;
-			continue; /* back to top of while (1) */
+			continue; /* get next char */
 		case '<':
 			redir_fd = redirect_opt_num(&ctx.word);
 			if (done_word(&ctx)) {
@@ -5304,7 +5328,7 @@ static struct pipe *parse_stream(char **pstring,
 #endif
 			if (parse_redirect(&ctx, redir_fd, redir_style, input))
 				goto parse_error;
-			continue; /* back to top of while (1) */
+			continue; /* get next char */
 		case '#':
 			if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
 				/* skip "#comment" */
@@ -5325,23 +5349,11 @@ static struct pipe *parse_stream(char **pstring,
 					if (ch == EOF)
 						break;
 				}
-				continue; /* back to top of while (1) */
-			}
-			break;
-#if 0 /* looks like we never reach this code */
-		case '\\':
-			if (next == '\n') {
-				/* It's "\<newline>" */
-#if !BB_MMU
-				/* Remove trailing '\' from ctx.as_string */
-				ctx.as_string.data[--ctx.as_string.length] = '\0';
-#endif
-				ch = i_getch(input); /* eat it */
-				continue; /* back to top of while (1) */
+				continue; /* get next char */
 			}
 			break;
-#endif
 		}
+ skip_end_trigger:
 
 		if (ctx.is_assignment == MAYBE_ASSIGNMENT
 		 /* check that we are not in word in "a=1 2>word b=1": */
@@ -5366,20 +5378,19 @@ static struct pipe *parse_stream(char **pstring,
 			o_addchr(&ctx.word, ch);
 			continue; /* get next char */
 		case '\\':
-			if (next == EOF) {
+			/*nommu_addchr(&ctx.as_string, '\\'); - already done */
+			o_addchr(&ctx.word, '\\');
+			ch = i_getch(input);
+			if (ch == EOF) {
 //TODO: in ". FILE" containing "cmd\" (no newline) bash ignores last "\"
 				syntax_error("\\<eof>");
 				xfunc_die();
 			}
-			ch = i_getch(input);
-			/* note: ch != '\n' (that case does not reach this place) */
-			o_addchr(&ctx.word, '\\');
-			/*nommu_addchr(&ctx.as_string, '\\'); - already done */
-			o_addchr(&ctx.word, ch);
-			nommu_addchr(&ctx.as_string, ch);
 			/* Example: echo Hello \2>file
 			 * we need to know that word 2 is quoted */
 			ctx.word.has_quoted_part = 1;
+			nommu_addchr(&ctx.as_string, ch);
+			o_addchr(&ctx.word, ch);
 			continue; /* get next char */
 		case '$':
 			if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
@@ -5388,33 +5399,12 @@ static struct pipe *parse_stream(char **pstring,
 				goto parse_error;
 			}
 			continue; /* get next char */
-		case '\'':
-			ctx.word.has_quoted_part = 1;
-			if (next == '\'' && !ctx.pending_redirect)
-				goto insert_empty_quoted_str_marker;
-			while (1) {
-				ch = i_getch(input);
-				if (ch == EOF) {
-					syntax_error_unterm_ch('\'');
-					goto parse_error;
-				}
-				nommu_addchr(&ctx.as_string, ch);
-				if (ch == '\'')
-					break;
-				if (ch == SPECIAL_VAR_SYMBOL) {
-					/* Convert raw ^C to corresponding special variable reference */
-					o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
-					o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
-				}
-				o_addqchr(&ctx.word, ch);
-			}
-			continue; /* get next char */
 		case '"':
 			ctx.word.has_quoted_part = 1;
 			if (next == '"' && !ctx.pending_redirect) {
+				i_getch(input); /* eat second " */
  insert_empty_quoted_str_marker:
 				nommu_addchr(&ctx.as_string, next);
-				i_getch(input); /* eat second ' */
 				o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
 				o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
 				continue; /* get next char */


More information about the busybox-cvs mailing list