From 219e88d0505f9c06d42772333995887ca694465a Mon Sep 17 00:00:00 2001
From: Denis Vlasenko <vda.linux@googlemail.com>
Date: Mon, 21 May 2007 10:18:23 +0000
Subject: hush: using smallints where we can. save ~20 bytes in code and some
 data storage at runtime.

---
 shell/hush.c | 97 +++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 50 insertions(+), 47 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index 107b821f8..90c89fba2 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -137,9 +137,10 @@ static const char *indenter(int i)
 #endif
 
 #define SPECIAL_VAR_SYMBOL   3
-#define FLAG_EXIT_FROM_LOOP  1
-#define FLAG_PARSE_SEMICOLON (1 << 1)		/* symbol ';' is special for parser */
-#define FLAG_REPARSING	     (1 << 2)		/* >= 2nd pass */
+
+#define PARSEFLAG_EXIT_FROM_LOOP 1
+#define PARSEFLAG_SEMICOLON      (1 << 1)  /* symbol ';' is special for parser */
+#define PARSEFLAG_REPARSING      (1 << 2)  /* >= 2nd pass */
 
 typedef enum {
 	REDIRECT_INPUT     = 1,
@@ -210,10 +211,10 @@ struct p_context {
 	struct pipe *list_head;
 	struct pipe *pipe;
 	struct redir_struct *pending_redirect;
-	reserved_style res_w;
-	int old_flag;           /* for figuring out valid reserved words */
+	smallint res_w;
+	smallint parse_type;        /* bitmask of PARSEFLAG_xxx, defines type of parser : ";$" common or special symbol */
+	int old_flag;               /* bitmask of FLAG_xxx, for figuring out valid reserved words */
 	struct p_context *stack;
-	int parse_type;         /* define type of parser : ";$" common or special symbol */
 	/* How about quoting status? */
 };
 
@@ -249,17 +250,17 @@ struct pipe {
 	struct pipe *next;
 	int num_progs;              /* total number of programs in job */
 	int running_progs;          /* number of programs running (not exited) */
-	char *cmdbuf;               /* buffer various argv's point into */
+	int stopped_progs;          /* number of programs alive, but stopped */
 #if ENABLE_HUSH_JOB
 	int jobid;                  /* job number */
-	char *cmdtext;              /* name of job */
 	pid_t pgrp;                 /* process group ID for the job */
+	char *cmdtext;              /* name of job */
 #endif
+	char *cmdbuf;               /* buffer various argv's point into */
 	struct child_prog *progs;   /* array of commands in pipe */
-	int stopped_progs;          /* number of programs alive, but stopped */
 	int job_context;            /* bitmask defining current context */
-	pipe_style followup;        /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
-	reserved_style r_mode;      /* supports if, for, while, until */
+	smallint followup;          /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
+	smallint res_word;          /* needed for if, for, while, until... */
 };
 
 struct close_me {
@@ -271,8 +272,8 @@ struct variables {
 	struct variables *next;
 	const char *name;
 	const char *value;
-	int flg_export;
-	int flg_read_only;
+	smallint flg_export;
+	smallint flg_read_only;
 };
 
 typedef struct {
@@ -703,8 +704,8 @@ static int builtin_eval(char **argv)
 
 	if (argv[1]) {
 		str = make_string(argv + 1);
-		parse_string_outer(str, FLAG_EXIT_FROM_LOOP |
-					FLAG_PARSE_SEMICOLON);
+		parse_string_outer(str, PARSEFLAG_EXIT_FROM_LOOP |
+					PARSEFLAG_SEMICOLON);
 		free(str);
 		rcode = last_return_code;
 	}
@@ -1897,10 +1898,11 @@ static void debug_print_tree(struct pipe *pi, int lvl)
 	};
 
 	int pin, prn;
+
 	pin = 0;
 	while (pi) {
-		fprintf(stderr, "%*spipe %d r_mode=%s followup=%d %s\n", lvl*2, "",
-				pin, RES[pi->r_mode], pi->followup, PIPE[pi->followup]);
+		fprintf(stderr, "%*spipe %d res_word=%s followup=%d %s\n", lvl*2, "",
+				pin, RES[pi->res_word], pi->followup, PIPE[pi->followup]);
 		prn = 0;
 		while (prn < pi->num_progs) {
 			struct child_prog *child = &pi->progs[prn];
@@ -1942,21 +1944,22 @@ static int run_list_real(struct pipe *pi)
 	int rcode = 0; /* probably for gcc only */
 	int flag_restore = 0;
 	int if_code = 0, next_if_code = 0;  /* need double-buffer to handle elif */
-	reserved_style rmode, skip_more_in_this_rmode = RES_XXXX;
+	reserved_style rword;
+	reserved_style skip_more_for_this_rword = RES_XXXX;
 
 	debug_printf_exec("run_list_real start lvl %d\n", run_list_level + 1);
 
 	/* check syntax for "for" */
 	for (rpipe = pi; rpipe; rpipe = rpipe->next) {
-		if ((rpipe->r_mode == RES_IN || rpipe->r_mode == RES_FOR)
+		if ((rpipe->res_word == RES_IN || rpipe->res_word == RES_FOR)
 		 && (rpipe->next == NULL)
 		) {
 			syntax(); /* unterminated FOR (no IN or no commands after IN) */
 			debug_printf_exec("run_list_real lvl %d return 1\n", run_list_level);
 			return 1;
 		}
-		if ((rpipe->r_mode == RES_IN &&	rpipe->next->r_mode == RES_IN && rpipe->next->progs[0].argv != NULL)
-		 || (rpipe->r_mode == RES_FOR && rpipe->next->r_mode != RES_IN)
+		if ((rpipe->res_word == RES_IN && rpipe->next->res_word == RES_IN && rpipe->next->progs[0].argv != NULL)
+		 || (rpipe->res_word == RES_FOR && rpipe->next->res_word != RES_IN)
 		) {
 			/* TODO: what is tested in the first condition? */
 			syntax(); /* 2nd: malformed FOR (not followed by IN) */
@@ -2008,32 +2011,32 @@ static int run_list_real(struct pipe *pi)
 #endif
 
 	for (; pi; pi = flag_restore ? rpipe : pi->next) {
-		rmode = pi->r_mode;
-		if (rmode == RES_WHILE || rmode == RES_UNTIL || rmode == RES_FOR) {
+		rword = pi->res_word;
+		if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) {
 			flag_restore = 0;
 			if (!rpipe) {
 				flag_rep = 0;
 				rpipe = pi;
 			}
 		}
-		debug_printf_exec(": rmode=%d if_code=%d next_if_code=%d skip_more=%d\n",
-				rmode, if_code, next_if_code, skip_more_in_this_rmode);
-		if (rmode == skip_more_in_this_rmode && flag_skip) {
+		debug_printf_exec(": rword=%d if_code=%d next_if_code=%d skip_more=%d\n",
+				rword, if_code, next_if_code, skip_more_for_this_rword);
+		if (rword == skip_more_for_this_rword && flag_skip) {
 			if (pi->followup == PIPE_SEQ)
 				flag_skip = 0;
 			continue;
 		}
 		flag_skip = 1;
-		skip_more_in_this_rmode = RES_XXXX;
-		if (rmode == RES_THEN || rmode == RES_ELSE)
+		skip_more_for_this_rword = RES_XXXX;
+		if (rword == RES_THEN || rword == RES_ELSE)
 			if_code = next_if_code;
-		if (rmode == RES_THEN && if_code)
+		if (rword == RES_THEN && if_code)
 			continue;
-		if (rmode == RES_ELSE && !if_code)
+		if (rword == RES_ELSE && !if_code)
 			continue;
-		if (rmode == RES_ELIF && !if_code)
+		if (rword == RES_ELIF && !if_code)
 			break;
-		if (rmode == RES_FOR && pi->num_progs) {
+		if (rword == RES_FOR && pi->num_progs) {
 			if (!for_lcur) {
 				/* if no variable values after "in" we skip "for" */
 				if (!pi->next->progs->argv)
@@ -2059,13 +2062,13 @@ static int run_list_real(struct pipe *pi)
 			pi->progs->argv[0] = xasprintf("%s=%s", for_varname, *for_lcur++);
 			pi->progs->glob_result.gl_pathv[0] = pi->progs->argv[0];
 		}
-		if (rmode == RES_IN)
+		if (rword == RES_IN)
 			continue;
-		if (rmode == RES_DO) {
+		if (rword == RES_DO) {
 			if (!flag_rep)
 				continue;
 		}
-		if (rmode == RES_DONE) {
+		if (rword == RES_DONE) {
 			if (flag_rep) {
 				flag_restore = 1;
 			} else {
@@ -2107,16 +2110,16 @@ static int run_list_real(struct pipe *pi)
 		debug_printf_exec(": setting last_return_code=%d\n", rcode);
 		last_return_code = rcode;
 		pi->num_progs = save_num_progs; /* restore number of programs */
-		if (rmode == RES_IF || rmode == RES_ELIF)
+		if (rword == RES_IF || rword == RES_ELIF)
 			next_if_code = rcode;  /* can be overwritten a number of times */
-		if (rmode == RES_WHILE)
+		if (rword == RES_WHILE)
 			flag_rep = !last_return_code;
-		if (rmode == RES_UNTIL)
+		if (rword == RES_UNTIL)
 			flag_rep = last_return_code;
 		if ((rcode == EXIT_SUCCESS && pi->followup == PIPE_OR)
 		 || (rcode != EXIT_SUCCESS && pi->followup == PIPE_AND)
 		) {
-			skip_more_in_this_rmode = rmode;
+			skip_more_for_this_rword = rword;
 		}
 		checkjobs(NULL);
 	}
@@ -2192,7 +2195,7 @@ static int free_pipe_list(struct pipe *head, int indent)
 	struct pipe *pi, *next;
 
 	for (pi = head; pi; pi = next) {
-		debug_printf_clean("%s pipe reserved mode %d\n", indenter(indent), pi->r_mode);
+		debug_printf_clean("%s pipe reserved mode %d\n", indenter(indent), pi->res_word);
 		rcode = free_pipe(pi, indent);
 		debug_printf_clean("%s pipe followup code %d\n", indenter(indent), pi->followup);
 		next = pi->next;
@@ -2786,7 +2789,7 @@ static struct pipe *new_pipe(void)
 	/*pi->next = NULL;*/
 	/*pi->followup = 0;  invalid */
 	if (RES_NONE)
-		pi->r_mode = RES_NONE;
+		pi->res_word = RES_NONE;
 	return pi;
 }
 
@@ -2898,7 +2901,7 @@ static int done_word(o_string *dest, struct p_context *ctx)
 			debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n");
 			return 1;
 		}
-		if (!child->argv && (ctx->parse_type & FLAG_PARSE_SEMICOLON)) {
+		if (!child->argv && (ctx->parse_type & PARSEFLAG_SEMICOLON)) {
 			debug_printf_parse(": checking '%s' for reserved-ness\n", dest->data);
 			if (reserved_word(dest, ctx)) {
 				debug_printf_parse("done_word return %d\n", (ctx->res_w == RES_SNTX));
@@ -2986,7 +2989,7 @@ static int done_pipe(struct p_context *ctx, pipe_style type)
 	debug_printf_parse("done_pipe entered, followup %d\n", type);
 	not_null = done_command(ctx);  /* implicit closure of previous command */
 	ctx->pipe->followup = type;
-	ctx->pipe->r_mode = ctx->res_w;
+	ctx->pipe->res_word = ctx->res_w;
 	/* Without this check, even just <enter> on command line generates
 	 * tree of three NOPs (!). Which is harmless but annoying.
 	 * IOW: it is safe to do it unconditionally. */
@@ -3510,7 +3513,7 @@ static int parse_stream_outer(struct in_str *inp, int parse_flag)
 		ctx.parse_type = parse_flag;
 		initialize_context(&ctx);
 		update_charmap();
-		if (!(parse_flag & FLAG_PARSE_SEMICOLON) || (parse_flag & FLAG_REPARSING))
+		if (!(parse_flag & PARSEFLAG_SEMICOLON) || (parse_flag & PARSEFLAG_REPARSING))
 			set_in_charmap(";$&|", CHAR_ORDINARY);
 #if ENABLE_HUSH_INTERACTIVE
 		inp->promptmode = 1;
@@ -3539,7 +3542,7 @@ static int parse_stream_outer(struct in_str *inp, int parse_flag)
 			free_pipe_list(ctx.list_head, 0);
 		}
 		b_free(&temp);
-	} while (rcode != -1 && !(parse_flag & FLAG_EXIT_FROM_LOOP));   /* loop on syntax errors, return on EOF */
+	} while (rcode != -1 && !(parse_flag & PARSEFLAG_EXIT_FROM_LOOP));   /* loop on syntax errors, return on EOF */
 	return 0;
 }
 
@@ -3555,7 +3558,7 @@ static int parse_file_outer(FILE *f)
 	int rcode;
 	struct in_str input;
 	setup_file_in_str(&input, f);
-	rcode = parse_stream_outer(&input, FLAG_PARSE_SEMICOLON);
+	rcode = parse_stream_outer(&input, PARSEFLAG_SEMICOLON);
 	return rcode;
 }
 
@@ -3646,7 +3649,7 @@ int hush_main(int argc, char **argv)
 		case 'c':
 			global_argv = argv + optind;
 			global_argc = argc - optind;
-			opt = parse_string_outer(optarg, FLAG_PARSE_SEMICOLON);
+			opt = parse_string_outer(optarg, PARSEFLAG_SEMICOLON);
 			goto final_return;
 		case 'i':
 			/* Well, we cannot just declare interactiveness,
-- 
cgit v1.2.3-55-g6feb