summaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-05-21 23:30:54 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-05-21 23:30:54 +0000
commit06810339189c1372d3defb8e3dcdb58a07ade7a7 (patch)
tree7d8ab749ab33dfbdcd8115013b75e0852e926293 /shell/hush.c
parent8805eeb44a291b830e9eb1a430d112913ffa9a24 (diff)
downloadbusybox-w32-06810339189c1372d3defb8e3dcdb58a07ade7a7.tar.gz
busybox-w32-06810339189c1372d3defb8e3dcdb58a07ade7a7.tar.bz2
busybox-w32-06810339189c1372d3defb8e3dcdb58a07ade7a7.zip
hush: add 3 CONFIG_xxx, allowing for smaller and less capable hush.
Minimal hush is ~9k now (lash is ~7k).
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c129
1 files changed, 91 insertions, 38 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 90c89fba2..61c03f703 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -175,33 +175,41 @@ typedef enum {
175/* might eventually control execution */ 175/* might eventually control execution */
176typedef enum { 176typedef enum {
177 RES_NONE = 0, 177 RES_NONE = 0,
178#if ENABLE_HUSH_IF
178 RES_IF = 1, 179 RES_IF = 1,
179 RES_THEN = 2, 180 RES_THEN = 2,
180 RES_ELIF = 3, 181 RES_ELIF = 3,
181 RES_ELSE = 4, 182 RES_ELSE = 4,
182 RES_FI = 5, 183 RES_FI = 5,
184#endif
185#if ENABLE_HUSH_LOOPS
183 RES_FOR = 6, 186 RES_FOR = 6,
184 RES_WHILE = 7, 187 RES_WHILE = 7,
185 RES_UNTIL = 8, 188 RES_UNTIL = 8,
186 RES_DO = 9, 189 RES_DO = 9,
187 RES_DONE = 10, 190 RES_DONE = 10,
188 RES_XXXX = 11, 191 RES_IN = 11,
189 RES_IN = 12, 192#endif
193 RES_XXXX = 12,
190 RES_SNTX = 13 194 RES_SNTX = 13
191} reserved_style; 195} reserved_style;
192enum { 196enum {
193 FLAG_END = (1 << RES_NONE ), 197 FLAG_END = (1 << RES_NONE ),
198#if ENABLE_HUSH_IF
194 FLAG_IF = (1 << RES_IF ), 199 FLAG_IF = (1 << RES_IF ),
195 FLAG_THEN = (1 << RES_THEN ), 200 FLAG_THEN = (1 << RES_THEN ),
196 FLAG_ELIF = (1 << RES_ELIF ), 201 FLAG_ELIF = (1 << RES_ELIF ),
197 FLAG_ELSE = (1 << RES_ELSE ), 202 FLAG_ELSE = (1 << RES_ELSE ),
198 FLAG_FI = (1 << RES_FI ), 203 FLAG_FI = (1 << RES_FI ),
204#endif
205#if ENABLE_HUSH_LOOPS
199 FLAG_FOR = (1 << RES_FOR ), 206 FLAG_FOR = (1 << RES_FOR ),
200 FLAG_WHILE = (1 << RES_WHILE), 207 FLAG_WHILE = (1 << RES_WHILE),
201 FLAG_UNTIL = (1 << RES_UNTIL), 208 FLAG_UNTIL = (1 << RES_UNTIL),
202 FLAG_DO = (1 << RES_DO ), 209 FLAG_DO = (1 << RES_DO ),
203 FLAG_DONE = (1 << RES_DONE ), 210 FLAG_DONE = (1 << RES_DONE ),
204 FLAG_IN = (1 << RES_IN ), 211 FLAG_IN = (1 << RES_IN ),
212#endif
205 FLAG_START = (1 << RES_XXXX ), 213 FLAG_START = (1 << RES_XXXX ),
206}; 214};
207 215
@@ -429,7 +437,9 @@ static int builtin_export(char **argv);
429static int builtin_fg_bg(char **argv); 437static int builtin_fg_bg(char **argv);
430static int builtin_jobs(char **argv); 438static int builtin_jobs(char **argv);
431#endif 439#endif
440#if ENABLE_HUSH_HELP
432static int builtin_help(char **argv); 441static int builtin_help(char **argv);
442#endif
433static int builtin_pwd(char **argv); 443static int builtin_pwd(char **argv);
434static int builtin_read(char **argv); 444static int builtin_read(char **argv);
435static int builtin_set(char **argv); 445static int builtin_set(char **argv);
@@ -437,7 +447,7 @@ static int builtin_shift(char **argv);
437static int builtin_source(char **argv); 447static int builtin_source(char **argv);
438static int builtin_umask(char **argv); 448static int builtin_umask(char **argv);
439static int builtin_unset(char **argv); 449static int builtin_unset(char **argv);
440static int builtin_not_written(char **argv); 450//static int builtin_not_written(char **argv);
441/* o_string manipulation: */ 451/* o_string manipulation: */
442static int b_check_space(o_string *o, int len); 452static int b_check_space(o_string *o, int len);
443static int b_addchr(o_string *o, int ch); 453static int b_addchr(o_string *o, int ch);
@@ -520,38 +530,45 @@ static void unset_local_var(const char *name);
520 * still be set at the end. */ 530 * still be set at the end. */
521struct built_in_command { 531struct built_in_command {
522 const char *cmd; /* name */ 532 const char *cmd; /* name */
523 const char *descr; /* description */
524 int (*function) (char **argv); /* function ptr */ 533 int (*function) (char **argv); /* function ptr */
534#if ENABLE_HUSH_HELP
535 const char *descr; /* description */
536#define BLTIN(cmd, func, help) { cmd, func, help }
537#else
538#define BLTIN(cmd, func, help) { cmd, func }
539#endif
525}; 540};
526 541
527static const struct built_in_command bltins[] = { 542static const struct built_in_command bltins[] = {
528#if ENABLE_HUSH_JOB 543#if ENABLE_HUSH_JOB
529 { "bg", "Resume a job in the background", builtin_fg_bg }, 544 BLTIN("bg" , builtin_fg_bg, "Resume a job in the background"),
530#endif 545#endif
531 { "break", "Exit for, while or until loop", builtin_not_written }, 546// BLTIN("break" , builtin_not_written, "Exit for, while or until loop"),
532 { "cd", "Change working directory", builtin_cd }, 547 BLTIN("cd" , builtin_cd, "Change working directory"),
533 { "continue", "Continue for, while or until loop", builtin_not_written }, 548// BLTIN("continue", builtin_not_written, "Continue for, while or until loop"),
534 { "eval", "Construct and run shell command", builtin_eval }, 549 BLTIN("eval" , builtin_eval, "Construct and run shell command"),
535 { "exec", "Exec command, replacing this shell with the exec'd process", 550 BLTIN("exec" , builtin_exec, "Exec command, replacing this shell with the exec'd process"),
536 builtin_exec }, 551 BLTIN("exit" , builtin_exit, "Exit from shell"),
537 { "exit", "Exit from shell()", builtin_exit }, 552 BLTIN("export", builtin_export, "Set environment variable"),
538 { "export", "Set environment variable", builtin_export },
539#if ENABLE_HUSH_JOB 553#if ENABLE_HUSH_JOB
540 { "fg", "Bring job into the foreground", builtin_fg_bg }, 554 BLTIN("fg" , builtin_fg_bg, "Bring job into the foreground"),
541 { "jobs", "Lists the active jobs", builtin_jobs }, 555 BLTIN("jobs" , builtin_jobs, "Lists the active jobs"),
542#endif 556#endif
543 { "pwd", "Print current directory", builtin_pwd }, 557// TODO: remove pwd? we have it as an applet...
544 { "read", "Input environment variable", builtin_read }, 558 BLTIN("pwd" , builtin_pwd, "Print current directory"),
545 { "return", "Return from a function", builtin_not_written }, 559 BLTIN("read" , builtin_read, "Input environment variable"),
546 { "set", "Set/unset shell local variables", builtin_set }, 560// BLTIN("return", builtin_not_written, "Return from a function"),
547 { "shift", "Shift positional parameters", builtin_shift }, 561 BLTIN("set" , builtin_set, "Set/unset shell local variables"),
548 { "trap", "Trap signals", builtin_not_written }, 562 BLTIN("shift" , builtin_shift, "Shift positional parameters"),
549 { "ulimit","Controls resource limits", builtin_not_written }, 563// BLTIN("trap" , builtin_not_written, "Trap signals"),
550 { "umask","Sets file creation mask", builtin_umask }, 564// BLTIN("ulimit", builtin_not_written, "Controls resource limits"),
551 { "unset", "Unset environment variable", builtin_unset }, 565 BLTIN("umask" , builtin_umask, "Sets file creation mask"),
552 { ".", "Source-in and run commands in a file", builtin_source }, 566 BLTIN("unset" , builtin_unset, "Unset environment variable"),
553 { "help", "List shell built-in commands", builtin_help }, 567 BLTIN("." , builtin_source, "Source-in and run commands in a file"),
554 { NULL, NULL, NULL } 568#if ENABLE_HUSH_HELP
569 BLTIN("help" , builtin_help, "List shell built-in commands"),
570#endif
571 BLTIN(NULL, NULL, NULL)
555}; 572};
556 573
557#if ENABLE_HUSH_JOB 574#if ENABLE_HUSH_JOB
@@ -868,6 +885,7 @@ static int builtin_fg_bg(char **argv)
868#endif 885#endif
869 886
870/* built-in 'help' handler */ 887/* built-in 'help' handler */
888#if ENABLE_HUSH_HELP
871static int builtin_help(char **argv ATTRIBUTE_UNUSED) 889static int builtin_help(char **argv ATTRIBUTE_UNUSED)
872{ 890{
873 const struct built_in_command *x; 891 const struct built_in_command *x;
@@ -875,13 +893,12 @@ static int builtin_help(char **argv ATTRIBUTE_UNUSED)
875 printf("\nBuilt-in commands:\n"); 893 printf("\nBuilt-in commands:\n");
876 printf("-------------------\n"); 894 printf("-------------------\n");
877 for (x = bltins; x->cmd; x++) { 895 for (x = bltins; x->cmd; x++) {
878 if (x->descr == NULL)
879 continue;
880 printf("%s\t%s\n", x->cmd, x->descr); 896 printf("%s\t%s\n", x->cmd, x->descr);
881 } 897 }
882 printf("\n\n"); 898 printf("\n\n");
883 return EXIT_SUCCESS; 899 return EXIT_SUCCESS;
884} 900}
901#endif
885 902
886#if ENABLE_HUSH_JOB 903#if ENABLE_HUSH_JOB
887/* built-in 'jobs' handler */ 904/* built-in 'jobs' handler */
@@ -1014,11 +1031,11 @@ static int builtin_unset(char **argv)
1014 return EXIT_SUCCESS; 1031 return EXIT_SUCCESS;
1015} 1032}
1016 1033
1017static int builtin_not_written(char **argv) 1034//static int builtin_not_written(char **argv)
1018{ 1035//{
1019 printf("builtin_%s not written\n", argv[0]); 1036// printf("builtin_%s not written\n", argv[0]);
1020 return EXIT_FAILURE; 1037// return EXIT_FAILURE;
1021} 1038//}
1022 1039
1023static int b_check_space(o_string *o, int len) 1040static int b_check_space(o_string *o, int len)
1024{ 1041{
@@ -1882,18 +1899,22 @@ static void debug_print_tree(struct pipe *pi, int lvl)
1882 }; 1899 };
1883 static const char *RES[] = { 1900 static const char *RES[] = {
1884 [RES_NONE ] = "NONE" , 1901 [RES_NONE ] = "NONE" ,
1902#if ENABLE_HUSH_IF
1885 [RES_IF ] = "IF" , 1903 [RES_IF ] = "IF" ,
1886 [RES_THEN ] = "THEN" , 1904 [RES_THEN ] = "THEN" ,
1887 [RES_ELIF ] = "ELIF" , 1905 [RES_ELIF ] = "ELIF" ,
1888 [RES_ELSE ] = "ELSE" , 1906 [RES_ELSE ] = "ELSE" ,
1889 [RES_FI ] = "FI" , 1907 [RES_FI ] = "FI" ,
1908#endif
1909#if ENABLE_HUSH_LOOPS
1890 [RES_FOR ] = "FOR" , 1910 [RES_FOR ] = "FOR" ,
1891 [RES_WHILE] = "WHILE", 1911 [RES_WHILE] = "WHILE",
1892 [RES_UNTIL] = "UNTIL", 1912 [RES_UNTIL] = "UNTIL",
1893 [RES_DO ] = "DO" , 1913 [RES_DO ] = "DO" ,
1894 [RES_DONE ] = "DONE" , 1914 [RES_DONE ] = "DONE" ,
1895 [RES_XXXX ] = "XXXX" ,
1896 [RES_IN ] = "IN" , 1915 [RES_IN ] = "IN" ,
1916#endif
1917 [RES_XXXX ] = "XXXX" ,
1897 [RES_SNTX ] = "SNTX" , 1918 [RES_SNTX ] = "SNTX" ,
1898 }; 1919 };
1899 1920
@@ -1934,21 +1955,28 @@ static void debug_print_tree(struct pipe *pi, int lvl)
1934 * global data until exec/_exit (we can be a child after vfork!) */ 1955 * global data until exec/_exit (we can be a child after vfork!) */
1935static int run_list_real(struct pipe *pi) 1956static int run_list_real(struct pipe *pi)
1936{ 1957{
1958 struct pipe *rpipe;
1959#if ENABLE_HUSH_LOOPS
1937 char *for_varname = NULL; 1960 char *for_varname = NULL;
1938 char **for_lcur = NULL; 1961 char **for_lcur = NULL;
1939 char **for_list = NULL; 1962 char **for_list = NULL;
1940 struct pipe *rpipe;
1941 int flag_rep = 0; 1963 int flag_rep = 0;
1964#endif
1942 int save_num_progs; 1965 int save_num_progs;
1943 int flag_skip = 1; 1966 int flag_skip = 1;
1944 int rcode = 0; /* probably for gcc only */ 1967 int rcode = 0; /* probably for gcc only */
1945 int flag_restore = 0; 1968 int flag_restore = 0;
1969#if ENABLE_HUSH_IF
1946 int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */ 1970 int if_code = 0, next_if_code = 0; /* need double-buffer to handle elif */
1971#else
1972 enum { if_code = 0, next_if_code = 0 };
1973#endif
1947 reserved_style rword; 1974 reserved_style rword;
1948 reserved_style skip_more_for_this_rword = RES_XXXX; 1975 reserved_style skip_more_for_this_rword = RES_XXXX;
1949 1976
1950 debug_printf_exec("run_list_real start lvl %d\n", run_list_level + 1); 1977 debug_printf_exec("run_list_real start lvl %d\n", run_list_level + 1);
1951 1978
1979#if ENABLE_HUSH_LOOPS
1952 /* check syntax for "for" */ 1980 /* check syntax for "for" */
1953 for (rpipe = pi; rpipe; rpipe = rpipe->next) { 1981 for (rpipe = pi; rpipe; rpipe = rpipe->next) {
1954 if ((rpipe->res_word == RES_IN || rpipe->res_word == RES_FOR) 1982 if ((rpipe->res_word == RES_IN || rpipe->res_word == RES_FOR)
@@ -1967,6 +1995,9 @@ static int run_list_real(struct pipe *pi)
1967 return 1; 1995 return 1;
1968 } 1996 }
1969 } 1997 }
1998#else
1999 rpipe = NULL;
2000#endif
1970 2001
1971#if ENABLE_HUSH_JOB 2002#if ENABLE_HUSH_JOB
1972 /* Example of nested list: "while true; do { sleep 1 | exit 2; } done". 2003 /* Example of nested list: "while true; do { sleep 1 | exit 2; } done".
@@ -2012,6 +2043,7 @@ static int run_list_real(struct pipe *pi)
2012 2043
2013 for (; pi; pi = flag_restore ? rpipe : pi->next) { 2044 for (; pi; pi = flag_restore ? rpipe : pi->next) {
2014 rword = pi->res_word; 2045 rword = pi->res_word;
2046#if ENABLE_HUSH_LOOPS
2015 if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) { 2047 if (rword == RES_WHILE || rword == RES_UNTIL || rword == RES_FOR) {
2016 flag_restore = 0; 2048 flag_restore = 0;
2017 if (!rpipe) { 2049 if (!rpipe) {
@@ -2019,6 +2051,7 @@ static int run_list_real(struct pipe *pi)
2019 rpipe = pi; 2051 rpipe = pi;
2020 } 2052 }
2021 } 2053 }
2054#endif
2022 debug_printf_exec(": rword=%d if_code=%d next_if_code=%d skip_more=%d\n", 2055 debug_printf_exec(": rword=%d if_code=%d next_if_code=%d skip_more=%d\n",
2023 rword, if_code, next_if_code, skip_more_for_this_rword); 2056 rword, if_code, next_if_code, skip_more_for_this_rword);
2024 if (rword == skip_more_for_this_rword && flag_skip) { 2057 if (rword == skip_more_for_this_rword && flag_skip) {
@@ -2028,6 +2061,7 @@ static int run_list_real(struct pipe *pi)
2028 } 2061 }
2029 flag_skip = 1; 2062 flag_skip = 1;
2030 skip_more_for_this_rword = RES_XXXX; 2063 skip_more_for_this_rword = RES_XXXX;
2064#if ENABLE_HUSH_IF
2031 if (rword == RES_THEN || rword == RES_ELSE) 2065 if (rword == RES_THEN || rword == RES_ELSE)
2032 if_code = next_if_code; 2066 if_code = next_if_code;
2033 if (rword == RES_THEN && if_code) 2067 if (rword == RES_THEN && if_code)
@@ -2036,6 +2070,8 @@ static int run_list_real(struct pipe *pi)
2036 continue; 2070 continue;
2037 if (rword == RES_ELIF && !if_code) 2071 if (rword == RES_ELIF && !if_code)
2038 break; 2072 break;
2073#endif
2074#if ENABLE_HUSH_LOOPS
2039 if (rword == RES_FOR && pi->num_progs) { 2075 if (rword == RES_FOR && pi->num_progs) {
2040 if (!for_lcur) { 2076 if (!for_lcur) {
2041 /* if no variable values after "in" we skip "for" */ 2077 /* if no variable values after "in" we skip "for" */
@@ -2075,6 +2111,7 @@ static int run_list_real(struct pipe *pi)
2075 rpipe = NULL; 2111 rpipe = NULL;
2076 } 2112 }
2077 } 2113 }
2114#endif
2078 if (pi->num_progs == 0) 2115 if (pi->num_progs == 0)
2079 continue; 2116 continue;
2080 save_num_progs = pi->num_progs; /* save number of programs */ 2117 save_num_progs = pi->num_progs; /* save number of programs */
@@ -2110,12 +2147,16 @@ static int run_list_real(struct pipe *pi)
2110 debug_printf_exec(": setting last_return_code=%d\n", rcode); 2147 debug_printf_exec(": setting last_return_code=%d\n", rcode);
2111 last_return_code = rcode; 2148 last_return_code = rcode;
2112 pi->num_progs = save_num_progs; /* restore number of programs */ 2149 pi->num_progs = save_num_progs; /* restore number of programs */
2150#if ENABLE_HUSH_IF
2113 if (rword == RES_IF || rword == RES_ELIF) 2151 if (rword == RES_IF || rword == RES_ELIF)
2114 next_if_code = rcode; /* can be overwritten a number of times */ 2152 next_if_code = rcode; /* can be overwritten a number of times */
2153#endif
2154#if ENABLE_HUSH_LOOPS
2115 if (rword == RES_WHILE) 2155 if (rword == RES_WHILE)
2116 flag_rep = !last_return_code; 2156 flag_rep = !last_return_code;
2117 if (rword == RES_UNTIL) 2157 if (rword == RES_UNTIL)
2118 flag_rep = last_return_code; 2158 flag_rep = last_return_code;
2159#endif
2119 if ((rcode == EXIT_SUCCESS && pi->followup == PIPE_OR) 2160 if ((rcode == EXIT_SUCCESS && pi->followup == PIPE_OR)
2120 || (rcode != EXIT_SUCCESS && pi->followup == PIPE_AND) 2161 || (rcode != EXIT_SUCCESS && pi->followup == PIPE_AND)
2121 ) { 2162 ) {
@@ -2811,6 +2852,7 @@ static void initialize_context(struct p_context *ctx)
2811 * should handle if, then, elif, else, fi, for, while, until, do, done. 2852 * should handle if, then, elif, else, fi, for, while, until, do, done.
2812 * case, function, and select are obnoxious, save those for later. 2853 * case, function, and select are obnoxious, save those for later.
2813 */ 2854 */
2855#if ENABLE_HUSH_IF || ENABLE_HUSH_LOOPS
2814static int reserved_word(o_string *dest, struct p_context *ctx) 2856static int reserved_word(o_string *dest, struct p_context *ctx)
2815{ 2857{
2816 struct reserved_combo { 2858 struct reserved_combo {
@@ -2824,17 +2866,21 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
2824 * FLAG_START means the word must start a new compound list. 2866 * FLAG_START means the word must start a new compound list.
2825 */ 2867 */
2826 static const struct reserved_combo reserved_list[] = { 2868 static const struct reserved_combo reserved_list[] = {
2869#if ENABLE_HUSH_IF
2827 { "if", RES_IF, FLAG_THEN | FLAG_START }, 2870 { "if", RES_IF, FLAG_THEN | FLAG_START },
2828 { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI }, 2871 { "then", RES_THEN, FLAG_ELIF | FLAG_ELSE | FLAG_FI },
2829 { "elif", RES_ELIF, FLAG_THEN }, 2872 { "elif", RES_ELIF, FLAG_THEN },
2830 { "else", RES_ELSE, FLAG_FI }, 2873 { "else", RES_ELSE, FLAG_FI },
2831 { "fi", RES_FI, FLAG_END }, 2874 { "fi", RES_FI, FLAG_END },
2875#endif
2876#if ENABLE_HUSH_LOOPS
2832 { "for", RES_FOR, FLAG_IN | FLAG_START }, 2877 { "for", RES_FOR, FLAG_IN | FLAG_START },
2833 { "while", RES_WHILE, FLAG_DO | FLAG_START }, 2878 { "while", RES_WHILE, FLAG_DO | FLAG_START },
2834 { "until", RES_UNTIL, FLAG_DO | FLAG_START }, 2879 { "until", RES_UNTIL, FLAG_DO | FLAG_START },
2835 { "in", RES_IN, FLAG_DO }, 2880 { "in", RES_IN, FLAG_DO },
2836 { "do", RES_DO, FLAG_DONE }, 2881 { "do", RES_DO, FLAG_DONE },
2837 { "done", RES_DONE, FLAG_END } 2882 { "done", RES_DONE, FLAG_END }
2883#endif
2838 }; 2884 };
2839 enum { NRES = sizeof(reserved_list)/sizeof(reserved_list[0]) }; 2885 enum { NRES = sizeof(reserved_list)/sizeof(reserved_list[0]) };
2840 const struct reserved_combo *r; 2886 const struct reserved_combo *r;
@@ -2845,6 +2891,7 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
2845 if (r->flag & FLAG_START) { 2891 if (r->flag & FLAG_START) {
2846 struct p_context *new = xmalloc(sizeof(struct p_context)); 2892 struct p_context *new = xmalloc(sizeof(struct p_context));
2847 debug_printf("push stack\n"); 2893 debug_printf("push stack\n");
2894#if ENABLE_HUSH_LOOPS
2848 if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) { 2895 if (ctx->res_w == RES_IN || ctx->res_w == RES_FOR) {
2849 syntax(); 2896 syntax();
2850 free(new); 2897 free(new);
@@ -2852,6 +2899,7 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
2852 b_reset(dest); 2899 b_reset(dest);
2853 return 1; 2900 return 1;
2854 } 2901 }
2902#endif
2855 *new = *ctx; /* physical copy */ 2903 *new = *ctx; /* physical copy */
2856 initialize_context(ctx); 2904 initialize_context(ctx);
2857 ctx->stack = new; 2905 ctx->stack = new;
@@ -2879,6 +2927,9 @@ static int reserved_word(o_string *dest, struct p_context *ctx)
2879 } 2927 }
2880 return 0; 2928 return 0;
2881} 2929}
2930#else
2931#define reserved_word(dest, ctx) ((int)0)
2932#endif
2882 2933
2883/* Normal return is 0. 2934/* Normal return is 0.
2884 * Syntax or xglob errors return 1. */ 2935 * Syntax or xglob errors return 1. */
@@ -2929,10 +2980,12 @@ static int done_word(o_string *dest, struct p_context *ctx)
2929 } else { 2980 } else {
2930 child->argv = glob_target->gl_pathv; 2981 child->argv = glob_target->gl_pathv;
2931 } 2982 }
2983#if ENABLE_HUSH_LOOPS
2932 if (ctx->res_w == RES_FOR) { 2984 if (ctx->res_w == RES_FOR) {
2933 done_word(dest, ctx); 2985 done_word(dest, ctx);
2934 done_pipe(ctx, PIPE_SEQ); 2986 done_pipe(ctx, PIPE_SEQ);
2935 } 2987 }
2988#endif
2936 debug_printf_parse("done_word return 0\n"); 2989 debug_printf_parse("done_word return 0\n");
2937 return 0; 2990 return 0;
2938} 2991}