diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-15 11:49:42 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-06-15 11:49:42 +0000 |
commit | 5703c22a51a154db17e6a7f6426a95232542cc9e (patch) | |
tree | ad29110cbcb1fea736fd9d949e15429ed8f8b9d4 | |
parent | ff7cd6f9250b352450bf811a1cc7bca75cc4e2b3 (diff) | |
download | busybox-w32-5703c22a51a154db17e6a7f6426a95232542cc9e.tar.gz busybox-w32-5703c22a51a154db17e6a7f6426a95232542cc9e.tar.bz2 busybox-w32-5703c22a51a154db17e6a7f6426a95232542cc9e.zip |
hush: eliminate PARSEFLAG_SEMICOLON and ctx->parse_type field.
function old new delta
parse_and_run_file 30 27 -3
hush_main 795 792 -3
initialize_context 45 39 -6
done_word 791 778 -13
parse_and_run_stream 375 338 -37
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/5 up/down: 0/-62) Total: -62 bytes
-rw-r--r-- | shell/hush.c | 49 |
1 files changed, 6 insertions, 43 deletions
diff --git a/shell/hush.c b/shell/hush.c index f4c170117..bc192b38b 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -178,11 +178,8 @@ void xxfree(void *ptr) | |||
178 | #endif | 178 | #endif |
179 | 179 | ||
180 | 180 | ||
181 | #define SPECIAL_VAR_SYMBOL 3 | 181 | #define SPECIAL_VAR_SYMBOL 3 |
182 | |||
183 | #define PARSEFLAG_EXIT_FROM_LOOP 1 | 182 | #define PARSEFLAG_EXIT_FROM_LOOP 1 |
184 | #define PARSEFLAG_SEMICOLON (1 << 1) /* symbol ';' is special for parser */ | ||
185 | #define PARSEFLAG_REPARSING (1 << 2) /* >= 2nd pass */ | ||
186 | 183 | ||
187 | typedef enum { | 184 | typedef enum { |
188 | REDIRECT_INPUT = 1, | 185 | REDIRECT_INPUT = 1, |
@@ -242,11 +239,9 @@ struct p_context { | |||
242 | struct pipe *pipe; | 239 | struct pipe *pipe; |
243 | struct redir_struct *pending_redirect; | 240 | struct redir_struct *pending_redirect; |
244 | smallint res_w; | 241 | smallint res_w; |
245 | smallint parse_type; /* bitmask of PARSEFLAG_xxx, defines type of parser: ";$" common or special symbol */ | ||
246 | smallint ctx_inverted; /* "! cmd | cmd" */ | 242 | smallint ctx_inverted; /* "! cmd | cmd" */ |
247 | int old_flag; /* bitmask of FLAG_xxx, for figuring out valid reserved words */ | 243 | int old_flag; /* bitmask of FLAG_xxx, for figuring out valid reserved words */ |
248 | struct p_context *stack; | 244 | struct p_context *stack; |
249 | /* How about quoting status? */ | ||
250 | }; | 245 | }; |
251 | 246 | ||
252 | struct redir_struct { | 247 | struct redir_struct { |
@@ -585,7 +580,6 @@ static void free_strings(char **strings) | |||
585 | } | 580 | } |
586 | } | 581 | } |
587 | 582 | ||
588 | |||
589 | #if !BB_MMU | 583 | #if !BB_MMU |
590 | #define EXTRA_PTRS 5 /* 1 for NULL, 1 for args, 3 for paranoid reasons */ | 584 | #define EXTRA_PTRS 5 /* 1 for NULL, 1 for args, 3 for paranoid reasons */ |
591 | static char **alloc_ptrs(char **argv) | 585 | static char **alloc_ptrs(char **argv) |
@@ -845,8 +839,7 @@ static int builtin_eval(char **argv) | |||
845 | 839 | ||
846 | if (argv[1]) { | 840 | if (argv[1]) { |
847 | char *str = expand_strvec_to_string(argv + 1); | 841 | char *str = expand_strvec_to_string(argv + 1); |
848 | parse_and_run_string(str, PARSEFLAG_EXIT_FROM_LOOP | | 842 | parse_and_run_string(str, PARSEFLAG_EXIT_FROM_LOOP); |
849 | PARSEFLAG_SEMICOLON); | ||
850 | free(str); | 843 | free(str); |
851 | rcode = last_return_code; | 844 | rcode = last_return_code; |
852 | } | 845 | } |
@@ -893,7 +886,6 @@ static int builtin_exit(char **argv) | |||
893 | //puts("exit"); /* bash does it */ | 886 | //puts("exit"); /* bash does it */ |
894 | // TODO: warn if we have background jobs: "There are stopped jobs" | 887 | // TODO: warn if we have background jobs: "There are stopped jobs" |
895 | // On second consecutive 'exit', exit anyway. | 888 | // On second consecutive 'exit', exit anyway. |
896 | |||
897 | if (argv[1] == NULL) | 889 | if (argv[1] == NULL) |
898 | hush_exit(last_return_code); | 890 | hush_exit(last_return_code); |
899 | /* mimic bash: exit 123abc == exit 255 + error msg */ | 891 | /* mimic bash: exit 123abc == exit 255 + error msg */ |
@@ -1139,12 +1131,6 @@ static int builtin_unset(char **argv) | |||
1139 | return EXIT_SUCCESS; | 1131 | return EXIT_SUCCESS; |
1140 | } | 1132 | } |
1141 | 1133 | ||
1142 | //static int builtin_not_written(char **argv) | ||
1143 | //{ | ||
1144 | // printf("builtin_%s not written\n", argv[0]); | ||
1145 | // return EXIT_FAILURE; | ||
1146 | //} | ||
1147 | |||
1148 | /* | 1134 | /* |
1149 | * o_string support | 1135 | * o_string support |
1150 | */ | 1136 | */ |
@@ -1635,12 +1621,6 @@ static void pseudo_exec(char **ptrs2free, struct child_prog *child) | |||
1635 | bb_error_msg_and_die("nested lists are not supported on NOMMU"); | 1621 | bb_error_msg_and_die("nested lists are not supported on NOMMU"); |
1636 | #else | 1622 | #else |
1637 | int rcode; | 1623 | int rcode; |
1638 | |||
1639 | #if ENABLE_HUSH_INTERACTIVE | ||
1640 | // run_list_level now takes care of it? | ||
1641 | // debug_printf_exec("pseudo_exec: setting interactive_fd=0\n"); | ||
1642 | // interactive_fd = 0; /* crucial!!!! */ | ||
1643 | #endif | ||
1644 | debug_printf_exec("pseudo_exec: run_list\n"); | 1624 | debug_printf_exec("pseudo_exec: run_list\n"); |
1645 | rcode = run_list(child->group); | 1625 | rcode = run_list(child->group); |
1646 | /* OK to leak memory by not calling free_pipe_list, | 1626 | /* OK to leak memory by not calling free_pipe_list, |
@@ -2263,7 +2243,6 @@ static int run_list(struct pipe *pi) | |||
2263 | #endif /* JOB */ | 2243 | #endif /* JOB */ |
2264 | 2244 | ||
2265 | for (; pi; pi = flag_restore ? rpipe : pi->next) { | 2245 | for (; pi; pi = flag_restore ? rpipe : pi->next) { |
2266 | //why? int save_num_progs; | ||
2267 | rword = pi->res_word; | 2246 | rword = pi->res_word; |
2268 | #if ENABLE_HUSH_LOOPS | 2247 | #if ENABLE_HUSH_LOOPS |
2269 | if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) { | 2248 | if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) { |
@@ -2336,7 +2315,6 @@ static int run_list(struct pipe *pi) | |||
2336 | #endif | 2315 | #endif |
2337 | if (pi->num_progs == 0) | 2316 | if (pi->num_progs == 0) |
2338 | continue; | 2317 | continue; |
2339 | //why? save_num_progs = pi->num_progs; | ||
2340 | debug_printf_exec(": run_pipe with %d members\n", pi->num_progs); | 2318 | debug_printf_exec(": run_pipe with %d members\n", pi->num_progs); |
2341 | rcode = run_pipe(pi); | 2319 | rcode = run_pipe(pi); |
2342 | if (rcode != -1) { | 2320 | if (rcode != -1) { |
@@ -2367,7 +2345,6 @@ static int run_list(struct pipe *pi) | |||
2367 | } | 2345 | } |
2368 | debug_printf_exec(": setting last_return_code=%d\n", rcode); | 2346 | debug_printf_exec(": setting last_return_code=%d\n", rcode); |
2369 | last_return_code = rcode; | 2347 | last_return_code = rcode; |
2370 | //why? pi->num_progs = save_num_progs; | ||
2371 | #if ENABLE_HUSH_IF | 2348 | #if ENABLE_HUSH_IF |
2372 | if (rword == RES_IF || rword == RES_ELIF) | 2349 | if (rword == RES_IF || rword == RES_ELIF) |
2373 | next_if_code = rcode; /* can be overwritten a number of times */ | 2350 | next_if_code = rcode; /* can be overwritten a number of times */ |
@@ -2488,10 +2465,6 @@ static int run_and_free_list(struct pipe *pi) | |||
2488 | return rcode; | 2465 | return rcode; |
2489 | } | 2466 | } |
2490 | 2467 | ||
2491 | /* Whoever decided to muck with glob internal data is AN IDIOT! */ | ||
2492 | /* uclibc happily changed the way it works (and it has rights to do so!), | ||
2493 | all hell broke loose (SEGVs) */ | ||
2494 | |||
2495 | /* The API for glob is arguably broken. This routine pushes a non-matching | 2468 | /* The API for glob is arguably broken. This routine pushes a non-matching |
2496 | * string into the output structure, removing non-backslashed backslashes. | 2469 | * string into the output structure, removing non-backslashed backslashes. |
2497 | * If someone can prove me wrong, by performing this function within the | 2470 | * If someone can prove me wrong, by performing this function within the |
@@ -3001,9 +2974,7 @@ static struct pipe *new_pipe(void) | |||
3001 | 2974 | ||
3002 | static void initialize_context(struct p_context *ctx) | 2975 | static void initialize_context(struct p_context *ctx) |
3003 | { | 2976 | { |
3004 | smallint sv = ctx->parse_type; | ||
3005 | memset(ctx, 0, sizeof(*ctx)); | 2977 | memset(ctx, 0, sizeof(*ctx)); |
3006 | ctx->parse_type = sv; | ||
3007 | ctx->pipe = ctx->list_head = new_pipe(); | 2978 | ctx->pipe = ctx->list_head = new_pipe(); |
3008 | /* Create the memory for child, roughly: | 2979 | /* Create the memory for child, roughly: |
3009 | * ctx->pipe->progs = new struct child_prog; | 2980 | * ctx->pipe->progs = new struct child_prog; |
@@ -3150,7 +3121,7 @@ static int done_word(o_string *word, struct p_context *ctx) | |||
3150 | debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n"); | 3121 | debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n"); |
3151 | return 1; | 3122 | return 1; |
3152 | } | 3123 | } |
3153 | if (!child->argv && (ctx->parse_type & PARSEFLAG_SEMICOLON)) { | 3124 | if (!child->argv) { |
3154 | debug_printf_parse(": checking '%s' for reserved-ness\n", word->data); | 3125 | debug_printf_parse(": checking '%s' for reserved-ness\n", word->data); |
3155 | if (reserved_word(word, ctx)) { | 3126 | if (reserved_word(word, ctx)) { |
3156 | o_reset(word); | 3127 | o_reset(word); |
@@ -3491,7 +3462,7 @@ static void add_till_double_quote(o_string *dest, struct in_str *input) | |||
3491 | o_addqchr(dest, ch); | 3462 | o_addqchr(dest, ch); |
3492 | continue; | 3463 | continue; |
3493 | } | 3464 | } |
3494 | // if (ch == '$') ... | 3465 | //if (ch == '$') ... |
3495 | } | 3466 | } |
3496 | } | 3467 | } |
3497 | /* Process `cmd` - copy contents until "`" is seen. Complicated by | 3468 | /* Process `cmd` - copy contents until "`" is seen. Complicated by |
@@ -3916,20 +3887,13 @@ static void update_charmap(void) | |||
3916 | * from builtin_source() and builtin_eval() */ | 3887 | * from builtin_source() and builtin_eval() */ |
3917 | static int parse_and_run_stream(struct in_str *inp, int parse_flag) | 3888 | static int parse_and_run_stream(struct in_str *inp, int parse_flag) |
3918 | { | 3889 | { |
3919 | //TODO: PARSEFLAG_SEMICOLON bit is always set in parse_flag. fishy | ||
3920 | //TODO: PARSEFLAG_REPARSING bit is never set (grep for it). wow | ||
3921 | struct p_context ctx; | 3890 | struct p_context ctx; |
3922 | o_string temp = NULL_O_STRING; | 3891 | o_string temp = NULL_O_STRING; |
3923 | int rcode; | 3892 | int rcode; |
3924 | 3893 | ||
3925 | do { | 3894 | do { |
3926 | // parse_type always has PARSEFLAG_SEMICOLON, can we remove all checks for this bit? | ||
3927 | // After that, the whole parse_type fiels is not needed. | ||
3928 | ctx.parse_type = parse_flag; | ||
3929 | initialize_context(&ctx); | 3895 | initialize_context(&ctx); |
3930 | update_charmap(); | 3896 | update_charmap(); |
3931 | if (!(parse_flag & PARSEFLAG_SEMICOLON) || (parse_flag & PARSEFLAG_REPARSING)) | ||
3932 | set_in_charmap(";$&|", CHAR_ORDINARY); | ||
3933 | #if ENABLE_HUSH_INTERACTIVE | 3897 | #if ENABLE_HUSH_INTERACTIVE |
3934 | inp->promptmode = 0; /* PS1 */ | 3898 | inp->promptmode = 0; /* PS1 */ |
3935 | #endif | 3899 | #endif |
@@ -3967,7 +3931,6 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag) | |||
3967 | 3931 | ||
3968 | static int parse_and_run_string(const char *s, int parse_flag) | 3932 | static int parse_and_run_string(const char *s, int parse_flag) |
3969 | { | 3933 | { |
3970 | //TODO: PARSEFLAG_SEMICOLON bit is always set in parse_flag. fishy | ||
3971 | struct in_str input; | 3934 | struct in_str input; |
3972 | setup_string_in_str(&input, s); | 3935 | setup_string_in_str(&input, s); |
3973 | return parse_and_run_stream(&input, parse_flag); | 3936 | return parse_and_run_stream(&input, parse_flag); |
@@ -3978,7 +3941,7 @@ static int parse_and_run_file(FILE *f) | |||
3978 | int rcode; | 3941 | int rcode; |
3979 | struct in_str input; | 3942 | struct in_str input; |
3980 | setup_file_in_str(&input, f); | 3943 | setup_file_in_str(&input, f); |
3981 | rcode = parse_and_run_stream(&input, PARSEFLAG_SEMICOLON); | 3944 | rcode = parse_and_run_stream(&input, 0 /* parse_flag */); |
3982 | return rcode; | 3945 | return rcode; |
3983 | } | 3946 | } |
3984 | 3947 | ||
@@ -4091,7 +4054,7 @@ int hush_main(int argc, char **argv) | |||
4091 | case 'c': | 4054 | case 'c': |
4092 | global_argv = argv + optind; | 4055 | global_argv = argv + optind; |
4093 | global_argc = argc - optind; | 4056 | global_argc = argc - optind; |
4094 | opt = parse_and_run_string(optarg, PARSEFLAG_SEMICOLON); | 4057 | opt = parse_and_run_string(optarg, 0 /* parse_flag */); |
4095 | goto final_return; | 4058 | goto final_return; |
4096 | case 'i': | 4059 | case 'i': |
4097 | /* Well, we cannot just declare interactiveness, | 4060 | /* Well, we cannot just declare interactiveness, |