ash: split bash compatible extensions into separate defines. No code changes
Splitting these options makes it self-documenting about what bash-compatible features we have. Signed-off-by: Kang-Che Sung <explorer09@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
a8a075acfe
commit
7d4aec0c3e
175
shell/ash.c
175
shell/ash.c
@ -145,15 +145,10 @@
|
||||
//kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
|
||||
|
||||
/*
|
||||
* The following should be set to reflect the type of system you have:
|
||||
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
|
||||
* define SYSV if you are running under System V.
|
||||
* define DEBUG=1 to compile in debugging ('set -o debug' to turn on)
|
||||
* define DEBUG=2 to compile in and turn on debugging.
|
||||
*
|
||||
* When debugging is on (DEBUG is 1 and "set -o debug" was executed),
|
||||
* debugging info will be written to ./trace and a quit signal
|
||||
* will generate a core dump.
|
||||
* DEBUG=1 to compile in debugging ('set -o debug' turns on)
|
||||
* DEBUG=2 to compile in and turn on debugging.
|
||||
* When debugging is on ("set -o debug" was executed, or DEBUG=2),
|
||||
* debugging info is written to ./trace, quit signal generates core dump.
|
||||
*/
|
||||
#define DEBUG 0
|
||||
/* Tweak debug output verbosity here */
|
||||
@ -170,9 +165,30 @@
|
||||
#include <fnmatch.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/utsname.h> /* for setting $HOSTNAME */
|
||||
|
||||
#include "busybox.h" /* for applet_names */
|
||||
|
||||
/* So far, all bash compat is controlled by one config option */
|
||||
/* Separate defines document which part of code implements what */
|
||||
/* function keyword */
|
||||
#define BASH_FUNCTION ENABLE_ASH_BASH_COMPAT
|
||||
#define IF_BASH_FUNCTION IF_ASH_BASH_COMPAT
|
||||
/* &>file */
|
||||
#define BASH_REDIR_OUTPUT ENABLE_ASH_BASH_COMPAT
|
||||
#define IF_BASH_REDIR_OUTPUT IF_ASH_BASH_COMPAT
|
||||
/* $'...' */
|
||||
#define BASH_DOLLAR_SQUOTE ENABLE_ASH_BASH_COMPAT
|
||||
#define IF_BASH_DOLLAR_SQUOTE IF_ASH_BASH_COMPAT
|
||||
#define BASH_PATTERN_SUBST ENABLE_ASH_BASH_COMPAT
|
||||
#define IF_BASH_PATTERN_SUBST IF_ASH_BASH_COMPAT
|
||||
#define BASH_SUBSTR ENABLE_ASH_BASH_COMPAT
|
||||
#define IF_BASH_SUBSTR IF_ASH_BASH_COMPAT
|
||||
/* [[ EXPR ]] */
|
||||
#define BASH_TEST2 (ENABLE_ASH_BASH_COMPAT * ENABLE_ASH_TEST)
|
||||
#define BASH_SOURCE ENABLE_ASH_BASH_COMPAT
|
||||
#define BASH_PIPEFAIL ENABLE_ASH_BASH_COMPAT
|
||||
#define BASH_HOSTNAME_VAR ENABLE_ASH_BASH_COMPAT
|
||||
#define BASH_SHLVL_VAR ENABLE_ASH_BASH_COMPAT
|
||||
|
||||
#if defined(__ANDROID_API__) && __ANDROID_API__ <= 24
|
||||
/* Bionic at least up to version 24 has no glob() */
|
||||
# undef ENABLE_ASH_INTERNAL_GLOB
|
||||
@ -250,7 +266,7 @@ static const char *const optletters_optnames[] = {
|
||||
"b" "notify",
|
||||
"u" "nounset",
|
||||
"\0" "vi"
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_PIPEFAIL
|
||||
,"\0" "pipefail"
|
||||
#endif
|
||||
#if DEBUG
|
||||
@ -327,14 +343,14 @@ struct globals_misc {
|
||||
#define bflag optlist[11]
|
||||
#define uflag optlist[12]
|
||||
#define viflag optlist[13]
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_PIPEFAIL
|
||||
# define pipefail optlist[14]
|
||||
#else
|
||||
# define pipefail 0
|
||||
#endif
|
||||
#if DEBUG
|
||||
# define nolog optlist[14 + ENABLE_ASH_BASH_COMPAT]
|
||||
# define debug optlist[15 + ENABLE_ASH_BASH_COMPAT]
|
||||
# define nolog optlist[14 + BASH_PIPEFAIL]
|
||||
# define debug optlist[15 + BASH_PIPEFAIL]
|
||||
#endif
|
||||
|
||||
/* trap handler commands */
|
||||
@ -655,8 +671,10 @@ out2str(const char *p)
|
||||
#define VSTRIMLEFT 0x8 /* ${var#pattern} */
|
||||
#define VSTRIMLEFTMAX 0x9 /* ${var##pattern} */
|
||||
#define VSLENGTH 0xa /* ${#var} */
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_SUBSTR
|
||||
#define VSSUBSTR 0xc /* ${var:position:length} */
|
||||
#endif
|
||||
#if BASH_PATTERN_SUBST
|
||||
#define VSREPLACE 0xd /* ${var/pattern/replacement} */
|
||||
#define VSREPLACEALL 0xe /* ${var//pattern/replacement} */
|
||||
#endif
|
||||
@ -683,7 +701,7 @@ static const char dolatstr[] ALIGN1 = {
|
||||
#define NDEFUN 14
|
||||
#define NARG 15
|
||||
#define NTO 16
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
#define NTO2 17
|
||||
#endif
|
||||
#define NCLOBBER 18
|
||||
@ -1093,7 +1111,7 @@ shcmd(union node *cmd, FILE *fp)
|
||||
case NTO: s = ">>"+1; dftfd = 1; break;
|
||||
case NCLOBBER: s = ">|"; dftfd = 1; break;
|
||||
case NAPPEND: s = ">>"; dftfd = 1; break;
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
case NTO2:
|
||||
#endif
|
||||
case NTOFD: s = ">&"; dftfd = 1; break;
|
||||
@ -4455,7 +4473,8 @@ cmdputs(const char *s)
|
||||
static const char vstype[VSTYPE + 1][3] = {
|
||||
"", "}", "-", "+", "?", "=",
|
||||
"%", "%%", "#", "##"
|
||||
IF_ASH_BASH_COMPAT(, ":", "/", "//")
|
||||
IF_BASH_SUBSTR(, ":")
|
||||
IF_BASH_PATTERN_SUBST(, "/", "//")
|
||||
};
|
||||
|
||||
const char *p, *str;
|
||||
@ -4682,7 +4701,7 @@ cmdtxt(union node *n)
|
||||
case NAPPEND:
|
||||
p = ">>";
|
||||
goto redir;
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
case NTO2:
|
||||
#endif
|
||||
case NTOFD:
|
||||
@ -5209,7 +5228,7 @@ openredirect(union node *redir)
|
||||
goto ecreate;
|
||||
break;
|
||||
case NTO:
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
case NTO2:
|
||||
#endif
|
||||
/* Take care of noclobber mode. */
|
||||
@ -5370,7 +5389,7 @@ redirect(union node *redir, int flags)
|
||||
union node *tmp = redir;
|
||||
do {
|
||||
sv_pos++;
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
if (tmp->nfile.type == NTO2)
|
||||
sv_pos++;
|
||||
#endif
|
||||
@ -5412,7 +5431,7 @@ redirect(union node *redir, int flags)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
redirect_more:
|
||||
#endif
|
||||
if (need_to_remember(sv, fd)) {
|
||||
@ -5465,12 +5484,12 @@ redirect(union node *redir, int flags)
|
||||
}
|
||||
} else if (fd != newfd) { /* move newfd to fd */
|
||||
dup2_or_raise(newfd, fd);
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
if (!(redir->nfile.type == NTO2 && fd == 2))
|
||||
#endif
|
||||
close(newfd);
|
||||
}
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
if (redir->nfile.type == NTO2 && fd == 1) {
|
||||
/* We already redirected it to fd 1, now copy it to 2 */
|
||||
newfd = 1;
|
||||
@ -5787,15 +5806,15 @@ static char *
|
||||
rmescapes(char *str, int flag)
|
||||
{
|
||||
static const char qchars[] ALIGN1 = {
|
||||
IF_ASH_BASH_COMPAT('/',) CTLESC, CTLQUOTEMARK, '\0' };
|
||||
IF_BASH_PATTERN_SUBST('/',) CTLESC, CTLQUOTEMARK, '\0' };
|
||||
|
||||
char *p, *q, *r;
|
||||
unsigned inquotes;
|
||||
unsigned protect_against_glob;
|
||||
unsigned globbing;
|
||||
IF_ASH_BASH_COMPAT(unsigned slash = flag & RMESCAPE_SLASH;)
|
||||
IF_BASH_PATTERN_SUBST(unsigned slash = flag & RMESCAPE_SLASH;)
|
||||
|
||||
p = strpbrk(str, qchars IF_ASH_BASH_COMPAT(+ !slash));
|
||||
p = strpbrk(str, qchars IF_BASH_PATTERN_SUBST(+ !slash));
|
||||
if (!p)
|
||||
return str;
|
||||
|
||||
@ -5847,7 +5866,7 @@ rmescapes(char *str, int flag)
|
||||
protect_against_glob = 0;
|
||||
goto copy;
|
||||
}
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_PATTERN_SUBST
|
||||
else if (*p == '/' && slash) {
|
||||
/* stop handling globbing and mark location of slash */
|
||||
globbing = slash = 0;
|
||||
@ -6494,10 +6513,10 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
||||
char *loc;
|
||||
char *rmesc, *rmescend;
|
||||
char *str;
|
||||
IF_ASH_BASH_COMPAT(char *repl = NULL;)
|
||||
IF_ASH_BASH_COMPAT(int pos, len, orig_len;)
|
||||
IF_BASH_SUBSTR(int pos, len, orig_len;)
|
||||
int amount, resetloc;
|
||||
IF_ASH_BASH_COMPAT(int workloc;)
|
||||
IF_BASH_PATTERN_SUBST(int workloc;)
|
||||
IF_BASH_PATTERN_SUBST(char *repl = NULL;)
|
||||
int zero;
|
||||
char *(*scan)(char*, char*, char*, char*, int, int);
|
||||
|
||||
@ -6522,7 +6541,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
||||
varunset(p, varname, startp, varflags);
|
||||
/* NOTREACHED */
|
||||
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_SUBSTR
|
||||
case VSSUBSTR:
|
||||
//TODO: support more general format ${v:EXPR:EXPR},
|
||||
// where EXPR follows $(()) rules
|
||||
@ -6591,17 +6610,19 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
||||
amount = loc - expdest;
|
||||
STADJUST(amount, expdest);
|
||||
return loc;
|
||||
#endif
|
||||
#endif /* BASH_SUBSTR */
|
||||
}
|
||||
|
||||
resetloc = expdest - (char *)stackblock();
|
||||
|
||||
#if BASH_PATTERN_SUBST
|
||||
/* We'll comeback here if we grow the stack while handling
|
||||
* a VSREPLACE or VSREPLACEALL, since our pointers into the
|
||||
* stack will need rebasing, and we'll need to remove our work
|
||||
* areas each time
|
||||
*/
|
||||
IF_ASH_BASH_COMPAT(restart:)
|
||||
restart:
|
||||
#endif
|
||||
|
||||
amount = expdest - ((char *)stackblock() + resetloc);
|
||||
STADJUST(-amount, expdest);
|
||||
@ -6626,11 +6647,11 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
||||
* RMESCAPE_SLASH causes preglob to work differently on the pattern
|
||||
* and string. It's only used on the first call.
|
||||
*/
|
||||
preglob(str, IF_ASH_BASH_COMPAT(
|
||||
preglob(str, IF_BASH_PATTERN_SUBST(
|
||||
(subtype == VSREPLACE || subtype == VSREPLACEALL) && !repl ?
|
||||
RMESCAPE_SLASH :) 0);
|
||||
RMESCAPE_SLASH : ) 0);
|
||||
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_PATTERN_SUBST
|
||||
workloc = expdest - (char *)stackblock();
|
||||
if (subtype == VSREPLACE || subtype == VSREPLACEALL) {
|
||||
char *idx, *end;
|
||||
@ -6731,7 +6752,7 @@ subevalvar(char *p, char *varname, int strloc, int subtype,
|
||||
STADJUST(-amount, expdest);
|
||||
return startp;
|
||||
}
|
||||
#endif /* ENABLE_ASH_BASH_COMPAT */
|
||||
#endif /* BASH_PATTERN_SUBST */
|
||||
|
||||
subtype -= VSTRIMRIGHT;
|
||||
#if DEBUG
|
||||
@ -6999,8 +7020,10 @@ evalvar(char *p, int flag, struct strlist *var_str_list)
|
||||
case VSTRIMLEFTMAX:
|
||||
case VSTRIMRIGHT:
|
||||
case VSTRIMRIGHTMAX:
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_SUBSTR
|
||||
case VSSUBSTR:
|
||||
#endif
|
||||
#if BASH_PATTERN_SUBST
|
||||
case VSREPLACE:
|
||||
case VSREPLACEALL:
|
||||
#endif
|
||||
@ -7924,7 +7947,7 @@ enum {
|
||||
TESAC,
|
||||
TFI,
|
||||
TFOR,
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_FUNCTION
|
||||
TFUNCTION,
|
||||
#endif
|
||||
TIF,
|
||||
@ -7962,7 +7985,7 @@ enum {
|
||||
/* 19 */ | (1u << TESAC)
|
||||
/* 20 */ | (1u << TFI)
|
||||
/* 21 */ | (0u << TFOR)
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_FUNCTION
|
||||
/* 22 */ | (0u << TFUNCTION)
|
||||
#endif
|
||||
/* 23 */ | (0u << TIF)
|
||||
@ -8000,7 +8023,7 @@ static const char *const tokname_array[] = {
|
||||
"esac",
|
||||
"fi",
|
||||
"for",
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_FUNCTION
|
||||
"function",
|
||||
#endif
|
||||
"if",
|
||||
@ -8244,7 +8267,7 @@ static const uint8_t nodesize[N_NUMBER] ALIGN1 = {
|
||||
[NDEFUN ] = SHELL_ALIGN(sizeof(struct narg)),
|
||||
[NARG ] = SHELL_ALIGN(sizeof(struct narg)),
|
||||
[NTO ] = SHELL_ALIGN(sizeof(struct nfile)),
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
[NTO2 ] = SHELL_ALIGN(sizeof(struct nfile)),
|
||||
#endif
|
||||
[NCLOBBER ] = SHELL_ALIGN(sizeof(struct nfile)),
|
||||
@ -8326,7 +8349,7 @@ calcsize(int funcblocksize, union node *n)
|
||||
funcblocksize = calcsize(funcblocksize, n->narg.next);
|
||||
break;
|
||||
case NTO:
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
case NTO2:
|
||||
#endif
|
||||
case NCLOBBER:
|
||||
@ -8440,7 +8463,7 @@ copynode(union node *n)
|
||||
new->narg.next = copynode(n->narg.next);
|
||||
break;
|
||||
case NTO:
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
case NTO2:
|
||||
#endif
|
||||
case NCLOBBER:
|
||||
@ -8873,14 +8896,14 @@ expredir(union node *n)
|
||||
case NFROMTO:
|
||||
case NFROM:
|
||||
case NTO:
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
case NTO2:
|
||||
#endif
|
||||
case NCLOBBER:
|
||||
case NAPPEND:
|
||||
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
|
||||
TRACE(("expredir expanded to '%s'\n", fn.list->text));
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
store_expfname:
|
||||
#endif
|
||||
#if 0
|
||||
@ -8902,7 +8925,7 @@ expredir(union node *n)
|
||||
expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
|
||||
if (fn.list == NULL)
|
||||
ash_msg_and_raise_error("redir error");
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
//FIXME: we used expandarg with different args!
|
||||
if (!isdigit_str9(fn.list->text)) {
|
||||
/* >&file, not >&fd */
|
||||
@ -9298,7 +9321,7 @@ static int FAST_FUNC echocmd(int argc, char **argv) { return echo_main(argc, a
|
||||
#if ENABLE_ASH_PRINTF
|
||||
static int FAST_FUNC printfcmd(int argc, char **argv) { return printf_main(argc, argv); }
|
||||
#endif
|
||||
#if ENABLE_ASH_TEST
|
||||
#if ENABLE_ASH_TEST || BASH_TEST2
|
||||
static int FAST_FUNC testcmd(int argc, char **argv) { return test_main(argc, argv); }
|
||||
#endif
|
||||
|
||||
@ -9308,9 +9331,9 @@ static const struct builtincmd builtintab[] = {
|
||||
{ BUILTIN_SPEC_REG ":" , truecmd },
|
||||
#if ENABLE_ASH_TEST
|
||||
{ BUILTIN_REGULAR "[" , testcmd },
|
||||
# if ENABLE_ASH_BASH_COMPAT
|
||||
#endif
|
||||
#if BASH_TEST2
|
||||
{ BUILTIN_REGULAR "[[" , testcmd },
|
||||
# endif
|
||||
#endif
|
||||
#if ENABLE_ASH_ALIAS
|
||||
{ BUILTIN_REG_ASSG "alias" , aliascmd },
|
||||
@ -9363,7 +9386,7 @@ static const struct builtincmd builtintab[] = {
|
||||
{ BUILTIN_SPEC_REG "return" , returncmd },
|
||||
{ BUILTIN_SPEC_REG "set" , setcmd },
|
||||
{ BUILTIN_SPEC_REG "shift" , shiftcmd },
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_SOURCE
|
||||
{ BUILTIN_SPEC_REG "source" , dotcmd },
|
||||
#endif
|
||||
#if ENABLE_ASH_TEST
|
||||
@ -9386,7 +9409,7 @@ static const struct builtincmd builtintab[] = {
|
||||
#define COMMANDCMD (builtintab + \
|
||||
/* . : */ 2 + \
|
||||
/* [ */ 1 * ENABLE_ASH_TEST + \
|
||||
/* [[ */ 1 * ENABLE_ASH_TEST * ENABLE_ASH_BASH_COMPAT + \
|
||||
/* [[ */ 1 * BASH_TEST2 + \
|
||||
/* alias */ 1 * ENABLE_ASH_ALIAS + \
|
||||
/* bg */ 1 * ENABLE_ASH_JOB_CONTROL + \
|
||||
/* break cd cddir */ 3)
|
||||
@ -11008,10 +11031,10 @@ simplecmd(void)
|
||||
union node *vars, **vpp;
|
||||
union node **rpp, *redir;
|
||||
int savecheckkwd;
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_TEST2
|
||||
smallint double_brackets_flag = 0;
|
||||
smallint function_flag = 0;
|
||||
#endif
|
||||
IF_BASH_FUNCTION(smallint function_flag = 0;)
|
||||
|
||||
args = NULL;
|
||||
app = &args;
|
||||
@ -11026,12 +11049,14 @@ simplecmd(void)
|
||||
checkkwd = savecheckkwd;
|
||||
t = readtoken();
|
||||
switch (t) {
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_FUNCTION
|
||||
case TFUNCTION:
|
||||
if (peektoken() != TWORD)
|
||||
raise_error_unexpected_syntax(TWORD);
|
||||
function_flag = 1;
|
||||
break;
|
||||
#endif
|
||||
#if BASH_TEST2
|
||||
case TAND: /* "&&" */
|
||||
case TOR: /* "||" */
|
||||
if (!double_brackets_flag) {
|
||||
@ -11045,7 +11070,7 @@ simplecmd(void)
|
||||
n->type = NARG;
|
||||
/*n->narg.next = NULL; - stzalloc did it */
|
||||
n->narg.text = wordtext;
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_TEST2
|
||||
if (strcmp("[[", wordtext) == 0)
|
||||
double_brackets_flag = 1;
|
||||
else if (strcmp("]]", wordtext) == 0)
|
||||
@ -11060,7 +11085,7 @@ simplecmd(void)
|
||||
app = &n->narg.next;
|
||||
savecheckkwd = 0;
|
||||
}
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_FUNCTION
|
||||
if (function_flag) {
|
||||
checkkwd = CHKNL | CHKKWD;
|
||||
switch (peektoken()) {
|
||||
@ -11090,7 +11115,7 @@ simplecmd(void)
|
||||
parsefname(); /* read name of redirection file */
|
||||
break;
|
||||
case TLP:
|
||||
IF_ASH_BASH_COMPAT(do_func:)
|
||||
IF_BASH_FUNCTION(do_func:)
|
||||
if (args && app == &args->narg.next
|
||||
&& !vars && !redir
|
||||
) {
|
||||
@ -11098,7 +11123,7 @@ simplecmd(void)
|
||||
const char *name;
|
||||
|
||||
/* We have a function */
|
||||
if (IF_ASH_BASH_COMPAT(!function_flag &&) readtoken() != TRP)
|
||||
if (IF_BASH_FUNCTION(!function_flag &&) readtoken() != TRP)
|
||||
raise_error_unexpected_syntax(TRP);
|
||||
name = n->narg.text;
|
||||
if (!goodname(name)
|
||||
@ -11111,7 +11136,7 @@ simplecmd(void)
|
||||
n->narg.next = parse_command();
|
||||
return n;
|
||||
}
|
||||
IF_ASH_BASH_COMPAT(function_flag = 0;)
|
||||
IF_BASH_FUNCTION(function_flag = 0;)
|
||||
/* fall through */
|
||||
default:
|
||||
tokpushback = 1;
|
||||
@ -11292,7 +11317,7 @@ parse_command(void)
|
||||
n1 = list(0);
|
||||
t = TEND;
|
||||
break;
|
||||
IF_ASH_BASH_COMPAT(case TFUNCTION:)
|
||||
IF_BASH_FUNCTION(case TFUNCTION:)
|
||||
case TWORD:
|
||||
case TREDIR:
|
||||
tokpushback = 1;
|
||||
@ -11325,7 +11350,7 @@ parse_command(void)
|
||||
return n1;
|
||||
}
|
||||
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_DOLLAR_SQUOTE
|
||||
static int
|
||||
decode_dollar_squote(void)
|
||||
{
|
||||
@ -11410,7 +11435,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||
IF_FEATURE_SH_MATH(int parenlevel;) /* levels of parens in arithmetic */
|
||||
int dqvarnest; /* levels of variables expansion within double quotes */
|
||||
|
||||
IF_ASH_BASH_COMPAT(smallint bash_dollar_squote = 0;)
|
||||
IF_BASH_DOLLAR_SQUOTE(smallint bash_dollar_squote = 0;)
|
||||
|
||||
startlinno = g_parsefile->linno;
|
||||
bqlist = NULL;
|
||||
@ -11445,7 +11470,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||
USTPUTC(c, out);
|
||||
break;
|
||||
case CCTL:
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_DOLLAR_SQUOTE
|
||||
if (c == '\\' && bash_dollar_squote) {
|
||||
c = decode_dollar_squote();
|
||||
if (c == '\0') {
|
||||
@ -11506,7 +11531,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||
dblquote = 1;
|
||||
goto quotemark;
|
||||
case CENDQUOTE:
|
||||
IF_ASH_BASH_COMPAT(bash_dollar_squote = 0;)
|
||||
IF_BASH_DOLLAR_SQUOTE(bash_dollar_squote = 0;)
|
||||
if (eofmark != NULL && varnest == 0) {
|
||||
USTPUTC(c, out);
|
||||
} else {
|
||||
@ -11565,7 +11590,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||
break;
|
||||
default:
|
||||
if (varnest == 0) {
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
if (c == '&') {
|
||||
//Can't call pgetc_eatbnl() here, this requires three-deep pungetc()
|
||||
if (pgetc() == '>')
|
||||
@ -11597,7 +11622,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
|
||||
len = out - (char *)stackblock();
|
||||
out = stackblock();
|
||||
if (eofmark == NULL) {
|
||||
if ((c == '>' || c == '<' IF_ASH_BASH_COMPAT( || c == 0x100 + '>'))
|
||||
if ((c == '>' || c == '<' IF_BASH_REDIR_OUTPUT( || c == 0x100 + '>'))
|
||||
&& quotef == 0
|
||||
) {
|
||||
if (isdigit_str9(out)) {
|
||||
@ -11685,7 +11710,7 @@ parseredir: {
|
||||
pungetc();
|
||||
}
|
||||
}
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
else if (c == 0x100 + '>') { /* this flags &> redirection */
|
||||
np->nfile.fd = 1;
|
||||
pgetc(); /* this is '>', no need to check */
|
||||
@ -11751,7 +11776,7 @@ parsesub: {
|
||||
if (c > 255 /* PEOA or PEOF */
|
||||
|| (c != '(' && c != '{' && !is_name(c) && !is_special(c))
|
||||
) {
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_DOLLAR_SQUOTE
|
||||
if (syntax != DQSYNTAX && c == '\'')
|
||||
bash_dollar_squote = 1;
|
||||
else
|
||||
@ -11827,7 +11852,7 @@ parsesub: {
|
||||
switch (c) {
|
||||
case ':':
|
||||
c = pgetc_eatbnl();
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_SUBSTR
|
||||
/* This check is only needed to not misinterpret
|
||||
* ${VAR:-WORD}, ${VAR:+WORD}, ${VAR:=WORD}, ${VAR:?WORD}
|
||||
* constructs.
|
||||
@ -11857,7 +11882,7 @@ parsesub: {
|
||||
subtype++;
|
||||
break;
|
||||
}
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_PATTERN_SUBST
|
||||
case '/':
|
||||
/* ${v/[/]pattern/repl} */
|
||||
//TODO: encode pattern and repl separately.
|
||||
@ -12112,7 +12137,7 @@ xxreadtoken(void)
|
||||
p += xxreadtoken_doubles + 1;
|
||||
} else {
|
||||
pungetc();
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_REDIR_OUTPUT
|
||||
if (c == '&' && cc == '>') /* &> */
|
||||
break; /* return readtoken1(...) */
|
||||
#endif
|
||||
@ -13274,9 +13299,11 @@ init(void)
|
||||
setvareq((char*)defoptindvar, VTEXTFIXED);
|
||||
|
||||
setvar0("PPID", utoa(getppid()));
|
||||
#if ENABLE_ASH_BASH_COMPAT
|
||||
#if BASH_SHLVL_VAR
|
||||
p = lookupvar("SHLVL");
|
||||
setvar("SHLVL", utoa((p ? atoi(p) : 0) + 1), VEXPORT);
|
||||
#endif
|
||||
#if BASH_HOSTNAME_VAR
|
||||
if (!lookupvar("HOSTNAME")) {
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
|
Loading…
Reference in New Issue
Block a user