[git commit] hush: put "current word" structure into parsing context

Denys Vlasenko vda.linux at googlemail.com
Tue Apr 10 01:22:10 UTC 2018


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

function                                             old     new   delta
done_word                                            790     767     -23
parse_stream                                        3018    2919     -99
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-122)           Total: -122 bytes

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

diff --git a/shell/hush.c b/shell/hush.c
index 885561389..0c57803f1 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -522,7 +522,6 @@ typedef struct o_string {
 	 * possibly empty one: word"", wo''rd etc. */
 	smallint has_quoted_part;
 	smallint has_empty_slot;
-	smallint o_assignment; /* 0:maybe, 1:yes, 2:no */
 } o_string;
 enum {
 	EXP_FLAG_SINGLEWORD     = 0x80, /* must be 0x80 */
@@ -531,13 +530,6 @@ enum {
 	 * by prepending \ to *, ?, [, \ */
 	EXP_FLAG_ESC_GLOB_CHARS = 0x1,
 };
-enum {
-	MAYBE_ASSIGNMENT      = 0,
-	DEFINITELY_ASSIGNMENT = 1,
-	NOT_ASSIGNMENT        = 2,
-	/* Not an assignment, but next word may be: "if v=xyz cmd;" */
-	WORD_IS_KEYWORD       = 3,
-};
 /* Used for initialization: o_string foo = NULL_O_STRING; */
 #define NULL_O_STRING { NULL }
 
@@ -694,9 +686,11 @@ struct parse_context {
 	struct command *command;
 	/* last redirect in command->redirects list */
 	struct redir_struct *pending_redirect;
+	o_string word;
 #if !BB_MMU
 	o_string as_string;
 #endif
+	smallint is_assignment; /* 0:maybe, 1:yes, 2:no, 3:keyword */
 #if HAS_KEYWORDS
 	smallint ctx_res_w;
 	smallint ctx_inverted; /* "! cmd | cmd" */
@@ -717,6 +711,13 @@ struct parse_context {
 	struct parse_context *stack;
 #endif
 };
+enum {
+	MAYBE_ASSIGNMENT      = 0,
+	DEFINITELY_ASSIGNMENT = 1,
+	NOT_ASSIGNMENT        = 2,
+	/* Not an assignment, but next word may be: "if v=xyz cmd;" */
+	WORD_IS_KEYWORD       = 3,
+};
 
 /* On program start, environ points to initial environment.
  * putenv adds new pointers into it, unsetenv removes them.
@@ -3671,6 +3672,8 @@ static void done_pipe(struct parse_context *ctx, pipe_style type)
 static void initialize_context(struct parse_context *ctx)
 {
 	memset(ctx, 0, sizeof(*ctx));
+	if (MAYBE_ASSIGNMENT != 0)
+		ctx->is_assignment = MAYBE_ASSIGNMENT;
 	ctx->pipe = ctx->list_head = new_pipe();
 	/* Create the memory for command, roughly:
 	 * ctx->pipe->cmds = new struct command;
@@ -3752,7 +3755,7 @@ static const struct reserved_combo* match_reserved_word(o_string *word)
 }
 /* Return NULL: not a keyword, else: keyword
  */
-static const struct reserved_combo* reserved_word(o_string *word, struct parse_context *ctx)
+static const struct reserved_combo* reserved_word(struct parse_context *ctx)
 {
 # if ENABLE_HUSH_CASE
 	static const struct reserved_combo reserved_match = {
@@ -3761,9 +3764,9 @@ static const struct reserved_combo* reserved_word(o_string *word, struct parse_c
 # endif
 	const struct reserved_combo *r;
 
-	if (word->has_quoted_part)
+	if (ctx->word.has_quoted_part)
 		return 0;
-	r = match_reserved_word(word);
+	r = match_reserved_word(&ctx->word);
 	if (!r)
 		return r; /* NULL */
 
@@ -3790,7 +3793,7 @@ static const struct reserved_combo* reserved_word(o_string *word, struct parse_c
 		initialize_context(ctx);
 		ctx->stack = old;
 	} else if (/*ctx->ctx_res_w == RES_NONE ||*/ !(ctx->old_flag & (1 << r->res))) {
-		syntax_error_at(word->data);
+		syntax_error_at(ctx->word.data);
 		ctx->ctx_res_w = RES_SNTX;
 		return r;
 	} else {
@@ -3803,8 +3806,8 @@ static const struct reserved_combo* reserved_word(o_string *word, struct parse_c
 
 	ctx->ctx_res_w = r->res;
 	ctx->old_flag = r->flag;
-	word->o_assignment = r->assignment_flag;
-	debug_printf_parse("word->o_assignment='%s'\n", assignment_flag[word->o_assignment]);
+	ctx->is_assignment = r->assignment_flag;
+	debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
 
 	if (ctx->old_flag & FLAG_END) {
 		struct parse_context *old;
@@ -3850,12 +3853,12 @@ static const struct reserved_combo* reserved_word(o_string *word, struct parse_c
  * Normal return is 0. Syntax errors return 1.
  * Note: on return, word is reset, but not o_free'd!
  */
-static int done_word(o_string *word, struct parse_context *ctx)
+static int done_word(struct parse_context *ctx)
 {
 	struct command *command = ctx->command;
 
-	debug_printf_parse("done_word entered: '%s' %p\n", word->data, command);
-	if (word->length == 0 && !word->has_quoted_part) {
+	debug_printf_parse("done_word entered: '%s' %p\n", ctx->word.data, command);
+	if (ctx->word.length == 0 && !ctx->word.has_quoted_part) {
 		debug_printf_parse("done_word return 0: true null, ignored\n");
 		return 0;
 	}
@@ -3885,7 +3888,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
 // <<EOF$((1))
 // <<EOF`true`  [this case also makes heredoc "quoted", a-la <<"EOF". Probably bash-4.3.43 bug]
 
-		ctx->pending_redirect->rd_filename = xstrdup(word->data);
+		ctx->pending_redirect->rd_filename = xstrdup(ctx->word.data);
 		/* Cater for >\file case:
 		 * >\a creates file a; >\\a, >"\a", >"\\a" create file \a
 		 * Same with heredocs:
@@ -3894,17 +3897,17 @@ static int done_word(o_string *word, struct parse_context *ctx)
 		if (ctx->pending_redirect->rd_type == REDIRECT_HEREDOC) {
 			unbackslash(ctx->pending_redirect->rd_filename);
 			/* Is it <<"HEREDOC"? */
-			if (word->has_quoted_part) {
+			if (ctx->word.has_quoted_part) {
 				ctx->pending_redirect->rd_dup |= HEREDOC_QUOTED;
 			}
 		}
-		debug_printf_parse("word stored in rd_filename: '%s'\n", word->data);
+		debug_printf_parse("word stored in rd_filename: '%s'\n", ctx->word.data);
 		ctx->pending_redirect = NULL;
 	} else {
 #if HAS_KEYWORDS
 # if ENABLE_HUSH_CASE
 		if (ctx->ctx_dsemicolon
-		 && strcmp(word->data, "esac") != 0 /* not "... pattern) cmd;; esac" */
+		 && strcmp(ctx->word.data, "esac") != 0 /* not "... pattern) cmd;; esac" */
 		) {
 			/* already done when ctx_dsemicolon was set to 1: */
 			/* ctx->ctx_res_w = RES_MATCH; */
@@ -3921,7 +3924,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
 # endif
 		) {
 			const struct reserved_combo *reserved;
-			reserved = reserved_word(word, ctx);
+			reserved = reserved_word(ctx);
 			debug_printf_parse("checking for reserved-ness: %d\n", !!reserved);
 			if (reserved) {
 # if ENABLE_HUSH_LINENO_VAR
@@ -3940,7 +3943,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
 					done_pipe(ctx, PIPE_SEQ);
 				}
 # endif
-				o_reset_to_empty_unquoted(word);
+				o_reset_to_empty_unquoted(&ctx->word);
 				debug_printf_parse("done_word return %d\n",
 						(ctx->ctx_res_w == RES_SNTX));
 				return (ctx->ctx_res_w == RES_SNTX);
@@ -3948,7 +3951,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
 # if defined(CMD_SINGLEWORD_NOGLOB)
 			if (0
 #  if BASH_TEST2
-			 || strcmp(word->data, "[[") == 0
+			 || strcmp(ctx->word.data, "[[") == 0
 #  endif
 			/* In bash, local/export/readonly are special, args
 			 * are assignments and therefore expansion of them
@@ -3965,9 +3968,9 @@ static int done_word(o_string *word, struct parse_context *ctx)
 			 *  $ "export" i=`echo 'aaa  bbb'`; echo "$i"
 			 *  aaa
 			 */
-			IF_HUSH_LOCAL(    || strcmp(word->data, "local") == 0)
-			IF_HUSH_EXPORT(   || strcmp(word->data, "export") == 0)
-			IF_HUSH_READONLY( || strcmp(word->data, "readonly") == 0)
+			 IF_HUSH_LOCAL(   || strcmp(ctx->word.data, "local") == 0)
+			 IF_HUSH_EXPORT(  || strcmp(ctx->word.data, "export") == 0)
+			 IF_HUSH_READONLY(|| strcmp(ctx->word.data, "readonly") == 0)
 			) {
 				command->cmd_type = CMD_SINGLEWORD_NOGLOB;
 			}
@@ -3978,7 +3981,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
 
 		if (command->group) {
 			/* "{ echo foo; } echo bar" - bad */
-			syntax_error_at(word->data);
+			syntax_error_at(ctx->word.data);
 			debug_printf_parse("done_word return 1: syntax error, "
 					"groups and arglists don't mix\n");
 			return 1;
@@ -3986,26 +3989,26 @@ static int done_word(o_string *word, struct parse_context *ctx)
 
 		/* If this word wasn't an assignment, next ones definitely
 		 * can't be assignments. Even if they look like ones. */
-		if (word->o_assignment != DEFINITELY_ASSIGNMENT
-		 && word->o_assignment != WORD_IS_KEYWORD
+		if (ctx->is_assignment != DEFINITELY_ASSIGNMENT
+		 && ctx->is_assignment != WORD_IS_KEYWORD
 		) {
-			word->o_assignment = NOT_ASSIGNMENT;
+			ctx->is_assignment = NOT_ASSIGNMENT;
 		} else {
-			if (word->o_assignment == DEFINITELY_ASSIGNMENT) {
+			if (ctx->is_assignment == DEFINITELY_ASSIGNMENT) {
 				command->assignment_cnt++;
 				debug_printf_parse("++assignment_cnt=%d\n", command->assignment_cnt);
 			}
-			debug_printf_parse("word->o_assignment was:'%s'\n", assignment_flag[word->o_assignment]);
-			word->o_assignment = MAYBE_ASSIGNMENT;
+			debug_printf_parse("ctx->is_assignment was:'%s'\n", assignment_flag[ctx->is_assignment]);
+			ctx->is_assignment = MAYBE_ASSIGNMENT;
 		}
-		debug_printf_parse("word->o_assignment='%s'\n", assignment_flag[word->o_assignment]);
-		command->argv = add_string_to_strings(command->argv, xstrdup(word->data));
+		debug_printf_parse("ctx->is_assignment='%s'\n", assignment_flag[ctx->is_assignment]);
+		command->argv = add_string_to_strings(command->argv, xstrdup(ctx->word.data));
 		debug_print_strings("word appended to argv", command->argv);
 	}
 
 #if ENABLE_HUSH_LOOPS
 	if (ctx->ctx_res_w == RES_FOR) {
-		if (word->has_quoted_part
+		if (ctx->word.has_quoted_part
 		 || !is_well_formed_var_name(command->argv[0], '\0')
 		) {
 			/* bash says just "not a valid identifier" */
@@ -4026,7 +4029,7 @@ static int done_word(o_string *word, struct parse_context *ctx)
 	}
 #endif
 
-	o_reset_to_empty_unquoted(word);
+	o_reset_to_empty_unquoted(&ctx->word);
 
 	debug_printf_parse("done_word return 0\n");
 	return 0;
@@ -4310,14 +4313,10 @@ static struct pipe *parse_stream(char **pstring,
 		int end_trigger);
 
 
-#if !ENABLE_HUSH_FUNCTIONS
-#define parse_group(dest, ctx, input, ch) \
-	parse_group(ctx, input, ch)
-#endif
-static int parse_group(o_string *dest, struct parse_context *ctx,
+static int parse_group(struct parse_context *ctx,
 	struct in_str *input, int ch)
 {
-	/* dest contains characters seen prior to ( or {.
+	/* ctx->word contains characters seen prior to ( or {.
 	 * Typically it's empty, but for function defs,
 	 * it contains function name (without '()'). */
 #if BB_MMU
@@ -4331,9 +4330,9 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
 
 	debug_printf_parse("parse_group entered\n");
 #if ENABLE_HUSH_FUNCTIONS
-	if (ch == '(' && !dest->has_quoted_part) {
-		if (dest->length)
-			if (done_word(dest, ctx))
+	if (ch == '(' && !ctx->word.has_quoted_part) {
+		if (ctx->word.length)
+			if (done_word(ctx))
 				return 1;
 		if (!command->argv)
 			goto skip; /* (... */
@@ -4365,8 +4364,8 @@ static int parse_group(o_string *dest, struct parse_context *ctx,
 
 #if 0 /* Prevented by caller */
 	if (command->argv /* word [word]{... */
-	 || dest->length /* word{... */
-	 || dest->has_quoted_part /* ""{... */
+	 || ctx->word.length /* word{... */
+	 || ctx->word.has_quoted_part /* ""{... */
 	) {
 		syntax_error(NULL);
 		debug_printf_parse("parse_group return 1: "
@@ -4972,29 +4971,28 @@ static struct pipe *parse_stream(char **pstring,
 		int end_trigger)
 {
 	struct parse_context ctx;
-	o_string dest = NULL_O_STRING;
 	int heredoc_cnt;
 
 	/* Single-quote triggers a bypass of the main loop until its mate is
-	 * found.  When recursing, quote state is passed in via dest->o_expflags.
+	 * found.  When recursing, quote state is passed in via ctx.word.o_expflags.
 	 */
 	debug_printf_parse("parse_stream entered, end_trigger='%c'\n",
 			end_trigger ? end_trigger : 'X');
 	debug_enter();
 
-	/* If very first arg is "" or '', dest.data may end up NULL.
-	 * Preventing this: */
-	o_addchr(&dest, '\0');
-	dest.length = 0;
+	initialize_context(&ctx);
+
+	/* If very first arg is "" or '', ctx.word.data may end up NULL.
+	 * Preventing this:
+	 */
+	o_addchr(&ctx.word, '\0');
+	ctx.word.length = 0;
 
 	/* We used to separate words on $IFS here. This was wrong.
 	 * $IFS is used only for word splitting when $var is expanded,
 	 * here we should use blank chars as separators, not $IFS
 	 */
 
-	if (MAYBE_ASSIGNMENT != 0)
-		dest.o_assignment = MAYBE_ASSIGNMENT;
-	initialize_context(&ctx);
 	heredoc_cnt = 0;
 	while (1) {
 		const char *is_blank;
@@ -5006,7 +5004,7 @@ static struct pipe *parse_stream(char **pstring,
 
 		ch = i_getch(input);
 		debug_printf_parse(": ch=%c (%d) escape=%d\n",
-				ch, ch, !!(dest.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
+				ch, ch, !!(ctx.word.o_expflags & EXP_FLAG_ESC_GLOB_CHARS));
 		if (ch == EOF) {
 			struct pipe *pi;
 
@@ -5023,10 +5021,10 @@ static struct pipe *parse_stream(char **pstring,
 				goto parse_error;
 			}
 
-			if (done_word(&dest, &ctx)) {
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
-			o_free(&dest);
+			o_free(&ctx.word);
 			done_pipe(&ctx, PIPE_SEQ);
 			pi = ctx.list_head;
 			/* If we got nothing... */
@@ -5066,8 +5064,8 @@ static struct pipe *parse_stream(char **pstring,
 				SPECIAL_VAR_SYMBOL_STR;
 		/* Are { and } special here? */
 		if (ctx.command->argv /* word [word]{... - non-special */
-		 || dest.length       /* word{... - non-special */
-		 || dest.has_quoted_part     /* ""{... - non-special */
+		 || ctx.word.length       /* word{... - non-special */
+		 || ctx.word.has_quoted_part     /* ""{... - non-special */
 		 || (next != ';'             /* }; - special */
 		    && next != ')'           /* }) - special */
 		    && next != '('           /* {( - special */
@@ -5084,14 +5082,14 @@ static struct pipe *parse_stream(char **pstring,
 
 		if (!is_special && !is_blank) { /* ordinary char */
  ordinary_char:
-			o_addQchr(&dest, ch);
-			if ((dest.o_assignment == MAYBE_ASSIGNMENT
-			    || dest.o_assignment == WORD_IS_KEYWORD)
+			o_addQchr(&ctx.word, ch);
+			if ((ctx.is_assignment == MAYBE_ASSIGNMENT
+			    || ctx.is_assignment == WORD_IS_KEYWORD)
 			 && ch == '='
-			 && is_well_formed_var_name(dest.data, '=')
+			 && is_well_formed_var_name(ctx.word.data, '=')
 			) {
-				dest.o_assignment = DEFINITELY_ASSIGNMENT;
-				debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
+				ctx.is_assignment = DEFINITELY_ASSIGNMENT;
+				debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
 			}
 			continue;
 		}
@@ -5113,7 +5111,7 @@ static struct pipe *parse_stream(char **pstring,
 			}
 			/* ch == last eaten whitespace char */
 #endif
-			if (done_word(&dest, &ctx)) {
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
 			if (ch == '\n') {
@@ -5123,7 +5121,7 @@ static struct pipe *parse_stream(char **pstring,
 				 * "case ... in <newline> word) ..."
 				 */
 				if (IS_NULL_CMD(ctx.command)
-				 && dest.length == 0 && !dest.has_quoted_part
+				 && ctx.word.length == 0 && !ctx.word.has_quoted_part
 				) {
 					/* This newline can be ignored. But...
 					 * Without check #1, interactive shell
@@ -5158,8 +5156,8 @@ static struct pipe *parse_stream(char **pstring,
 					}
 					heredoc_cnt = 0;
 				}
-				dest.o_assignment = MAYBE_ASSIGNMENT;
-				debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
+				ctx.is_assignment = MAYBE_ASSIGNMENT;
+				debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
 				ch = ';';
 				/* note: if (is_blank) continue;
 				 * will still trigger for us */
@@ -5171,8 +5169,8 @@ static struct pipe *parse_stream(char **pstring,
 		 * Pathological example: { ""}; } should exec "}" cmd
 		 */
 		if (ch == '}') {
-			if (dest.length != 0 /* word} */
-			 || dest.has_quoted_part    /* ""} */
+			if (ctx.word.length != 0 /* word} */
+			 || ctx.word.has_quoted_part    /* ""} */
 			) {
 				goto ordinary_char;
 			}
@@ -5201,7 +5199,7 @@ static struct pipe *parse_stream(char **pstring,
 #if ENABLE_HUSH_CASE
 		 && (ch != ')'
 		    || ctx.ctx_res_w != RES_MATCH
-		    || (!dest.has_quoted_part && strcmp(dest.data, "esac") == 0)
+		    || (!ctx.word.has_quoted_part && strcmp(ctx.word.data, "esac") == 0)
 		    )
 #endif
 		) {
@@ -5218,17 +5216,17 @@ static struct pipe *parse_stream(char **pstring,
 				syntax_error_unterm_str("here document");
 				goto parse_error;
 			}
-			if (done_word(&dest, &ctx)) {
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
 			done_pipe(&ctx, PIPE_SEQ);
-			dest.o_assignment = MAYBE_ASSIGNMENT;
-			debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
+			ctx.is_assignment = MAYBE_ASSIGNMENT;
+			debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
 			/* Do we sit outside of any if's, loops or case's? */
 			if (!HAS_KEYWORDS
 			IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0))
 			) {
-				o_free(&dest);
+				o_free(&ctx.word);
 #if !BB_MMU
 				debug_printf_parse("as_string2 '%s'\n", ctx.as_string.data);
 				if (pstring)
@@ -5257,8 +5255,8 @@ static struct pipe *parse_stream(char **pstring,
 		 * an assignment. a=1 2>z b=2: b=2 is still assignment */
 		switch (ch) {
 		case '>':
-			redir_fd = redirect_opt_num(&dest);
-			if (done_word(&dest, &ctx)) {
+			redir_fd = redirect_opt_num(&ctx.word);
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
 			redir_style = REDIRECT_OVERWRITE;
@@ -5279,8 +5277,8 @@ static struct pipe *parse_stream(char **pstring,
 				goto parse_error;
 			continue; /* back to top of while (1) */
 		case '<':
-			redir_fd = redirect_opt_num(&dest);
-			if (done_word(&dest, &ctx)) {
+			redir_fd = redirect_opt_num(&ctx.word);
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
 			redir_style = REDIRECT_INPUT;
@@ -5307,7 +5305,7 @@ static struct pipe *parse_stream(char **pstring,
 				goto parse_error;
 			continue; /* back to top of while (1) */
 		case '#':
-			if (dest.length == 0 && !dest.has_quoted_part) {
+			if (ctx.word.length == 0 && !ctx.word.has_quoted_part) {
 				/* skip "#comment" */
 				/* note: we do not add it to &ctx.as_string */
 /* TODO: in bash:
@@ -5342,14 +5340,14 @@ static struct pipe *parse_stream(char **pstring,
 			break;
 		}
 
-		if (dest.o_assignment == MAYBE_ASSIGNMENT
+		if (ctx.is_assignment == MAYBE_ASSIGNMENT
 		 /* check that we are not in word in "a=1 2>word b=1": */
 		 && !ctx.pending_redirect
 		) {
 			/* ch is a special char and thus this word
 			 * cannot be an assignment */
-			dest.o_assignment = NOT_ASSIGNMENT;
-			debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
+			ctx.is_assignment = NOT_ASSIGNMENT;
+			debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
 		}
 
 		/* Note: nommu_addchr(&ctx.as_string, ch) is already done */
@@ -5357,12 +5355,12 @@ static struct pipe *parse_stream(char **pstring,
 		switch (ch) {
 		case SPECIAL_VAR_SYMBOL:
 			/* Convert raw ^C to corresponding special variable reference */
-			o_addchr(&dest, SPECIAL_VAR_SYMBOL);
-			o_addchr(&dest, SPECIAL_VAR_QUOTED_SVS);
+			o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
+			o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
 			/* fall through */
 		case '#':
 			/* non-comment #: "echo a#b" etc */
-			o_addchr(&dest, ch);
+			o_addchr(&ctx.word, ch);
 			break;
 		case '\\':
 			if (next == EOF) {
@@ -5371,29 +5369,29 @@ static struct pipe *parse_stream(char **pstring,
 			}
 			ch = i_getch(input);
 			/* note: ch != '\n' (that case does not reach this place) */
-			o_addchr(&dest, '\\');
+			o_addchr(&ctx.word, '\\');
 			/*nommu_addchr(&ctx.as_string, '\\'); - already done */
-			o_addchr(&dest, ch);
+			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 */
-			dest.has_quoted_part = 1;
+			ctx.word.has_quoted_part = 1;
 			break;
 		case '$':
-			if (!parse_dollar(&ctx.as_string, &dest, input, /*quote_mask:*/ 0)) {
+			if (!parse_dollar(&ctx.as_string, &ctx.word, input, /*quote_mask:*/ 0)) {
 				debug_printf_parse("parse_stream parse error: "
 					"parse_dollar returned 0 (error)\n");
 				goto parse_error;
 			}
 			break;
 		case '\'':
-			dest.has_quoted_part = 1;
+			ctx.word.has_quoted_part = 1;
 			if (next == '\'' && !ctx.pending_redirect) {
  insert_empty_quoted_str_marker:
 				nommu_addchr(&ctx.as_string, next);
 				i_getch(input); /* eat second ' */
-				o_addchr(&dest, SPECIAL_VAR_SYMBOL);
-				o_addchr(&dest, SPECIAL_VAR_SYMBOL);
+				o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
+				o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
 			} else {
 				while (1) {
 					ch = i_getch(input);
@@ -5406,38 +5404,38 @@ static struct pipe *parse_stream(char **pstring,
 						break;
 					if (ch == SPECIAL_VAR_SYMBOL) {
 						/* Convert raw ^C to corresponding special variable reference */
-						o_addchr(&dest, SPECIAL_VAR_SYMBOL);
-						o_addchr(&dest, SPECIAL_VAR_QUOTED_SVS);
+						o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
+						o_addchr(&ctx.word, SPECIAL_VAR_QUOTED_SVS);
 					}
-					o_addqchr(&dest, ch);
+					o_addqchr(&ctx.word, ch);
 				}
 			}
 			break;
 		case '"':
-			dest.has_quoted_part = 1;
+			ctx.word.has_quoted_part = 1;
 			if (next == '"' && !ctx.pending_redirect)
 				goto insert_empty_quoted_str_marker;
-			if (dest.o_assignment == NOT_ASSIGNMENT)
-				dest.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS;
-			if (!encode_string(&ctx.as_string, &dest, input, '"', /*process_bkslash:*/ 1))
+			if (ctx.is_assignment == NOT_ASSIGNMENT)
+				ctx.word.o_expflags |= EXP_FLAG_ESC_GLOB_CHARS;
+			if (!encode_string(&ctx.as_string, &ctx.word, input, '"', /*process_bkslash:*/ 1))
 				goto parse_error;
-			dest.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS;
+			ctx.word.o_expflags &= ~EXP_FLAG_ESC_GLOB_CHARS;
 			break;
 #if ENABLE_HUSH_TICK
 		case '`': {
 			USE_FOR_NOMMU(unsigned pos;)
 
-			o_addchr(&dest, SPECIAL_VAR_SYMBOL);
-			o_addchr(&dest, '`');
-			USE_FOR_NOMMU(pos = dest.length;)
-			if (!add_till_backquote(&dest, input, /*in_dquote:*/ 0))
+			o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
+			o_addchr(&ctx.word, '`');
+			USE_FOR_NOMMU(pos = ctx.word.length;)
+			if (!add_till_backquote(&ctx.word, input, /*in_dquote:*/ 0))
 				goto parse_error;
 # if !BB_MMU
-			o_addstr(&ctx.as_string, dest.data + pos);
+			o_addstr(&ctx.as_string, ctx.word.data + pos);
 			o_addchr(&ctx.as_string, '`');
 # endif
-			o_addchr(&dest, SPECIAL_VAR_SYMBOL);
-			//debug_printf_subst("SUBST RES3 '%s'\n", dest.data + pos);
+			o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
+			//debug_printf_subst("SUBST RES3 '%s'\n", ctx.word.data + pos);
 			break;
 		}
 #endif
@@ -5445,7 +5443,7 @@ static struct pipe *parse_stream(char **pstring,
 #if ENABLE_HUSH_CASE
  case_semi:
 #endif
-			if (done_word(&dest, &ctx)) {
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
 			done_pipe(&ctx, PIPE_SEQ);
@@ -5468,11 +5466,11 @@ static struct pipe *parse_stream(char **pstring,
  new_cmd:
 			/* We just finished a cmd. New one may start
 			 * with an assignment */
-			dest.o_assignment = MAYBE_ASSIGNMENT;
-			debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]);
+			ctx.is_assignment = MAYBE_ASSIGNMENT;
+			debug_printf_parse("ctx.is_assignment='%s'\n", assignment_flag[ctx.is_assignment]);
 			break;
 		case '&':
-			if (done_word(&dest, &ctx)) {
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
 			if (next == '\\')
@@ -5486,7 +5484,7 @@ static struct pipe *parse_stream(char **pstring,
 			}
 			goto new_cmd;
 		case '|':
-			if (done_word(&dest, &ctx)) {
+			if (done_word(&ctx)) {
 				goto parse_error;
 			}
 #if ENABLE_HUSH_CASE
@@ -5511,14 +5509,14 @@ static struct pipe *parse_stream(char **pstring,
 			/* "case... in [(]word)..." - skip '(' */
 			if (ctx.ctx_res_w == RES_MATCH
 			 && ctx.command->argv == NULL /* not (word|(... */
-			 && dest.length == 0 /* not word(... */
-			 && dest.has_quoted_part == 0 /* not ""(... */
+			 && ctx.word.length == 0 /* not word(... */
+			 && ctx.word.has_quoted_part == 0 /* not ""(... */
 			) {
 				continue;
 			}
 #endif
 		case '{':
-			if (parse_group(&dest, &ctx, input, ch) != 0) {
+			if (parse_group(&ctx, input, ch) != 0) {
 				goto parse_error;
 			}
 			goto new_cmd;
@@ -5575,7 +5573,7 @@ static struct pipe *parse_stream(char **pstring,
 			IF_HAS_KEYWORDS(pctx = p2;)
 		} while (HAS_KEYWORDS && pctx);
 
-		o_free(&dest);
+		o_free(&ctx.word);
 #if !BB_MMU
 		if (pstring)
 			*pstring = NULL;


More information about the busybox-cvs mailing list