diff options
author | Eric Andersen <andersen@codepoet.org> | 2001-04-27 07:26:12 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2001-04-27 07:26:12 +0000 |
commit | af44a0e8f459bd0aa98961b87f6dff07d139d618 (patch) | |
tree | 827a7202f8c22e2bda4c6d2c8cbaba7c18e2288a | |
parent | 0081466925ec6224eae13f0702f2df719237de6e (diff) | |
download | busybox-w32-af44a0e8f459bd0aa98961b87f6dff07d139d618.tar.gz busybox-w32-af44a0e8f459bd0aa98961b87f6dff07d139d618.tar.bz2 busybox-w32-af44a0e8f459bd0aa98961b87f6dff07d139d618.zip |
An update to hush from Larry:
It should recover more smoothly from syntax errors, and it now
has a decent guess when the reserved word construct is over
(or not) to control execution and prompting. I took out all the
redundant standalone test copies of libbb routines, but left in a
hook so I can include those for my testing. I'll post that include
file on my web site.
- Larry
-rw-r--r-- | hush.c | 114 | ||||
-rw-r--r-- | shell/hush.c | 114 |
2 files changed, 40 insertions, 188 deletions
@@ -111,96 +111,11 @@ | |||
111 | #include "busybox.h" | 111 | #include "busybox.h" |
112 | #include "cmdedit.h" | 112 | #include "cmdedit.h" |
113 | #else | 113 | #else |
114 | /* in place of #include "busybox.h"; much of this is indeed | ||
115 | * pasted in from the copy of busybox.h in busybox-0.49pre */ | ||
116 | |||
117 | #define xrealloc realloc | ||
118 | #define applet_name "hush" | 114 | #define applet_name "hush" |
115 | #include "standalone.h" | ||
119 | #define shell_main main | 116 | #define shell_main main |
120 | 117 | #define BB_FEATURE_SH_SIMPLE_PROMPT | |
121 | extern void *xmalloc(size_t size) | 118 | #endif |
122 | { | ||
123 | void *ptr = malloc(size); | ||
124 | |||
125 | if (!ptr) { | ||
126 | fprintf(stderr, "memory_exhausted\n"); | ||
127 | exit (EXIT_FAILURE); | ||
128 | } | ||
129 | return ptr; | ||
130 | } | ||
131 | |||
132 | extern void usage(const char *usage) | ||
133 | { | ||
134 | fprintf(stderr, "Usage: %s\n", usage); | ||
135 | exit(EXIT_FAILURE); | ||
136 | } | ||
137 | |||
138 | static void verror_msg(const char *s, va_list p) | ||
139 | { | ||
140 | fflush(stdout); | ||
141 | fprintf(stderr, "%s: ", applet_name); | ||
142 | vfprintf(stderr, s, p); | ||
143 | fflush(stderr); | ||
144 | } | ||
145 | |||
146 | extern void error_msg(const char *s, ...) | ||
147 | { | ||
148 | va_list p; | ||
149 | |||
150 | va_start(p, s); | ||
151 | verror_msg(s, p); | ||
152 | va_end(p); | ||
153 | } | ||
154 | |||
155 | extern void error_msg_and_die(const char *s, ...) | ||
156 | { | ||
157 | va_list p; | ||
158 | |||
159 | va_start(p, s); | ||
160 | verror_msg(s, p); | ||
161 | va_end(p); | ||
162 | exit(EXIT_FAILURE); | ||
163 | } | ||
164 | |||
165 | static void vperror_msg(const char *s, va_list p) | ||
166 | { | ||
167 | fflush(stdout); | ||
168 | fprintf(stderr, "%s: ", applet_name); | ||
169 | if (s && *s) { | ||
170 | vfprintf(stderr, s, p); | ||
171 | fputs(": ", stderr); | ||
172 | } | ||
173 | fprintf(stderr, "%s\n", strerror(errno)); | ||
174 | fflush(stderr); | ||
175 | } | ||
176 | |||
177 | extern void perror_msg(const char *s, ...) | ||
178 | { | ||
179 | va_list p; | ||
180 | |||
181 | va_start(p, s); | ||
182 | vperror_msg(s, p); | ||
183 | va_end(p); | ||
184 | } | ||
185 | |||
186 | extern void perror_msg_and_die(const char *s, ...) | ||
187 | { | ||
188 | va_list p; | ||
189 | |||
190 | va_start(p, s); | ||
191 | vperror_msg(s, p); | ||
192 | va_end(p); | ||
193 | exit(EXIT_FAILURE); | ||
194 | } | ||
195 | |||
196 | FILE *xfopen(const char *path, const char *mode) | ||
197 | { | ||
198 | FILE *fp; | ||
199 | if ((fp = fopen(path, mode)) == NULL) | ||
200 | perror_msg_and_die(path); | ||
201 | return fp; | ||
202 | } | ||
203 | #endif /* of busybox.h replacement */ | ||
204 | 119 | ||
205 | typedef enum { | 120 | typedef enum { |
206 | REDIRECT_INPUT = 1, | 121 | REDIRECT_INPUT = 1, |
@@ -241,7 +156,8 @@ typedef enum { | |||
241 | RES_UNTIL = 8, | 156 | RES_UNTIL = 8, |
242 | RES_DO = 9, | 157 | RES_DO = 9, |
243 | RES_DONE = 10, | 158 | RES_DONE = 10, |
244 | RES_XXXX = 11 | 159 | RES_XXXX = 11, |
160 | RES_SNTX = 12 | ||
245 | } reserved_style; | 161 | } reserved_style; |
246 | #define FLAG_END (1<<RES_NONE) | 162 | #define FLAG_END (1<<RES_NONE) |
247 | #define FLAG_IF (1<<RES_IF) | 163 | #define FLAG_IF (1<<RES_IF) |
@@ -331,7 +247,7 @@ static int fake_mode=0; | |||
331 | static int interactive=0; | 247 | static int interactive=0; |
332 | static struct close_me *close_me_head = NULL; | 248 | static struct close_me *close_me_head = NULL; |
333 | static char *cwd; | 249 | static char *cwd; |
334 | static struct jobset job_list = { NULL, NULL }; | 250 | /* static struct jobset job_list = { NULL, NULL }; */ |
335 | static unsigned int last_bg_pid=0; | 251 | static unsigned int last_bg_pid=0; |
336 | static char *PS1; | 252 | static char *PS1; |
337 | static char *PS2 = "> "; | 253 | static char *PS2 = "> "; |
@@ -843,6 +759,7 @@ static inline void cmdedit_set_initial_prompt(void) | |||
843 | 759 | ||
844 | static inline void setup_prompt_string(int promptmode, char **prompt_str) | 760 | static inline void setup_prompt_string(int promptmode, char **prompt_str) |
845 | { | 761 | { |
762 | debug_printf("setup_prompt_string %d ",promptmode); | ||
846 | #ifdef BB_FEATURE_SH_SIMPLE_PROMPT | 763 | #ifdef BB_FEATURE_SH_SIMPLE_PROMPT |
847 | /* Set up the prompt */ | 764 | /* Set up the prompt */ |
848 | if (promptmode == 1) { | 765 | if (promptmode == 1) { |
@@ -856,7 +773,8 @@ static inline void setup_prompt_string(int promptmode, char **prompt_str) | |||
856 | } | 773 | } |
857 | #else | 774 | #else |
858 | *prompt_str = (promptmode==0)? PS1 : PS2; | 775 | *prompt_str = (promptmode==0)? PS1 : PS2; |
859 | #endif | 776 | #endif |
777 | debug_printf("result %s\n",*prompt_str); | ||
860 | } | 778 | } |
861 | 779 | ||
862 | static void get_user_input(struct in_str *i) | 780 | static void get_user_input(struct in_str *i) |
@@ -1537,7 +1455,10 @@ int reserved_word(o_string *dest, struct p_context *ctx) | |||
1537 | initialize_context(ctx); | 1455 | initialize_context(ctx); |
1538 | ctx->stack=new; | 1456 | ctx->stack=new; |
1539 | } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) { | 1457 | } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) { |
1540 | syntax(); /* XXX how do we get out? */ | 1458 | syntax(); |
1459 | ctx->w = RES_SNTX; | ||
1460 | b_reset (dest); | ||
1461 | return 1; | ||
1541 | } | 1462 | } |
1542 | ctx->w=r->code; | 1463 | ctx->w=r->code; |
1543 | ctx->old_flag = r->flag; | 1464 | ctx->old_flag = r->flag; |
@@ -1579,7 +1500,7 @@ static int done_word(o_string *dest, struct p_context *ctx) | |||
1579 | } | 1500 | } |
1580 | if (!child->argv) { | 1501 | if (!child->argv) { |
1581 | debug_printf("checking %s for reserved-ness\n",dest->data); | 1502 | debug_printf("checking %s for reserved-ness\n",dest->data); |
1582 | if (reserved_word(dest,ctx)) return 0; | 1503 | if (reserved_word(dest,ctx)) return ctx->w==RES_SNTX; |
1583 | } | 1504 | } |
1584 | glob_target = &child->glob_result; | 1505 | glob_target = &child->glob_result; |
1585 | if (child->argv) flags |= GLOB_APPEND; | 1506 | if (child->argv) flags |= GLOB_APPEND; |
@@ -1921,11 +1842,16 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1921 | ch,ch,m,dest->quote); | 1842 | ch,ch,m,dest->quote); |
1922 | if (m==0 || ((m==1 || m==2) && dest->quote)) { | 1843 | if (m==0 || ((m==1 || m==2) && dest->quote)) { |
1923 | b_addqchr(dest, ch, dest->quote); | 1844 | b_addqchr(dest, ch, dest->quote); |
1924 | } else if (ch == end_trigger && !dest->quote) { | 1845 | } else if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { |
1925 | debug_printf("leaving parse_stream\n"); | 1846 | debug_printf("leaving parse_stream\n"); |
1926 | return 0; | 1847 | return 0; |
1927 | } else if (m==2 && !dest->quote) { /* IFS */ | 1848 | } else if (m==2 && !dest->quote) { /* IFS */ |
1928 | done_word(dest, ctx); | 1849 | done_word(dest, ctx); |
1850 | if (ch=='\n') done_pipe(ctx,PIPE_SEQ); | ||
1851 | if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { | ||
1852 | debug_printf("leaving parse_stream (stupid duplication)\n"); | ||
1853 | return 0; | ||
1854 | } | ||
1929 | #if 0 | 1855 | #if 0 |
1930 | if (ch=='\n') { | 1856 | if (ch=='\n') { |
1931 | /* Yahoo! Time to run with it! */ | 1857 | /* Yahoo! Time to run with it! */ |
diff --git a/shell/hush.c b/shell/hush.c index f2a4ea410..cec2549be 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -111,96 +111,11 @@ | |||
111 | #include "busybox.h" | 111 | #include "busybox.h" |
112 | #include "cmdedit.h" | 112 | #include "cmdedit.h" |
113 | #else | 113 | #else |
114 | /* in place of #include "busybox.h"; much of this is indeed | ||
115 | * pasted in from the copy of busybox.h in busybox-0.49pre */ | ||
116 | |||
117 | #define xrealloc realloc | ||
118 | #define applet_name "hush" | 114 | #define applet_name "hush" |
115 | #include "standalone.h" | ||
119 | #define shell_main main | 116 | #define shell_main main |
120 | 117 | #define BB_FEATURE_SH_SIMPLE_PROMPT | |
121 | extern void *xmalloc(size_t size) | 118 | #endif |
122 | { | ||
123 | void *ptr = malloc(size); | ||
124 | |||
125 | if (!ptr) { | ||
126 | fprintf(stderr, "memory_exhausted\n"); | ||
127 | exit (EXIT_FAILURE); | ||
128 | } | ||
129 | return ptr; | ||
130 | } | ||
131 | |||
132 | extern void usage(const char *usage) | ||
133 | { | ||
134 | fprintf(stderr, "Usage: %s\n", usage); | ||
135 | exit(EXIT_FAILURE); | ||
136 | } | ||
137 | |||
138 | static void verror_msg(const char *s, va_list p) | ||
139 | { | ||
140 | fflush(stdout); | ||
141 | fprintf(stderr, "%s: ", applet_name); | ||
142 | vfprintf(stderr, s, p); | ||
143 | fflush(stderr); | ||
144 | } | ||
145 | |||
146 | extern void error_msg(const char *s, ...) | ||
147 | { | ||
148 | va_list p; | ||
149 | |||
150 | va_start(p, s); | ||
151 | verror_msg(s, p); | ||
152 | va_end(p); | ||
153 | } | ||
154 | |||
155 | extern void error_msg_and_die(const char *s, ...) | ||
156 | { | ||
157 | va_list p; | ||
158 | |||
159 | va_start(p, s); | ||
160 | verror_msg(s, p); | ||
161 | va_end(p); | ||
162 | exit(EXIT_FAILURE); | ||
163 | } | ||
164 | |||
165 | static void vperror_msg(const char *s, va_list p) | ||
166 | { | ||
167 | fflush(stdout); | ||
168 | fprintf(stderr, "%s: ", applet_name); | ||
169 | if (s && *s) { | ||
170 | vfprintf(stderr, s, p); | ||
171 | fputs(": ", stderr); | ||
172 | } | ||
173 | fprintf(stderr, "%s\n", strerror(errno)); | ||
174 | fflush(stderr); | ||
175 | } | ||
176 | |||
177 | extern void perror_msg(const char *s, ...) | ||
178 | { | ||
179 | va_list p; | ||
180 | |||
181 | va_start(p, s); | ||
182 | vperror_msg(s, p); | ||
183 | va_end(p); | ||
184 | } | ||
185 | |||
186 | extern void perror_msg_and_die(const char *s, ...) | ||
187 | { | ||
188 | va_list p; | ||
189 | |||
190 | va_start(p, s); | ||
191 | vperror_msg(s, p); | ||
192 | va_end(p); | ||
193 | exit(EXIT_FAILURE); | ||
194 | } | ||
195 | |||
196 | FILE *xfopen(const char *path, const char *mode) | ||
197 | { | ||
198 | FILE *fp; | ||
199 | if ((fp = fopen(path, mode)) == NULL) | ||
200 | perror_msg_and_die(path); | ||
201 | return fp; | ||
202 | } | ||
203 | #endif /* of busybox.h replacement */ | ||
204 | 119 | ||
205 | typedef enum { | 120 | typedef enum { |
206 | REDIRECT_INPUT = 1, | 121 | REDIRECT_INPUT = 1, |
@@ -241,7 +156,8 @@ typedef enum { | |||
241 | RES_UNTIL = 8, | 156 | RES_UNTIL = 8, |
242 | RES_DO = 9, | 157 | RES_DO = 9, |
243 | RES_DONE = 10, | 158 | RES_DONE = 10, |
244 | RES_XXXX = 11 | 159 | RES_XXXX = 11, |
160 | RES_SNTX = 12 | ||
245 | } reserved_style; | 161 | } reserved_style; |
246 | #define FLAG_END (1<<RES_NONE) | 162 | #define FLAG_END (1<<RES_NONE) |
247 | #define FLAG_IF (1<<RES_IF) | 163 | #define FLAG_IF (1<<RES_IF) |
@@ -331,7 +247,7 @@ static int fake_mode=0; | |||
331 | static int interactive=0; | 247 | static int interactive=0; |
332 | static struct close_me *close_me_head = NULL; | 248 | static struct close_me *close_me_head = NULL; |
333 | static char *cwd; | 249 | static char *cwd; |
334 | static struct jobset job_list = { NULL, NULL }; | 250 | /* static struct jobset job_list = { NULL, NULL }; */ |
335 | static unsigned int last_bg_pid=0; | 251 | static unsigned int last_bg_pid=0; |
336 | static char *PS1; | 252 | static char *PS1; |
337 | static char *PS2 = "> "; | 253 | static char *PS2 = "> "; |
@@ -843,6 +759,7 @@ static inline void cmdedit_set_initial_prompt(void) | |||
843 | 759 | ||
844 | static inline void setup_prompt_string(int promptmode, char **prompt_str) | 760 | static inline void setup_prompt_string(int promptmode, char **prompt_str) |
845 | { | 761 | { |
762 | debug_printf("setup_prompt_string %d ",promptmode); | ||
846 | #ifdef BB_FEATURE_SH_SIMPLE_PROMPT | 763 | #ifdef BB_FEATURE_SH_SIMPLE_PROMPT |
847 | /* Set up the prompt */ | 764 | /* Set up the prompt */ |
848 | if (promptmode == 1) { | 765 | if (promptmode == 1) { |
@@ -856,7 +773,8 @@ static inline void setup_prompt_string(int promptmode, char **prompt_str) | |||
856 | } | 773 | } |
857 | #else | 774 | #else |
858 | *prompt_str = (promptmode==0)? PS1 : PS2; | 775 | *prompt_str = (promptmode==0)? PS1 : PS2; |
859 | #endif | 776 | #endif |
777 | debug_printf("result %s\n",*prompt_str); | ||
860 | } | 778 | } |
861 | 779 | ||
862 | static void get_user_input(struct in_str *i) | 780 | static void get_user_input(struct in_str *i) |
@@ -1537,7 +1455,10 @@ int reserved_word(o_string *dest, struct p_context *ctx) | |||
1537 | initialize_context(ctx); | 1455 | initialize_context(ctx); |
1538 | ctx->stack=new; | 1456 | ctx->stack=new; |
1539 | } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) { | 1457 | } else if ( ctx->w == RES_NONE || ! (ctx->old_flag & (1<<r->code))) { |
1540 | syntax(); /* XXX how do we get out? */ | 1458 | syntax(); |
1459 | ctx->w = RES_SNTX; | ||
1460 | b_reset (dest); | ||
1461 | return 1; | ||
1541 | } | 1462 | } |
1542 | ctx->w=r->code; | 1463 | ctx->w=r->code; |
1543 | ctx->old_flag = r->flag; | 1464 | ctx->old_flag = r->flag; |
@@ -1579,7 +1500,7 @@ static int done_word(o_string *dest, struct p_context *ctx) | |||
1579 | } | 1500 | } |
1580 | if (!child->argv) { | 1501 | if (!child->argv) { |
1581 | debug_printf("checking %s for reserved-ness\n",dest->data); | 1502 | debug_printf("checking %s for reserved-ness\n",dest->data); |
1582 | if (reserved_word(dest,ctx)) return 0; | 1503 | if (reserved_word(dest,ctx)) return ctx->w==RES_SNTX; |
1583 | } | 1504 | } |
1584 | glob_target = &child->glob_result; | 1505 | glob_target = &child->glob_result; |
1585 | if (child->argv) flags |= GLOB_APPEND; | 1506 | if (child->argv) flags |= GLOB_APPEND; |
@@ -1921,11 +1842,16 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
1921 | ch,ch,m,dest->quote); | 1842 | ch,ch,m,dest->quote); |
1922 | if (m==0 || ((m==1 || m==2) && dest->quote)) { | 1843 | if (m==0 || ((m==1 || m==2) && dest->quote)) { |
1923 | b_addqchr(dest, ch, dest->quote); | 1844 | b_addqchr(dest, ch, dest->quote); |
1924 | } else if (ch == end_trigger && !dest->quote) { | 1845 | } else if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { |
1925 | debug_printf("leaving parse_stream\n"); | 1846 | debug_printf("leaving parse_stream\n"); |
1926 | return 0; | 1847 | return 0; |
1927 | } else if (m==2 && !dest->quote) { /* IFS */ | 1848 | } else if (m==2 && !dest->quote) { /* IFS */ |
1928 | done_word(dest, ctx); | 1849 | done_word(dest, ctx); |
1850 | if (ch=='\n') done_pipe(ctx,PIPE_SEQ); | ||
1851 | if (ch == end_trigger && !dest->quote && ctx->w==RES_NONE) { | ||
1852 | debug_printf("leaving parse_stream (stupid duplication)\n"); | ||
1853 | return 0; | ||
1854 | } | ||
1929 | #if 0 | 1855 | #if 0 |
1930 | if (ch=='\n') { | 1856 | if (ch=='\n') { |
1931 | /* Yahoo! Time to run with it! */ | 1857 | /* Yahoo! Time to run with it! */ |