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 /shell | |
| 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
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 114 |
1 files changed, 20 insertions, 94 deletions
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! */ |
