hush: using smallints where we can. save ~20 bytes in code and
authorDenis Vlasenko <vda.linux@googlemail.com>
Mon, 21 May 2007 10:18:23 +0000 (10:18 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Mon, 21 May 2007 10:18:23 +0000 (10:18 -0000)
some data storage at runtime.

shell/hush.c

index 107b821..90c89fb 100644 (file)
@@ -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,