aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-04-27 07:26:12 +0000
committerEric Andersen <andersen@codepoet.org>2001-04-27 07:26:12 +0000
commitaf44a0e8f459bd0aa98961b87f6dff07d139d618 (patch)
tree827a7202f8c22e2bda4c6d2c8cbaba7c18e2288a
parent0081466925ec6224eae13f0702f2df719237de6e (diff)
downloadbusybox-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.c114
-rw-r--r--shell/hush.c114
2 files changed, 40 insertions, 188 deletions
diff --git a/hush.c b/hush.c
index f2a4ea410..cec2549be 100644
--- a/hush.c
+++ b/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
121extern 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
132extern void usage(const char *usage)
133{
134 fprintf(stderr, "Usage: %s\n", usage);
135 exit(EXIT_FAILURE);
136}
137
138static 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
146extern 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
155extern 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
165static 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
177extern 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
186extern 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
196FILE *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
205typedef enum { 120typedef 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;
331static int interactive=0; 247static int interactive=0;
332static struct close_me *close_me_head = NULL; 248static struct close_me *close_me_head = NULL;
333static char *cwd; 249static char *cwd;
334static struct jobset job_list = { NULL, NULL }; 250/* static struct jobset job_list = { NULL, NULL }; */
335static unsigned int last_bg_pid=0; 251static unsigned int last_bg_pid=0;
336static char *PS1; 252static char *PS1;
337static char *PS2 = "> "; 253static char *PS2 = "> ";
@@ -843,6 +759,7 @@ static inline void cmdedit_set_initial_prompt(void)
843 759
844static inline void setup_prompt_string(int promptmode, char **prompt_str) 760static 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
862static void get_user_input(struct in_str *i) 780static 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
121extern 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
132extern void usage(const char *usage)
133{
134 fprintf(stderr, "Usage: %s\n", usage);
135 exit(EXIT_FAILURE);
136}
137
138static 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
146extern 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
155extern 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
165static 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
177extern 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
186extern 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
196FILE *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
205typedef enum { 120typedef 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;
331static int interactive=0; 247static int interactive=0;
332static struct close_me *close_me_head = NULL; 248static struct close_me *close_me_head = NULL;
333static char *cwd; 249static char *cwd;
334static struct jobset job_list = { NULL, NULL }; 250/* static struct jobset job_list = { NULL, NULL }; */
335static unsigned int last_bg_pid=0; 251static unsigned int last_bg_pid=0;
336static char *PS1; 252static char *PS1;
337static char *PS2 = "> "; 253static char *PS2 = "> ";
@@ -843,6 +759,7 @@ static inline void cmdedit_set_initial_prompt(void)
843 759
844static inline void setup_prompt_string(int promptmode, char **prompt_str) 760static 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
862static void get_user_input(struct in_str *i) 780static 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! */