ash: support &> redirection (bashism). ~90 bytes of code
This commit is contained in:
parent
176d49d4f7
commit
834dee785d
117
shell/ash.c
117
shell/ash.c
@ -2572,34 +2572,36 @@ pwdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
|||||||
|
|
||||||
/* ============ ... */
|
/* ============ ... */
|
||||||
|
|
||||||
|
|
||||||
#define IBUFSIZ COMMON_BUFSIZE
|
#define IBUFSIZ COMMON_BUFSIZE
|
||||||
#define basebuf bb_common_bufsiz1 /* buffer for top level input file */
|
/* buffer for top level input file */
|
||||||
|
#define basebuf bb_common_bufsiz1
|
||||||
|
|
||||||
/* Syntax classes */
|
/* Syntax classes */
|
||||||
#define CWORD 0 /* character is nothing special */
|
#define CWORD 0 /* character is nothing special */
|
||||||
#define CNL 1 /* newline character */
|
#define CNL 1 /* newline character */
|
||||||
#define CBACK 2 /* a backslash character */
|
#define CBACK 2 /* a backslash character */
|
||||||
#define CSQUOTE 3 /* single quote */
|
#define CSQUOTE 3 /* single quote */
|
||||||
#define CDQUOTE 4 /* double quote */
|
#define CDQUOTE 4 /* double quote */
|
||||||
#define CENDQUOTE 5 /* a terminating quote */
|
#define CENDQUOTE 5 /* a terminating quote */
|
||||||
#define CBQUOTE 6 /* backwards single quote */
|
#define CBQUOTE 6 /* backwards single quote */
|
||||||
#define CVAR 7 /* a dollar sign */
|
#define CVAR 7 /* a dollar sign */
|
||||||
#define CENDVAR 8 /* a '}' character */
|
#define CENDVAR 8 /* a '}' character */
|
||||||
#define CLP 9 /* a left paren in arithmetic */
|
#define CLP 9 /* a left paren in arithmetic */
|
||||||
#define CRP 10 /* a right paren in arithmetic */
|
#define CRP 10 /* a right paren in arithmetic */
|
||||||
#define CENDFILE 11 /* end of file */
|
#define CENDFILE 11 /* end of file */
|
||||||
#define CCTL 12 /* like CWORD, except it must be escaped */
|
#define CCTL 12 /* like CWORD, except it must be escaped */
|
||||||
#define CSPCL 13 /* these terminate a word */
|
#define CSPCL 13 /* these terminate a word */
|
||||||
#define CIGN 14 /* character should be ignored */
|
#define CIGN 14 /* character should be ignored */
|
||||||
|
|
||||||
#if ENABLE_ASH_ALIAS
|
#if ENABLE_ASH_ALIAS
|
||||||
#define SYNBASE 130
|
#define SYNBASE 130
|
||||||
#define PEOF -130
|
#define PEOF -130
|
||||||
#define PEOA -129
|
#define PEOA -129
|
||||||
#define PEOA_OR_PEOF PEOA
|
#define PEOA_OR_PEOF PEOA
|
||||||
#else
|
#else
|
||||||
#define SYNBASE 129
|
#define SYNBASE 129
|
||||||
#define PEOF -129
|
#define PEOF -129
|
||||||
#define PEOA_OR_PEOF PEOF
|
#define PEOA_OR_PEOF PEOF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -9269,7 +9271,7 @@ preadbuffer(void)
|
|||||||
return signed_char2int(*parsenextc++);
|
return signed_char2int(*parsenextc++);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define pgetc_as_macro() (--parsenleft >= 0? signed_char2int(*parsenextc++) : preadbuffer())
|
#define pgetc_as_macro() (--parsenleft >= 0 ? signed_char2int(*parsenextc++) : preadbuffer())
|
||||||
static int
|
static int
|
||||||
pgetc(void)
|
pgetc(void)
|
||||||
{
|
{
|
||||||
@ -9277,9 +9279,9 @@ pgetc(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_ASH_OPTIMIZE_FOR_SIZE
|
#if ENABLE_ASH_OPTIMIZE_FOR_SIZE
|
||||||
#define pgetc_macro() pgetc()
|
#define pgetc_fast() pgetc()
|
||||||
#else
|
#else
|
||||||
#define pgetc_macro() pgetc_as_macro()
|
#define pgetc_fast() pgetc_as_macro()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -9290,18 +9292,13 @@ static int
|
|||||||
pgetc2(void)
|
pgetc2(void)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
c = pgetc_macro();
|
c = pgetc_fast();
|
||||||
} while (c == PEOA);
|
} while (c == PEOA);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int
|
#define pgetc2() pgetc()
|
||||||
pgetc2(void)
|
|
||||||
{
|
|
||||||
return pgetc_macro();
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -9355,7 +9352,6 @@ pushstring(char *s, struct alias *ap)
|
|||||||
|
|
||||||
len = strlen(s);
|
len = strlen(s);
|
||||||
INT_OFF;
|
INT_OFF;
|
||||||
/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
|
|
||||||
if (g_parsefile->strpush) {
|
if (g_parsefile->strpush) {
|
||||||
sp = ckzalloc(sizeof(struct strpush));
|
sp = ckzalloc(sizeof(struct strpush));
|
||||||
sp->prev = g_parsefile->strpush;
|
sp->prev = g_parsefile->strpush;
|
||||||
@ -10800,15 +10796,23 @@ readtoken1(int firstc, int syntax, char *eofmark, int striptabs)
|
|||||||
case CIGN:
|
case CIGN:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (varnest == 0)
|
if (varnest == 0) {
|
||||||
|
#if ENABLE_ASH_BASH_COMPAT
|
||||||
|
if (c == '&') {
|
||||||
|
if (pgetc() == '>')
|
||||||
|
c = 0x100 + '>'; /* flag &> */
|
||||||
|
pungetc();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
goto endword; /* exit outer loop */
|
goto endword; /* exit outer loop */
|
||||||
|
}
|
||||||
#if ENABLE_ASH_ALIAS
|
#if ENABLE_ASH_ALIAS
|
||||||
if (c != PEOA)
|
if (c != PEOA)
|
||||||
#endif
|
#endif
|
||||||
USTPUTC(c, out);
|
USTPUTC(c, out);
|
||||||
|
|
||||||
}
|
}
|
||||||
c = pgetc_macro();
|
c = pgetc_fast();
|
||||||
} /* for (;;) */
|
} /* for (;;) */
|
||||||
}
|
}
|
||||||
endword:
|
endword:
|
||||||
@ -10827,7 +10831,9 @@ readtoken1(int firstc, int syntax, char *eofmark, int striptabs)
|
|||||||
len = out - (char *)stackblock();
|
len = out - (char *)stackblock();
|
||||||
out = stackblock();
|
out = stackblock();
|
||||||
if (eofmark == NULL) {
|
if (eofmark == NULL) {
|
||||||
if ((c == '>' || c == '<') && quotef == 0) {
|
if ((c == '>' || c == '<' USE_ASH_BASH_COMPAT( || c == 0x100 + '>'))
|
||||||
|
&& quotef == 0
|
||||||
|
) {
|
||||||
if (isdigit_str9(out)) {
|
if (isdigit_str9(out)) {
|
||||||
PARSEREDIR(); /* passed as params: out, c */
|
PARSEREDIR(); /* passed as params: out, c */
|
||||||
lasttoken = TREDIR;
|
lasttoken = TREDIR;
|
||||||
@ -10908,7 +10914,15 @@ parseredir: {
|
|||||||
np->type = NTO;
|
np->type = NTO;
|
||||||
pungetc();
|
pungetc();
|
||||||
}
|
}
|
||||||
} else { /* c == '<' */
|
}
|
||||||
|
#if ENABLE_ASH_BASH_COMPAT
|
||||||
|
else if (c == 0x100 + '>') { /* this flags &> redirection */
|
||||||
|
np->nfile.fd = 1;
|
||||||
|
pgetc(); /* this is '>', no need to check */
|
||||||
|
np->type = NTO2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else { /* c == '<' */
|
||||||
/*np->nfile.fd = 0; - stzalloc did it */
|
/*np->nfile.fd = 0; - stzalloc did it */
|
||||||
c = pgetc();
|
c = pgetc();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
@ -11281,9 +11295,14 @@ parsearith: {
|
|||||||
#ifdef NEW_xxreadtoken
|
#ifdef NEW_xxreadtoken
|
||||||
/* singles must be first! */
|
/* singles must be first! */
|
||||||
static const char xxreadtoken_chars[7] ALIGN1 = {
|
static const char xxreadtoken_chars[7] ALIGN1 = {
|
||||||
'\n', '(', ')', '&', '|', ';', 0
|
'\n', '(', ')', /* singles */
|
||||||
|
'&', '|', ';', /* doubles */
|
||||||
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define xxreadtoken_singles 3
|
||||||
|
#define xxreadtoken_doubles 3
|
||||||
|
|
||||||
static const char xxreadtoken_tokens[] ALIGN1 = {
|
static const char xxreadtoken_tokens[] ALIGN1 = {
|
||||||
TNL, TLP, TRP, /* only single occurrence allowed */
|
TNL, TLP, TRP, /* only single occurrence allowed */
|
||||||
TBACKGND, TPIPE, TSEMI, /* if single occurrence */
|
TBACKGND, TPIPE, TSEMI, /* if single occurrence */
|
||||||
@ -11291,11 +11310,6 @@ static const char xxreadtoken_tokens[] ALIGN1 = {
|
|||||||
TAND, TOR, TENDCASE /* if double occurrence */
|
TAND, TOR, TENDCASE /* if double occurrence */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define xxreadtoken_doubles \
|
|
||||||
(sizeof(xxreadtoken_tokens) - sizeof(xxreadtoken_chars))
|
|
||||||
#define xxreadtoken_singles \
|
|
||||||
(sizeof(xxreadtoken_chars) - xxreadtoken_doubles - 1)
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
xxreadtoken(void)
|
xxreadtoken(void)
|
||||||
{
|
{
|
||||||
@ -11310,7 +11324,7 @@ xxreadtoken(void)
|
|||||||
}
|
}
|
||||||
startlinno = plinno;
|
startlinno = plinno;
|
||||||
for (;;) { /* until token or start of word found */
|
for (;;) { /* until token or start of word found */
|
||||||
c = pgetc_macro();
|
c = pgetc_fast();
|
||||||
if (c == ' ' || c == '\t' USE_ASH_ALIAS( || c == PEOA))
|
if (c == ' ' || c == '\t' USE_ASH_ALIAS( || c == PEOA))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -11321,7 +11335,7 @@ xxreadtoken(void)
|
|||||||
} else if (c == '\\') {
|
} else if (c == '\\') {
|
||||||
if (pgetc() != '\n') {
|
if (pgetc() != '\n') {
|
||||||
pungetc();
|
pungetc();
|
||||||
goto READTOKEN1;
|
break; /* return readtoken1(...) */
|
||||||
}
|
}
|
||||||
startlinno = ++plinno;
|
startlinno = ++plinno;
|
||||||
if (doprompt)
|
if (doprompt)
|
||||||
@ -11337,16 +11351,19 @@ xxreadtoken(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
p = strchr(xxreadtoken_chars, c);
|
p = strchr(xxreadtoken_chars, c);
|
||||||
if (p == NULL) {
|
if (p == NULL)
|
||||||
READTOKEN1:
|
break; /* return readtoken1(...) */
|
||||||
return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((size_t)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
|
if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) {
|
||||||
if (pgetc() == *p) { /* double occurrence? */
|
int cc = pgetc();
|
||||||
|
if (cc == c) { /* double occurrence? */
|
||||||
p += xxreadtoken_doubles + 1;
|
p += xxreadtoken_doubles + 1;
|
||||||
} else {
|
} else {
|
||||||
pungetc();
|
pungetc();
|
||||||
|
#if ENABLE_ASH_BASH_COMPAT
|
||||||
|
if (c == '&' && cc == '>') /* &> */
|
||||||
|
break; /* return readtoken1(...) */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -11354,6 +11371,8 @@ xxreadtoken(void)
|
|||||||
return lasttoken;
|
return lasttoken;
|
||||||
}
|
}
|
||||||
} /* for (;;) */
|
} /* for (;;) */
|
||||||
|
|
||||||
|
return readtoken1(c, BASESYNTAX, (char *) NULL, 0);
|
||||||
}
|
}
|
||||||
#else /* old xxreadtoken */
|
#else /* old xxreadtoken */
|
||||||
#define RETURN(token) return lasttoken = token
|
#define RETURN(token) return lasttoken = token
|
||||||
@ -11371,7 +11390,7 @@ xxreadtoken(void)
|
|||||||
}
|
}
|
||||||
startlinno = plinno;
|
startlinno = plinno;
|
||||||
for (;;) { /* until token or start of word found */
|
for (;;) { /* until token or start of word found */
|
||||||
c = pgetc_macro();
|
c = pgetc_fast();
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case ' ': case '\t':
|
case ' ': case '\t':
|
||||||
#if ENABLE_ASH_ALIAS
|
#if ENABLE_ASH_ALIAS
|
||||||
|
Loading…
x
Reference in New Issue
Block a user