aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-10-07 09:18:30 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-10-07 09:18:30 +0000
commit834dee785df541c938b8b2a19ccb3c0d96a4aa14 (patch)
tree397156f429dc65724ced1d8493e4087cb99337da
parent176d49d4f7bd1c049211c704018b1ac9d432f52e (diff)
downloadbusybox-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.c117
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())
9273static int 9275static int
9274pgetc(void) 9276pgetc(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
9290pgetc2(void) 9292pgetc2(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
9300static int 9301#define pgetc2() pgetc()
9301pgetc2(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! */
11283static const char xxreadtoken_chars[7] ALIGN1 = { 11297static 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
11287static const char xxreadtoken_tokens[] ALIGN1 = { 11306static 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
11299static int 11313static int
11300xxreadtoken(void) 11314xxreadtoken(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