ash: eval: Replace with listsetvar with mklocal/setvareq
Upstream commit: Date: Sat, 19 May 2018 02:39:55 +0800 eval: Replace with listsetvar with mklocal/setvareq This patch replaces listsetvar with mklocal/setvareq. As we now determine special built-in status prior to variable assignment, we no longer have to do a second pass listsetvar. Instead we will call setvareq directly instead of mklocal when necessary. In order to do this mklocal can now take a flag in order to mark a variable for export. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
54bef2a8ef
commit
3e729102a8
61
shell/ash.c
61
shell/ash.c
@ -2476,24 +2476,6 @@ unsetvar(const char *s)
|
|||||||
setvar(s, NULL, 0);
|
setvar(s, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Process a linked list of variable assignments.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
listsetvar(struct strlist *list_set_var, int flags)
|
|
||||||
{
|
|
||||||
struct strlist *lp = list_set_var;
|
|
||||||
|
|
||||||
if (!lp)
|
|
||||||
return;
|
|
||||||
INT_OFF;
|
|
||||||
do {
|
|
||||||
setvareq(lp->text, flags);
|
|
||||||
lp = lp->next;
|
|
||||||
} while (lp);
|
|
||||||
INT_ON;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a list of variables satisfying the given conditions.
|
* Generate a list of variables satisfying the given conditions.
|
||||||
*/
|
*/
|
||||||
@ -9810,7 +9792,7 @@ evalfun(struct funcnode *func, int argc, char **argv, int flags)
|
|||||||
* (options will be restored on return from the function).
|
* (options will be restored on return from the function).
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
mklocal(char *name)
|
mklocal(char *name, int flags)
|
||||||
{
|
{
|
||||||
struct localvar *lvp;
|
struct localvar *lvp;
|
||||||
struct var **vpp;
|
struct var **vpp;
|
||||||
@ -9847,9 +9829,9 @@ mklocal(char *name)
|
|||||||
if (vp == NULL) {
|
if (vp == NULL) {
|
||||||
/* variable did not exist yet */
|
/* variable did not exist yet */
|
||||||
if (eq)
|
if (eq)
|
||||||
vp = setvareq(name, VSTRFIXED);
|
vp = setvareq(name, VSTRFIXED | flags);
|
||||||
else
|
else
|
||||||
vp = setvar(name, NULL, VSTRFIXED);
|
vp = setvar(name, NULL, VSTRFIXED | flags);
|
||||||
lvp->flags = VUNSET;
|
lvp->flags = VUNSET;
|
||||||
} else {
|
} else {
|
||||||
lvp->text = vp->var_text;
|
lvp->text = vp->var_text;
|
||||||
@ -9859,7 +9841,7 @@ mklocal(char *name)
|
|||||||
*/
|
*/
|
||||||
vp->flags |= VSTRFIXED|VTEXTFIXED;
|
vp->flags |= VSTRFIXED|VTEXTFIXED;
|
||||||
if (eq)
|
if (eq)
|
||||||
setvareq(name, 0);
|
setvareq(name, flags);
|
||||||
else
|
else
|
||||||
/* "local VAR" unsets VAR: */
|
/* "local VAR" unsets VAR: */
|
||||||
setvar0(name, NULL);
|
setvar0(name, NULL);
|
||||||
@ -9885,7 +9867,7 @@ localcmd(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
argv = argptr;
|
argv = argptr;
|
||||||
while ((name = *argv++) != NULL) {
|
while ((name = *argv++) != NULL) {
|
||||||
mklocal(name);
|
mklocal(name, 0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -10166,6 +10148,8 @@ evalcommand(union node *cmd, int flags)
|
|||||||
int status;
|
int status;
|
||||||
char **nargv;
|
char **nargv;
|
||||||
smallint cmd_is_exec;
|
smallint cmd_is_exec;
|
||||||
|
int vflags;
|
||||||
|
int vlocal;
|
||||||
|
|
||||||
errlinno = lineno = cmd->ncmd.linno;
|
errlinno = lineno = cmd->ncmd.linno;
|
||||||
if (funcline)
|
if (funcline)
|
||||||
@ -10173,7 +10157,6 @@ evalcommand(union node *cmd, int flags)
|
|||||||
|
|
||||||
/* First expand the arguments. */
|
/* First expand the arguments. */
|
||||||
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
|
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
|
||||||
localvar_stop = pushlocalvars();
|
|
||||||
file_stop = g_parsefile;
|
file_stop = g_parsefile;
|
||||||
back_exitstatus = 0;
|
back_exitstatus = 0;
|
||||||
|
|
||||||
@ -10187,6 +10170,8 @@ evalcommand(union node *cmd, int flags)
|
|||||||
cmd_flag = 0;
|
cmd_flag = 0;
|
||||||
cmd_is_exec = 0;
|
cmd_is_exec = 0;
|
||||||
spclbltin = -1;
|
spclbltin = -1;
|
||||||
|
vflags = 0;
|
||||||
|
vlocal = 0;
|
||||||
path = NULL;
|
path = NULL;
|
||||||
|
|
||||||
argc = 0;
|
argc = 0;
|
||||||
@ -10199,6 +10184,8 @@ evalcommand(union node *cmd, int flags)
|
|||||||
find_command(arglist.list->text, &cmdentry,
|
find_command(arglist.list->text, &cmdentry,
|
||||||
cmd_flag | DO_REGBLTIN, pathval());
|
cmd_flag | DO_REGBLTIN, pathval());
|
||||||
|
|
||||||
|
vlocal++;
|
||||||
|
|
||||||
/* implement bltin and command here */
|
/* implement bltin and command here */
|
||||||
if (cmdentry.cmdtype != CMDBUILTIN)
|
if (cmdentry.cmdtype != CMDBUILTIN)
|
||||||
break;
|
break;
|
||||||
@ -10206,6 +10193,7 @@ evalcommand(union node *cmd, int flags)
|
|||||||
pseudovarflag = IS_BUILTIN_ASSIGN(cmdentry.u.cmd);
|
pseudovarflag = IS_BUILTIN_ASSIGN(cmdentry.u.cmd);
|
||||||
if (spclbltin < 0) {
|
if (spclbltin < 0) {
|
||||||
spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
|
spclbltin = IS_BUILTIN_SPECIAL(cmdentry.u.cmd);
|
||||||
|
vlocal = !spclbltin;
|
||||||
}
|
}
|
||||||
cmd_is_exec = cmdentry.u.cmd == EXECCMD;
|
cmd_is_exec = cmdentry.u.cmd == EXECCMD;
|
||||||
if (cmdentry.u.cmd != COMMANDCMD)
|
if (cmdentry.u.cmd != COMMANDCMD)
|
||||||
@ -10224,6 +10212,9 @@ evalcommand(union node *cmd, int flags)
|
|||||||
|
|
||||||
for (sp = arglist.list; sp; sp = sp->next)
|
for (sp = arglist.list; sp; sp = sp->next)
|
||||||
argc++;
|
argc++;
|
||||||
|
|
||||||
|
if (cmd_is_exec && argc > 1)
|
||||||
|
vflags = VEXPORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reserve one extra spot at the front for shellexec. */
|
/* Reserve one extra spot at the front for shellexec. */
|
||||||
@ -10254,6 +10245,7 @@ evalcommand(union node *cmd, int flags)
|
|||||||
status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
|
status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH | REDIR_SAVEFD2);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
|
vlocal = 0;
|
||||||
bail:
|
bail:
|
||||||
exitstatus = status;
|
exitstatus = status;
|
||||||
|
|
||||||
@ -10264,13 +10256,20 @@ evalcommand(union node *cmd, int flags)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
localvar_stop = NULL;
|
||||||
|
if (vlocal)
|
||||||
|
localvar_stop = pushlocalvars();
|
||||||
|
|
||||||
for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
|
for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) {
|
||||||
struct strlist **spp;
|
struct strlist **spp;
|
||||||
|
|
||||||
spp = varlist.lastp;
|
spp = varlist.lastp;
|
||||||
expandarg(argp, &varlist, EXP_VARTILDE);
|
expandarg(argp, &varlist, EXP_VARTILDE);
|
||||||
|
|
||||||
mklocal((*spp)->text);
|
if (vlocal)
|
||||||
|
mklocal((*spp)->text, VEXPORT);
|
||||||
|
else
|
||||||
|
setvareq((*spp)->text, vflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print the command if xflag is set. */
|
/* Print the command if xflag is set. */
|
||||||
@ -10313,8 +10312,8 @@ evalcommand(union node *cmd, int flags)
|
|||||||
if (cmdentry.cmdtype != CMDBUILTIN
|
if (cmdentry.cmdtype != CMDBUILTIN
|
||||||
|| !(IS_BUILTIN_REGULAR(cmdentry.u.cmd))
|
|| !(IS_BUILTIN_REGULAR(cmdentry.u.cmd))
|
||||||
) {
|
) {
|
||||||
find_command(argv[0], &cmdentry, cmd_flag | DO_ERR,
|
path = path ? path : pathval();
|
||||||
path ? path : pathval());
|
find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
jp = NULL;
|
jp = NULL;
|
||||||
@ -10385,17 +10384,10 @@ evalcommand(union node *cmd, int flags)
|
|||||||
FORCE_INT_ON;
|
FORCE_INT_ON;
|
||||||
/* fall through to exec'ing external program */
|
/* fall through to exec'ing external program */
|
||||||
}
|
}
|
||||||
listsetvar(varlist.list, VEXPORT|VSTACK);
|
|
||||||
path = path ? path : pathval();
|
|
||||||
shellexec(argv[0], argv, path, cmdentry.u.index);
|
shellexec(argv[0], argv, path, cmdentry.u.index);
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
} /* default */
|
} /* default */
|
||||||
case CMDBUILTIN:
|
case CMDBUILTIN:
|
||||||
if (spclbltin > 0 || argc == 0) {
|
|
||||||
poplocalvars(1);
|
|
||||||
if (cmd_is_exec && argc > 1)
|
|
||||||
listsetvar(varlist.list, VEXPORT);
|
|
||||||
}
|
|
||||||
if (evalbltin(cmdentry.u.cmd, argc, argv, flags)
|
if (evalbltin(cmdentry.u.cmd, argc, argv, flags)
|
||||||
&& !(exception_type == EXERROR && spclbltin <= 0)
|
&& !(exception_type == EXERROR && spclbltin <= 0)
|
||||||
) {
|
) {
|
||||||
@ -10418,6 +10410,7 @@ evalcommand(union node *cmd, int flags)
|
|||||||
popredir(/*drop:*/ cmd_is_exec);
|
popredir(/*drop:*/ cmd_is_exec);
|
||||||
unwindredir(redir_stop);
|
unwindredir(redir_stop);
|
||||||
unwindfiles(file_stop);
|
unwindfiles(file_stop);
|
||||||
|
if (vlocal)
|
||||||
unwindlocalvars(localvar_stop);
|
unwindlocalvars(localvar_stop);
|
||||||
if (lastarg) {
|
if (lastarg) {
|
||||||
/* dsl: I think this is intended to be used to support
|
/* dsl: I think this is intended to be used to support
|
||||||
|
Loading…
x
Reference in New Issue
Block a user