diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-07 09:18:30 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-10-07 09:18:30 +0000 |
commit | 834dee785df541c938b8b2a19ccb3c0d96a4aa14 (patch) | |
tree | 397156f429dc65724ced1d8493e4087cb99337da | |
parent | 176d49d4f7bd1c049211c704018b1ac9d432f52e (diff) | |
download | busybox-w32-834dee785df541c938b8b2a19ccb3c0d96a4aa14.tar.gz busybox-w32-834dee785df541c938b8b2a19ccb3c0d96a4aa14.tar.bz2 busybox-w32-834dee785df541c938b8b2a19ccb3c0d96a4aa14.zip |
ash: support &> redirection (bashism). ~90 bytes of code
-rw-r--r-- | shell/ash.c | 117 |
1 files changed, 68 insertions, 49 deletions
diff --git a/shell/ash.c b/shell/ash.c index 962d5be02..70b7ae32a 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2572,34 +2572,36 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
2572 | 2572 | ||
2573 | /* ============ ... */ | 2573 | /* ============ ... */ |
2574 | 2574 | ||
2575 | |||
2575 | #define IBUFSIZ COMMON_BUFSIZE | 2576 | #define IBUFSIZ COMMON_BUFSIZE |
2576 | #define basebuf bb_common_bufsiz1 /* buffer for top level input file */ | 2577 | /* buffer for top level input file */ |
2578 | #define basebuf bb_common_bufsiz1 | ||
2577 | 2579 | ||
2578 | /* Syntax classes */ | 2580 | /* Syntax classes */ |
2579 | #define CWORD 0 /* character is nothing special */ | 2581 | #define CWORD 0 /* character is nothing special */ |
2580 | #define CNL 1 /* newline character */ | 2582 | #define CNL 1 /* newline character */ |
2581 | #define CBACK 2 /* a backslash character */ | 2583 | #define CBACK 2 /* a backslash character */ |
2582 | #define CSQUOTE 3 /* single quote */ | 2584 | #define CSQUOTE 3 /* single quote */ |
2583 | #define CDQUOTE 4 /* double quote */ | 2585 | #define CDQUOTE 4 /* double quote */ |
2584 | #define CENDQUOTE 5 /* a terminating quote */ | 2586 | #define CENDQUOTE 5 /* a terminating quote */ |
2585 | #define CBQUOTE 6 /* backwards single quote */ | 2587 | #define CBQUOTE 6 /* backwards single quote */ |
2586 | #define CVAR 7 /* a dollar sign */ | 2588 | #define CVAR 7 /* a dollar sign */ |
2587 | #define CENDVAR 8 /* a '}' character */ | 2589 | #define CENDVAR 8 /* a '}' character */ |
2588 | #define CLP 9 /* a left paren in arithmetic */ | 2590 | #define CLP 9 /* a left paren in arithmetic */ |
2589 | #define CRP 10 /* a right paren in arithmetic */ | 2591 | #define CRP 10 /* a right paren in arithmetic */ |
2590 | #define CENDFILE 11 /* end of file */ | 2592 | #define CENDFILE 11 /* end of file */ |
2591 | #define CCTL 12 /* like CWORD, except it must be escaped */ | 2593 | #define CCTL 12 /* like CWORD, except it must be escaped */ |
2592 | #define CSPCL 13 /* these terminate a word */ | 2594 | #define CSPCL 13 /* these terminate a word */ |
2593 | #define CIGN 14 /* character should be ignored */ | 2595 | #define CIGN 14 /* character should be ignored */ |
2594 | 2596 | ||
2595 | #if ENABLE_ASH_ALIAS | 2597 | #if ENABLE_ASH_ALIAS |
2596 | #define SYNBASE 130 | 2598 | #define SYNBASE 130 |
2597 | #define PEOF -130 | 2599 | #define PEOF -130 |
2598 | #define PEOA -129 | 2600 | #define PEOA -129 |
2599 | #define PEOA_OR_PEOF PEOA | 2601 | #define PEOA_OR_PEOF PEOA |
2600 | #else | 2602 | #else |
2601 | #define SYNBASE 129 | 2603 | #define SYNBASE 129 |
2602 | #define PEOF -129 | 2604 | #define PEOF -129 |
2603 | #define PEOA_OR_PEOF PEOF | 2605 | #define PEOA_OR_PEOF PEOF |
2604 | #endif | 2606 | #endif |
2605 | 2607 | ||
@@ -9269,7 +9271,7 @@ preadbuffer(void) | |||
9269 | return signed_char2int(*parsenextc++); | 9271 | return signed_char2int(*parsenextc++); |
9270 | } | 9272 | } |
9271 | 9273 | ||
9272 | #define pgetc_as_macro() (--parsenleft >= 0? signed_char2int(*parsenextc++) : preadbuffer()) | 9274 | #define pgetc_as_macro() (--parsenleft >= 0 ? signed_char2int(*parsenextc++) : preadbuffer()) |
9273 | static int | 9275 | static int |
9274 | pgetc(void) | 9276 | pgetc(void) |
9275 | { | 9277 | { |
@@ -9277,9 +9279,9 @@ pgetc(void) | |||
9277 | } | 9279 | } |
9278 | 9280 | ||
9279 | #if ENABLE_ASH_OPTIMIZE_FOR_SIZE | 9281 | #if ENABLE_ASH_OPTIMIZE_FOR_SIZE |
9280 | #define pgetc_macro() pgetc() | 9282 | #define pgetc_fast() pgetc() |
9281 | #else | 9283 | #else |
9282 | #define pgetc_macro() pgetc_as_macro() | 9284 | #define pgetc_fast() pgetc_as_macro() |
9283 | #endif | 9285 | #endif |
9284 | 9286 | ||
9285 | /* | 9287 | /* |
@@ -9290,18 +9292,13 @@ static int | |||
9290 | pgetc2(void) | 9292 | pgetc2(void) |
9291 | { | 9293 | { |
9292 | int c; | 9294 | int c; |
9293 | |||
9294 | do { | 9295 | do { |
9295 | c = pgetc_macro(); | 9296 | c = pgetc_fast(); |
9296 | } while (c == PEOA); | 9297 | } while (c == PEOA); |
9297 | return c; | 9298 | return c; |
9298 | } | 9299 | } |
9299 | #else | 9300 | #else |
9300 | static int | 9301 | #define pgetc2() pgetc() |
9301 | pgetc2(void) | ||
9302 | { | ||
9303 | return pgetc_macro(); | ||
9304 | } | ||
9305 | #endif | 9302 | #endif |
9306 | 9303 | ||
9307 | /* | 9304 | /* |
@@ -9355,7 +9352,6 @@ pushstring(char *s, struct alias *ap) | |||
9355 | 9352 | ||
9356 | len = strlen(s); | 9353 | len = strlen(s); |
9357 | INT_OFF; | 9354 | INT_OFF; |
9358 | /*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ | ||
9359 | if (g_parsefile->strpush) { | 9355 | if (g_parsefile->strpush) { |
9360 | sp = ckzalloc(sizeof(struct strpush)); | 9356 | sp = ckzalloc(sizeof(struct strpush)); |
9361 | sp->prev = g_parsefile->strpush; | 9357 | sp->prev = g_parsefile->strpush; |
@@ -10800,15 +10796,23 @@ readtoken1(int firstc, int syntax, char *eofmark, int striptabs) | |||
10800 | case CIGN: | 10796 | case CIGN: |
10801 | break; | 10797 | break; |
10802 | default: | 10798 | default: |
10803 | if (varnest == 0) | 10799 | if (varnest == 0) { |
10800 | #if ENABLE_ASH_BASH_COMPAT | ||
10801 | if (c == '&') { | ||
10802 | if (pgetc() == '>') | ||
10803 | c = 0x100 + '>'; /* flag &> */ | ||
10804 | pungetc(); | ||
10805 | } | ||
10806 | #endif | ||
10804 | goto endword; /* exit outer loop */ | 10807 | goto endword; /* exit outer loop */ |
10808 | } | ||
10805 | #if ENABLE_ASH_ALIAS | 10809 | #if ENABLE_ASH_ALIAS |
10806 | if (c != PEOA) | 10810 | if (c != PEOA) |
10807 | #endif | 10811 | #endif |
10808 | USTPUTC(c, out); | 10812 | USTPUTC(c, out); |
10809 | 10813 | ||
10810 | } | 10814 | } |
10811 | c = pgetc_macro(); | 10815 | c = pgetc_fast(); |
10812 | } /* for (;;) */ | 10816 | } /* for (;;) */ |
10813 | } | 10817 | } |
10814 | endword: | 10818 | endword: |
@@ -10827,7 +10831,9 @@ readtoken1(int firstc, int syntax, char *eofmark, int striptabs) | |||
10827 | len = out - (char *)stackblock(); | 10831 | len = out - (char *)stackblock(); |
10828 | out = stackblock(); | 10832 | out = stackblock(); |
10829 | if (eofmark == NULL) { | 10833 | if (eofmark == NULL) { |
10830 | if ((c == '>' || c == '<') && quotef == 0) { | 10834 | if ((c == '>' || c == '<' USE_ASH_BASH_COMPAT( || c == 0x100 + '>')) |
10835 | && quotef == 0 | ||
10836 | ) { | ||
10831 | if (isdigit_str9(out)) { | 10837 | if (isdigit_str9(out)) { |
10832 | PARSEREDIR(); /* passed as params: out, c */ | 10838 | PARSEREDIR(); /* passed as params: out, c */ |
10833 | lasttoken = TREDIR; | 10839 | lasttoken = TREDIR; |
@@ -10908,7 +10914,15 @@ parseredir: { | |||
10908 | np->type = NTO; | 10914 | np->type = NTO; |
10909 | pungetc(); | 10915 | pungetc(); |
10910 | } | 10916 | } |
10911 | } else { /* c == '<' */ | 10917 | } |
10918 | #if ENABLE_ASH_BASH_COMPAT | ||
10919 | else if (c == 0x100 + '>') { /* this flags &> redirection */ | ||
10920 | np->nfile.fd = 1; | ||
10921 | pgetc(); /* this is '>', no need to check */ | ||
10922 | np->type = NTO2; | ||
10923 | } | ||
10924 | #endif | ||
10925 | else { /* c == '<' */ | ||
10912 | /*np->nfile.fd = 0; - stzalloc did it */ | 10926 | /*np->nfile.fd = 0; - stzalloc did it */ |
10913 | c = pgetc(); | 10927 | c = pgetc(); |
10914 | switch (c) { | 10928 | switch (c) { |
@@ -11281,9 +11295,14 @@ parsearith: { | |||
11281 | #ifdef NEW_xxreadtoken | 11295 | #ifdef NEW_xxreadtoken |
11282 | /* singles must be first! */ | 11296 | /* singles must be first! */ |
11283 | static const char xxreadtoken_chars[7] ALIGN1 = { | 11297 | static const char xxreadtoken_chars[7] ALIGN1 = { |
11284 | '\n', '(', ')', '&', '|', ';', 0 | 11298 | '\n', '(', ')', /* singles */ |
11299 | '&', '|', ';', /* doubles */ | ||
11300 | 0 | ||
11285 | }; | 11301 | }; |
11286 | 11302 | ||
11303 | #define xxreadtoken_singles 3 | ||
11304 | #define xxreadtoken_doubles 3 | ||
11305 | |||
11287 | static const char xxreadtoken_tokens[] ALIGN1 = { | 11306 | static const char xxreadtoken_tokens[] ALIGN1 = { |
11288 | TNL, TLP, TRP, /* only single occurrence allowed */ | 11307 | TNL, TLP, TRP, /* only single occurrence allowed */ |
11289 | TBACKGND, TPIPE, TSEMI, /* if single occurrence */ | 11308 | TBACKGND, TPIPE, TSEMI, /* if single occurrence */ |
@@ -11291,11 +11310,6 @@ static const char xxreadtoken_tokens[] ALIGN1 = { | |||
11291 | TAND, TOR, TENDCASE /* if double occurrence */ | 11310 | TAND, TOR, TENDCASE /* if double occurrence */ |
11292 | }; | 11311 | }; |
11293 | 11312 | ||
11294 | #define xxreadtoken_doubles \ | ||
11295 | (sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars)) | ||
11296 | #define xxreadtoken_singles \ | ||
11297 | (sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1) | ||
11298 | |||
11299 | static int | 11313 | static int |
11300 | xxreadtoken(void) | 11314 | xxreadtoken(void) |
11301 | { | 11315 | { |
@@ -11310,7 +11324,7 @@ xxreadtoken(void) | |||
11310 | } | 11324 | } |
11311 | startlinno = plinno; | 11325 | startlinno = plinno; |
11312 | for (;;) { /* until token or start of word found */ | 11326 | for (;;) { /* until token or start of word found */ |
11313 | c = pgetc_macro(); | 11327 | c = pgetc_fast(); |
11314 | if (c == ' ' || c == '\t' USE_ASH_ALIAS( || c == PEOA)) | 11328 | if (c == ' ' || c == '\t' USE_ASH_ALIAS( || c == PEOA)) |
11315 | continue; | 11329 | continue; |
11316 | 11330 | ||
@@ -11321,7 +11335,7 @@ xxreadtoken(void) | |||
11321 | } else if (c == '\\') { | 11335 | } else if (c == '\\') { |
11322 | if (pgetc() != '\n') { | 11336 | if (pgetc() != '\n') { |
11323 | pungetc(); | 11337 | pungetc(); |
11324 | goto READTOKEN1; | 11338 | break; /* return readtoken1(...) */ |
11325 | } | 11339 | } |
11326 | startlinno = ++plinno; | 11340 | startlinno = ++plinno; |
11327 | if (doprompt) | 11341 | if (doprompt) |
@@ -11337,16 +11351,19 @@ xxreadtoken(void) | |||
11337 | } | 11351 | } |
11338 | 11352 | ||
11339 | p = strchr(xxreadtoken_chars, c); | 11353 | p = strchr(xxreadtoken_chars, c); |
11340 | if (p == NULL) { | 11354 | if (p == NULL) |
11341 | READTOKEN1: | 11355 | break; /* return readtoken1(...) */ |
11342 | return readtoken1(c, BASESYNTAX, (char *) NULL, 0); | ||
11343 | } | ||
11344 | 11356 | ||
11345 | if ((size_t)(p - xxreadtoken_chars) >= xxreadtoken_singles) { | 11357 | if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) { |
11346 | if (pgetc() == *p) { /* double occurrence? */ | 11358 | int cc = pgetc(); |
11359 | if (cc == c) { /* double occurrence? */ | ||
11347 | p += xxreadtoken_doubles + 1; | 11360 | p += xxreadtoken_doubles + 1; |
11348 | } else { | 11361 | } else { |
11349 | pungetc(); | 11362 | pungetc(); |
11363 | #if ENABLE_ASH_BASH_COMPAT | ||
11364 | if (c == '&' && cc == '>') /* &> */ | ||
11365 | break; /* return readtoken1(...) */ | ||
11366 | #endif | ||
11350 | } | 11367 | } |
11351 | } | 11368 | } |
11352 | } | 11369 | } |
@@ -11354,6 +11371,8 @@ xxreadtoken(void) | |||
11354 | return lasttoken; | 11371 | return lasttoken; |
11355 | } | 11372 | } |
11356 | } /* for (;;) */ | 11373 | } /* for (;;) */ |
11374 | |||
11375 | return readtoken1(c, BASESYNTAX, (char *) NULL, 0); | ||
11357 | } | 11376 | } |
11358 | #else /* old xxreadtoken */ | 11377 | #else /* old xxreadtoken */ |
11359 | #define RETURN(token) return lasttoken = token | 11378 | #define RETURN(token) return lasttoken = token |
@@ -11371,7 +11390,7 @@ xxreadtoken(void) | |||
11371 | } | 11390 | } |
11372 | startlinno = plinno; | 11391 | startlinno = plinno; |
11373 | for (;;) { /* until token or start of word found */ | 11392 | for (;;) { /* until token or start of word found */ |
11374 | c = pgetc_macro(); | 11393 | c = pgetc_fast(); |
11375 | switch (c) { | 11394 | switch (c) { |
11376 | case ' ': case '\t': | 11395 | case ' ': case '\t': |
11377 | #if ENABLE_ASH_ALIAS | 11396 | #if ENABLE_ASH_ALIAS |