aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-24 00:50:07 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-24 00:50:07 +0000
commit5ec6132c9884f1f6ccbcc8277cb73220462a2133 (patch)
tree3944b70fa297304042d48acb52b32359433c5c97
parent003f9fb213e034dcfd3bdbd93e4d60315002d473 (diff)
downloadbusybox-w32-5ec6132c9884f1f6ccbcc8277cb73220462a2133.tar.gz
busybox-w32-5ec6132c9884f1f6ccbcc8277cb73220462a2133.tar.bz2
busybox-w32-5ec6132c9884f1f6ccbcc8277cb73220462a2133.zip
hush: ifdef out parts which are not needed
if neither loops nor ifs are supported. Code savings: function old new delta parse_stream 1758 1757 -1 checkjobs 335 318 -17 done_pipe 74 52 -22 expand_variables 1437 1407 -30 run_list 1232 1189 -43 parse_and_run_stream 328 267 -61 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 0/6 up/down: 0/-174) Total: -174 bytes
-rw-r--r--shell/hush.c105
1 files changed, 59 insertions, 46 deletions
diff --git a/shell/hush.c b/shell/hush.c
index b59f67942..ace0cdafc 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -150,9 +150,6 @@
150#define debug_printf_subst(...) fprintf(stderr, __VA_ARGS__) 150#define debug_printf_subst(...) fprintf(stderr, __VA_ARGS__)
151#endif 151#endif
152 152
153/* Keep unconditionally on for now */
154#define ENABLE_HUSH_DEBUG 1
155
156#ifndef debug_printf_clean 153#ifndef debug_printf_clean
157/* broken, of course, but OK for testing */ 154/* broken, of course, but OK for testing */
158static const char *indenter(int i) 155static const char *indenter(int i)
@@ -176,7 +173,6 @@ static void debug_print_strings(const char *prefix, char **vv)
176#define debug_print_strings(prefix, vv) ((void)0) 173#define debug_print_strings(prefix, vv) ((void)0)
177#endif 174#endif
178 175
179
180/* 176/*
181 * Leak hunting. Use hush_leaktool.sh for post-processing. 177 * Leak hunting. Use hush_leaktool.sh for post-processing.
182 */ 178 */
@@ -216,6 +212,20 @@ void xxfree(void *ptr)
216#endif 212#endif
217 213
218 214
215/* Keep unconditionally on for now */
216#define HUSH_DEBUG 1
217/* Do we support ANY keywords? */
218#if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS
219#define HAS_KEYWORDS 1
220#define IF_HAS_KEYWORDS(...) __VA_ARGS__
221#define IF_HAS_NO_KEYWORDS(...)
222#else
223#define HAS_KEYWORDS 0
224#define IF_HAS_KEYWORDS(...)
225#define IF_HAS_NO_KEYWORDS(...) __VA_ARGS__
226#endif
227
228
219#define SPECIAL_VAR_SYMBOL 3 229#define SPECIAL_VAR_SYMBOL 3
220#define PARSEFLAG_EXIT_FROM_LOOP 1 230#define PARSEFLAG_EXIT_FROM_LOOP 1
221 231
@@ -276,18 +286,20 @@ struct p_context {
276 struct pipe *list_head; 286 struct pipe *list_head;
277 struct pipe *pipe; 287 struct pipe *pipe;
278 struct redir_struct *pending_redirect; 288 struct redir_struct *pending_redirect;
279 smallint res_w; 289#if HAS_KEYWORDS
280 smallint ctx_inverted; /* "! cmd | cmd" */ 290 smallint ctx_res_w;
281 int old_flag; /* bitmask of FLAG_xxx, for figuring out valid reserved words */ 291 smallint ctx_inverted; /* "! cmd | cmd" */
292 int old_flag; /* bitmask of FLAG_xxx, for figuring out valid reserved words */
282 struct p_context *stack; 293 struct p_context *stack;
294#endif
283}; 295};
284 296
285struct redir_struct { 297struct redir_struct {
286 struct redir_struct *next; 298 struct redir_struct *next;
287 smallint /*redir_type*/ rd_type; 299 char *rd_filename; /* filename */
288 int fd; /* file descriptor being redirected */ 300 int fd; /* file descriptor being redirected */
289 int dup; /* -1, or file descriptor being duplicated */ 301 int dup; /* -1, or file descriptor being duplicated */
290 char *rd_filename; /* filename */ 302 smallint /*enum redir_type*/ rd_type;
291}; 303};
292 304
293struct child_prog { 305struct child_prog {
@@ -317,9 +329,9 @@ struct pipe {
317 char *cmdtext; /* name of job */ 329 char *cmdtext; /* name of job */
318#endif 330#endif
319 struct child_prog *progs; /* array of commands in pipe */ 331 struct child_prog *progs; /* array of commands in pipe */
320 smallint pi_inverted; /* "! cmd | cmd" */
321 smallint followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */ 332 smallint followup; /* PIPE_BG, PIPE_SEQ, PIPE_OR, PIPE_AND */
322 smallint res_word; /* needed for if, for, while, until... */ 333 IF_HAS_KEYWORDS(smallint pi_inverted;) /* "! cmd | cmd" */
334 IF_HAS_KEYWORDS(smallint res_word;) /* needed for if, for, while, until... */
323}; 335};
324 336
325/* On program start, environ points to initial environment. 337/* On program start, environ points to initial environment.
@@ -1629,8 +1641,7 @@ static int checkjobs(struct pipe* fg_pipe)
1629 if (i == fg_pipe->num_progs - 1) { 1641 if (i == fg_pipe->num_progs - 1) {
1630 /* last process gives overall exitstatus */ 1642 /* last process gives overall exitstatus */
1631 rcode = WEXITSTATUS(status); 1643 rcode = WEXITSTATUS(status);
1632 if (fg_pipe->pi_inverted) 1644 IF_HAS_KEYWORDS(if (fg_pipe->pi_inverted) rcode = !rcode;)
1633 rcode = !rcode;
1634 } 1645 }
1635 } else { 1646 } else {
1636 fg_pipe->progs[i].is_stopped = 1; 1647 fg_pipe->progs[i].is_stopped = 1;
@@ -1757,8 +1768,7 @@ static int run_pipe(struct pipe *pi)
1757 rcode = run_list(child->group) & 0xff; 1768 rcode = run_list(child->group) & 0xff;
1758 restore_redirects(squirrel); 1769 restore_redirects(squirrel);
1759 debug_printf_exec("run_pipe return %d\n", rcode); 1770 debug_printf_exec("run_pipe return %d\n", rcode);
1760 if (pi->pi_inverted) 1771 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
1761 rcode = !rcode;
1762 return rcode; 1772 return rcode;
1763 } 1773 }
1764 1774
@@ -1801,8 +1811,7 @@ static int run_pipe(struct pipe *pi)
1801 free(argv_expanded); 1811 free(argv_expanded);
1802 restore_redirects(squirrel); 1812 restore_redirects(squirrel);
1803 debug_printf_exec("run_pipe return %d\n", rcode); 1813 debug_printf_exec("run_pipe return %d\n", rcode);
1804 if (pi->pi_inverted) 1814 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
1805 rcode = !rcode;
1806 return rcode; 1815 return rcode;
1807 } 1816 }
1808 } 1817 }
@@ -1819,8 +1828,7 @@ static int run_pipe(struct pipe *pi)
1819 free(argv_expanded); 1828 free(argv_expanded);
1820 restore_redirects(squirrel); 1829 restore_redirects(squirrel);
1821 debug_printf_exec("run_pipe return %d\n", rcode); 1830 debug_printf_exec("run_pipe return %d\n", rcode);
1822 if (pi->pi_inverted) 1831 IF_HAS_KEYWORDS(if (pi->pi_inverted) rcode = !rcode;)
1823 rcode = !rcode;
1824 return rcode; 1832 return rcode;
1825 } 1833 }
1826 } 1834 }
@@ -2003,8 +2011,7 @@ static int run_list(struct pipe *pi)
2003#else 2011#else
2004 enum { if_code = 0, next_if_code = 0 }; 2012 enum { if_code = 0, next_if_code = 0 };
2005#endif 2013#endif
2006// TODO: rword and ->res_word are not needed if !LOOPS and !IF 2014 reserved_style rword IF_HAS_NO_KEYWORDS(= RES_NONE);
2007 reserved_style rword;
2008 reserved_style skip_more_for_this_rword = RES_XXXX; 2015 reserved_style skip_more_for_this_rword = RES_XXXX;
2009 2016
2010 debug_printf_exec("run_list start lvl %d\n", run_list_level + 1); 2017 debug_printf_exec("run_list start lvl %d\n", run_list_level + 1);
@@ -2075,7 +2082,8 @@ static int run_list(struct pipe *pi)
2075#endif /* JOB */ 2082#endif /* JOB */
2076 2083
2077 for (; pi; pi = flag_restore ? rpipe : pi->next) { 2084 for (; pi; pi = flag_restore ? rpipe : pi->next) {
2078 rword = pi->res_word; 2085 IF_HAS_KEYWORDS(rword = pi->res_word;)
2086 IF_HAS_NO_KEYWORDS(rword = RES_NONE;)
2079#if ENABLE_HUSH_LOOPS 2087#if ENABLE_HUSH_LOOPS
2080 if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) { 2088 if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) {
2081 flag_restore = 0; 2089 flag_restore = 0;
@@ -2272,7 +2280,9 @@ static int free_pipe_list(struct pipe *head, int indent)
2272 struct pipe *pi, *next; 2280 struct pipe *pi, *next;
2273 2281
2274 for (pi = head; pi; pi = next) { 2282 for (pi = head; pi; pi = next) {
2283#if HAS_KEYWORDS
2275 debug_printf_clean("%s pipe reserved mode %d\n", indenter(indent), pi->res_word); 2284 debug_printf_clean("%s pipe reserved mode %d\n", indenter(indent), pi->res_word);
2285#endif
2276 rcode = free_pipe(pi, indent); 2286 rcode = free_pipe(pi, indent);
2277 debug_printf_clean("%s pipe followup code %d\n", indenter(indent), pi->followup); 2287 debug_printf_clean("%s pipe followup code %d\n", indenter(indent), pi->followup);
2278 next = pi->next; 2288 next = pi->next;
@@ -2548,7 +2558,7 @@ static char *expand_string_to_string(const char *str)
2548 argv[0] = (char*)str; 2558 argv[0] = (char*)str;
2549 argv[1] = NULL; 2559 argv[1] = NULL;
2550 list = expand_variables(argv, 0x80); /* 0x80: make one-element expansion */ 2560 list = expand_variables(argv, 0x80); /* 0x80: make one-element expansion */
2551 if (ENABLE_HUSH_DEBUG) 2561 if (HUSH_DEBUG)
2552 if (!list[0] || list[1]) 2562 if (!list[0] || list[1])
2553 bb_error_msg_and_die("BUG in varexp2"); 2563 bb_error_msg_and_die("BUG in varexp2");
2554 /* actually, just move string 2*sizeof(char*) bytes back */ 2564 /* actually, just move string 2*sizeof(char*) bytes back */
@@ -2567,7 +2577,7 @@ static char* expand_strvec_to_string(char **argv)
2567 if (list[0]) { 2577 if (list[0]) {
2568 int n = 1; 2578 int n = 1;
2569 while (list[n]) { 2579 while (list[n]) {
2570 if (ENABLE_HUSH_DEBUG) 2580 if (HUSH_DEBUG)
2571 if (list[n-1] + strlen(list[n-1]) + 1 != list[n]) 2581 if (list[n-1] + strlen(list[n-1]) + 1 != list[n])
2572 bb_error_msg_and_die("BUG in varexp3"); 2582 bb_error_msg_and_die("BUG in varexp3");
2573 list[n][-1] = ' '; /* TODO: or to ifs[0]? */ 2583 list[n][-1] = ' '; /* TODO: or to ifs[0]? */
@@ -2747,8 +2757,7 @@ static struct pipe *new_pipe(void)
2747 struct pipe *pi; 2757 struct pipe *pi;
2748 pi = xzalloc(sizeof(struct pipe)); 2758 pi = xzalloc(sizeof(struct pipe));
2749 /*pi->followup = 0; - deliberately invalid value */ 2759 /*pi->followup = 0; - deliberately invalid value */
2750 if (RES_NONE) 2760 /*pi->res_word = RES_NONE; - RES_NONE is 0 anyway */
2751 pi->res_word = RES_NONE;
2752 return pi; 2761 return pi;
2753} 2762}
2754 2763
@@ -2769,7 +2778,7 @@ static void initialize_context(struct p_context *ctx)
2769 * Handles if, then, elif, else, fi, for, while, until, do, done. 2778 * Handles if, then, elif, else, fi, for, while, until, do, done.
2770 * case, function, and select are obnoxious, save those for later. 2779 * case, function, and select are obnoxious, save those for later.
2771 */ 2780 */
2772#if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS 2781#if HAS_KEYWORDS
2773static int reserved_word(const o_string *word, struct p_context *ctx) 2782static int reserved_word(const o_string *word, struct p_context *ctx)
2774{ 2783{
2775 struct reserved_combo { 2784 struct reserved_combo {
@@ -2828,18 +2837,18 @@ static int reserved_word(const o_string *word, struct p_context *ctx)
2828 debug_printf("found reserved word %s, res %d\n", r->literal, r->res); 2837 debug_printf("found reserved word %s, res %d\n", r->literal, r->res);
2829 if (r->flag == 0) { /* '!' */ 2838 if (r->flag == 0) { /* '!' */
2830#if ENABLE_HUSH_LOOPS 2839#if ENABLE_HUSH_LOOPS
2831 if (ctx->res_w == RES_IN) { 2840 if (ctx->ctx_res_w == RES_IN) {
2832 /* 'for a in ! a b c; ...' - ! isn't a keyword here */ 2841 /* 'for a in ! a b c; ...' - ! isn't a keyword here */
2833 break; 2842 break;
2834 } 2843 }
2835#endif 2844#endif
2836 if (ctx->ctx_inverted /* bash doesn't accept '! ! true' */ 2845 if (ctx->ctx_inverted /* bash doesn't accept '! ! true' */
2837#if ENABLE_HUSH_LOOPS 2846#if ENABLE_HUSH_LOOPS
2838 || ctx->res_w == RES_FOR /* example: 'for ! a' */ 2847 || ctx->ctx_res_w == RES_FOR /* example: 'for ! a' */
2839#endif 2848#endif
2840 ) { 2849 ) {
2841 syntax(NULL); 2850 syntax(NULL);
2842 ctx->res_w = RES_SNTX; 2851 IF_HAS_KEYWORDS(ctx->ctx_res_w = RES_SNTX;)
2843 } 2852 }
2844 ctx->ctx_inverted = 1; 2853 ctx->ctx_inverted = 1;
2845 return 1; 2854 return 1;
@@ -2848,9 +2857,9 @@ static int reserved_word(const o_string *word, struct p_context *ctx)
2848 struct p_context *new; 2857 struct p_context *new;
2849 debug_printf("push stack\n"); 2858 debug_printf("push stack\n");
2850#if ENABLE_HUSH_LOOPS 2859#if ENABLE_HUSH_LOOPS
2851 if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) { 2860 if (ctx->ctx_res_w == RES_IN || ctx->ctx_res_w == RES_FOR) {
2852 syntax("malformed for"); /* example: 'for if' */ 2861 syntax("malformed for"); /* example: 'for if' */
2853 ctx->res_w = RES_SNTX; 2862 ctx->ctx_res_w = RES_SNTX;
2854 return 1; 2863 return 1;
2855 } 2864 }
2856#endif 2865#endif
@@ -2858,12 +2867,12 @@ static int reserved_word(const o_string *word, struct p_context *ctx)
2858 *new = *ctx; /* physical copy */ 2867 *new = *ctx; /* physical copy */
2859 initialize_context(ctx); 2868 initialize_context(ctx);
2860 ctx->stack = new; 2869 ctx->stack = new;
2861 } else if (ctx->res_w == RES_NONE || !(ctx->old_flag & (1 << r->res))) { 2870 } else if (ctx->ctx_res_w == RES_NONE || !(ctx->old_flag & (1 << r->res))) {
2862 syntax(NULL); 2871 syntax(NULL);
2863 ctx->res_w = RES_SNTX; 2872 ctx->ctx_res_w = RES_SNTX;
2864 return 1; 2873 return 1;
2865 } 2874 }
2866 ctx->res_w = r->res; 2875 ctx->ctx_res_w = r->res;
2867 ctx->old_flag = r->flag; 2876 ctx->old_flag = r->flag;
2868 if (ctx->old_flag & FLAG_END) { 2877 if (ctx->old_flag & FLAG_END) {
2869 struct p_context *old; 2878 struct p_context *old;
@@ -2879,8 +2888,6 @@ static int reserved_word(const o_string *word, struct p_context *ctx)
2879 } 2888 }
2880 return 0; 2889 return 0;
2881} 2890}
2882#else
2883#define reserved_word(word, ctx) ((int)0)
2884#endif 2891#endif
2885 2892
2886/* Word is complete, look at it and update parsing context. 2893/* Word is complete, look at it and update parsing context.
@@ -2914,15 +2921,17 @@ static int done_word(o_string *word, struct p_context *ctx)
2914 debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n"); 2921 debug_printf_parse("done_word return 1: syntax error, groups and arglists don't mix\n");
2915 return 1; 2922 return 1;
2916 } 2923 }
2924#if HAS_KEYWORDS
2917 if (!child->argv) { /* if it's the first word... */ 2925 if (!child->argv) { /* if it's the first word... */
2918 debug_printf_parse(": checking '%s' for reserved-ness\n", word->data); 2926 debug_printf_parse(": checking '%s' for reserved-ness\n", word->data);
2919 if (reserved_word(word, ctx)) { 2927 if (reserved_word(word, ctx)) {
2920 o_reset(word); 2928 o_reset(word);
2921 word->o_assignment = NOT_ASSIGNMENT; 2929 word->o_assignment = NOT_ASSIGNMENT;
2922 debug_printf_parse("done_word return %d\n", (ctx->res_w == RES_SNTX)); 2930 debug_printf_parse("done_word return %d\n", (ctx->ctx_res_w == RES_SNTX));
2923 return (ctx->res_w == RES_SNTX); 2931 return (ctx->ctx_res_w == RES_SNTX);
2924 } 2932 }
2925 } 2933 }
2934#endif
2926 if (word->nonnull /* we saw "xx" or 'xx' */ 2935 if (word->nonnull /* we saw "xx" or 'xx' */
2927 /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */ 2936 /* optimization: and if it's ("" or '') or ($v... or `cmd`...): */
2928 && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL) 2937 && (word->data[0] == '\0' || word->data[0] == SPECIAL_VAR_SYMBOL)
@@ -2942,7 +2951,7 @@ static int done_word(o_string *word, struct p_context *ctx)
2942 2951
2943#if ENABLE_HUSH_LOOPS 2952#if ENABLE_HUSH_LOOPS
2944 /* Force FOR to have just one word (variable name) */ 2953 /* Force FOR to have just one word (variable name) */
2945 if (ctx->res_w == RES_FOR) 2954 if (ctx->ctx_res_w == RES_FOR)
2946 done_pipe(ctx, PIPE_SEQ); 2955 done_pipe(ctx, PIPE_SEQ);
2947#endif 2956#endif
2948 debug_printf_parse("done_word return 0\n"); 2957 debug_printf_parse("done_word return 0\n");
@@ -2993,9 +3002,9 @@ static void done_pipe(struct p_context *ctx, pipe_style type)
2993 debug_printf_parse("done_pipe entered, followup %d\n", type); 3002 debug_printf_parse("done_pipe entered, followup %d\n", type);
2994 not_null = done_command(ctx); /* implicit closure of previous command */ 3003 not_null = done_command(ctx); /* implicit closure of previous command */
2995 ctx->pipe->followup = type; 3004 ctx->pipe->followup = type;
2996 ctx->pipe->res_word = ctx->res_w; 3005 IF_HAS_KEYWORDS(ctx->pipe->res_word = ctx->ctx_res_w;)
2997 ctx->pipe->pi_inverted = ctx->ctx_inverted; 3006 IF_HAS_KEYWORDS(ctx->pipe->pi_inverted = ctx->ctx_inverted;)
2998 ctx->ctx_inverted = 0; 3007 IF_HAS_KEYWORDS(ctx->ctx_inverted = 0;)
2999 /* Without this check, even just <enter> on command line generates 3008 /* Without this check, even just <enter> on command line generates
3000 * tree of three NOPs (!). Which is harmless but annoying. 3009 * tree of three NOPs (!). Which is harmless but annoying.
3001 * IOW: it is safe to do it unconditionally. 3010 * IOW: it is safe to do it unconditionally.
@@ -3480,7 +3489,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3480//err chk? 3489//err chk?
3481 done_pipe(ctx, PIPE_SEQ); 3490 done_pipe(ctx, PIPE_SEQ);
3482 } 3491 }
3483 if (ctx->res_w == RES_NONE) { 3492 if (!HAS_KEYWORDS IF_HAS_KEYWORDS(|| ctx->ctx_res_w == RES_NONE)) {
3484 debug_printf_parse("parse_stream return 0: end_trigger char found\n"); 3493 debug_printf_parse("parse_stream return 0: end_trigger char found\n");
3485 return 0; 3494 return 0;
3486 } 3495 }
@@ -3650,7 +3659,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx,
3650 debug_printf_parse("parse_stream return 1: unexpected '}'\n"); 3659 debug_printf_parse("parse_stream return 1: unexpected '}'\n");
3651 return 1; 3660 return 1;
3652 default: 3661 default:
3653 if (ENABLE_HUSH_DEBUG) 3662 if (HUSH_DEBUG)
3654 bb_error_msg_and_die("BUG: unexpected %c\n", ch); 3663 bb_error_msg_and_die("BUG: unexpected %c\n", ch);
3655 } 3664 }
3656 } /* while (1) */ 3665 } /* while (1) */
@@ -3706,10 +3715,12 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
3706 * Example: "sleep 9999; echo TEST" + ctrl-C: 3715 * Example: "sleep 9999; echo TEST" + ctrl-C:
3707 * TEST should be printed */ 3716 * TEST should be printed */
3708 rcode = parse_stream(&temp, &ctx, inp, ";\n"); 3717 rcode = parse_stream(&temp, &ctx, inp, ";\n");
3718#if HAS_KEYWORDS
3709 if (rcode != 1 && ctx.old_flag != 0) { 3719 if (rcode != 1 && ctx.old_flag != 0) {
3710 syntax(NULL); 3720 syntax(NULL);
3711 } 3721 }
3712 if (rcode != 1 && ctx.old_flag == 0) { 3722#endif
3723 if (rcode != 1 IF_HAS_KEYWORDS(&& ctx.old_flag == 0)) {
3713 done_word(&temp, &ctx); 3724 done_word(&temp, &ctx);
3714 done_pipe(&ctx, PIPE_SEQ); 3725 done_pipe(&ctx, PIPE_SEQ);
3715 debug_print_tree(ctx.list_head, 0); 3726 debug_print_tree(ctx.list_head, 0);
@@ -3717,10 +3728,12 @@ static int parse_and_run_stream(struct in_str *inp, int parse_flag)
3717 run_and_free_list(ctx.list_head); 3728 run_and_free_list(ctx.list_head);
3718 } else { 3729 } else {
3719 /* We arrive here also if rcode == 1 (error in parse_stream) */ 3730 /* We arrive here also if rcode == 1 (error in parse_stream) */
3731#if HAS_KEYWORDS
3720 if (ctx.old_flag != 0) { 3732 if (ctx.old_flag != 0) {
3721 free(ctx.stack); 3733 free(ctx.stack);
3722 o_reset(&temp); 3734 o_reset(&temp);
3723 } 3735 }
3736#endif
3724 /*temp.nonnull = 0; - o_free does it below */ 3737 /*temp.nonnull = 0; - o_free does it below */
3725 /*temp.o_quote = 0; - o_free does it below */ 3738 /*temp.o_quote = 0; - o_free does it below */
3726 free_pipe_list(ctx.list_head, /* indent: */ 0); 3739 free_pipe_list(ctx.list_head, /* indent: */ 0);