From patchwork Fri May 18 18:39:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Herbert Xu X-Patchwork-Id: 10411861 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 268476037E for ; Fri, 18 May 2018 18:39:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 15D4A28707 for ; Fri, 18 May 2018 18:39:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0AAF328A8E; Fri, 18 May 2018 18:39:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BB6A28A8D for ; Fri, 18 May 2018 18:39:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751815AbeERSj5 (ORCPT ); Fri, 18 May 2018 14:39:57 -0400 Received: from orcrist.hmeau.com ([104.223.48.154]:48264 "EHLO deadmen.hmeau.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751734AbeERSj4 (ORCPT ); Fri, 18 May 2018 14:39:56 -0400 Received: from gondobar.mordor.me.apana.org.au ([192.168.128.4] helo=gondobar) by deadmen.hmeau.com with esmtps (Exim 4.89 #2 (Debian)) id 1fJkIF-0006FL-ID for ; Sat, 19 May 2018 02:39:55 +0800 Received: from herbert by gondobar with local (Exim 4.89) (envelope-from ) id 1fJkIF-0005q7-7I; Sat, 19 May 2018 02:39:55 +0800 Subject: [v3 PATCH 16/17] eval: Replace with listsetvar with mklocal/setvareq References: <20180518183844.zizl3xevlcm4gzsj@gondor.apana.org.au> To: DASH Mailing List Message-Id: From: Herbert Xu Date: Sat, 19 May 2018 02:39:55 +0800 Sender: dash-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: dash@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- src/eval.c | 36 +++++++++++++++++++++++------------- src/var.c | 32 +++++--------------------------- src/var.h | 3 +-- 3 files changed, 29 insertions(+), 42 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe dash" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/src/eval.c b/src/eval.c index 122613b..ff8a869 100644 --- a/src/eval.c +++ b/src/eval.c @@ -737,6 +737,8 @@ evalcommand(union node *cmd, int flags) int execcmd; int status; char **nargv; + int vflags; + int vlocal; errlinno = lineno = cmd->ncmd.linno; if (funcline) @@ -745,7 +747,6 @@ evalcommand(union node *cmd, int flags) /* First expand the arguments. */ TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); setstackmark(&smark); - localvar_stop = pushlocalvars(); file_stop = parsefile; back_exitstatus = 0; @@ -759,6 +760,8 @@ evalcommand(union node *cmd, int flags) cmd_flag = 0; execcmd = 0; spclbltin = -1; + vflags = 0; + vlocal = 0; path = NULL; argc = 0; @@ -770,6 +773,8 @@ evalcommand(union node *cmd, int flags) find_command(arglist.list->text, &cmdentry, cmd_flag | DO_REGBLTIN, pathval()); + vlocal++; + /* implement bltin and command here */ if (cmdentry.cmdtype != CMDBUILTIN) break; @@ -780,6 +785,7 @@ evalcommand(union node *cmd, int flags) cmdentry.u.cmd->flags & BUILTIN_SPECIAL ; + vlocal = spclbltin ^ BUILTIN_SPECIAL; } execcmd = cmdentry.u.cmd == EXECCMD; if (likely(cmdentry.u.cmd != COMMANDCMD)) @@ -798,6 +804,9 @@ evalcommand(union node *cmd, int flags) for (sp = arglist.list; sp; sp = sp->next) argc++; + + if (execcmd && argc > 1) + vflags = VEXPORT; } /* Reserve one extra spot at the front for shellexec. */ @@ -818,7 +827,8 @@ evalcommand(union node *cmd, int flags) redir_stop = pushredir(cmd->ncmd.redirect); status = redirectsafe(cmd->ncmd.redirect, REDIR_PUSH|REDIR_SAVEFD2); - if (status) { + if (unlikely(status)) { + vlocal = 0; bail: exitstatus = status; @@ -829,13 +839,19 @@ bail: goto out; } + if (likely(vlocal)) + localvar_stop = pushlocalvars(); + for (argp = cmd->ncmd.assign; argp; argp = argp->narg.next) { struct strlist **spp; spp = varlist.lastp; 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. */ @@ -857,8 +873,8 @@ bail: /* Now locate the command. */ if (cmdentry.cmdtype != CMDBUILTIN || !(cmdentry.u.cmd->flags & BUILTIN_REGULAR)) { - find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, - unlikely(path) ? path : pathval()); + path = unlikely(path) ? path : pathval(); + find_command(argv[0], &cmdentry, cmd_flag | DO_ERR, path); } jp = NULL; @@ -881,17 +897,10 @@ bail: break; FORCEINTON; } - listsetvar(varlist.list, VEXPORT|VSTACK); - path = unlikely(path) ? path : pathval(); shellexec(argv, path, cmdentry.u.index); /* NOTREACHED */ case CMDBUILTIN: - if (spclbltin > 0 || argc == 0) { - poplocalvars(1); - if (execcmd && argc > 1) - listsetvar(varlist.list, VEXPORT); - } if (evalbltin(cmdentry.u.cmd, argc, argv, flags) && !(exception == EXERROR && spclbltin <= 0)) { raise: @@ -913,7 +922,8 @@ out: popredir(execcmd); unwindredir(redir_stop); unwindfiles(file_stop); - unwindlocalvars(localvar_stop); + if (likely(vlocal)) + unwindlocalvars(localvar_stop); if (lastarg) /* dsl: I think this is intended to be used to support * '_' in 'vi' command mode during line editing... diff --git a/src/var.c b/src/var.c index 604ab1f..40743e5 100644 --- a/src/var.c +++ b/src/var.c @@ -302,28 +302,6 @@ out: return vp; } - - -/* - * Process a linked list of variable assignments. - */ - -void -listsetvar(struct strlist *list, int flags) -{ - struct strlist *lp; - - lp = list; - if (!lp) - return; - INTOFF; - do { - setvareq(lp->text, flags); - } while ((lp = lp->next)); - INTON; -} - - /* * Find the value of a variable. Returns NULL if not set. */ @@ -468,7 +446,7 @@ localcmd(int argc, char **argv) argv = argptr; while ((name = *argv++) != NULL) { - mklocal(name); + mklocal(name, 0); } return 0; } @@ -481,7 +459,7 @@ localcmd(int argc, char **argv) * "-" as a special case. */ -void mklocal(char *name) +void mklocal(char *name, int flags) { struct localvar *lvp; struct var **vpp; @@ -502,16 +480,16 @@ void mklocal(char *name) eq = strchr(name, '='); if (vp == NULL) { if (eq) - vp = setvareq(name, VSTRFIXED); + vp = setvareq(name, VSTRFIXED | flags); else - vp = setvar(name, NULL, VSTRFIXED); + vp = setvar(name, NULL, VSTRFIXED | flags); lvp->flags = VUNSET; } else { lvp->text = vp->text; lvp->flags = vp->flags; vp->flags |= VSTRFIXED|VTEXTFIXED; if (eq) - setvareq(name, 0); + setvareq(name, flags); } } lvp->vp = vp; diff --git a/src/var.h b/src/var.h index 55fed1b..b2054f7 100644 --- a/src/var.h +++ b/src/var.h @@ -139,7 +139,6 @@ struct var *setvar(const char *name, const char *val, int flags); intmax_t setvarint(const char *, intmax_t, int); struct var *setvareq(char *s, int flags); struct strlist; -void listsetvar(struct strlist *, int); char *lookupvar(const char *); intmax_t lookupvarint(const char *); char **listvars(int, int, char ***); @@ -147,7 +146,7 @@ char **listvars(int, int, char ***); int showvars(const char *, int, int); int exportcmd(int, char **); int localcmd(int, char **); -void mklocal(char *); +void mklocal(char *name, int flags); struct localvar_list *pushlocalvars(void); void poplocalvars(int); void unwindlocalvars(struct localvar_list *stop);