aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-15 11:49:42 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-15 11:49:42 +0000
commit5703c22a51a154db17e6a7f6426a95232542cc9e (patch)
treead29110cbcb1fea736fd9d949e15429ed8f8b9d4
parentff7cd6f9250b352450bf811a1cc7bca75cc4e2b3 (diff)
downloadbusybox-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.c49
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
187typedef enum { 184typedef 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
252struct redir_struct { 247struct 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 */
591static char **alloc_ptrs(char **argv) 585static 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
3002static void initialize_context(struct p_context *ctx) 2975static 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() */
3917static int parse_and_run_stream(struct in_str *inp, int parse_flag) 3888static 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
3968static int parse_and_run_string(const char *s, int parse_flag) 3932static 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,