From patchwork Wed Oct 7 07:20:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rasmus Villemoes X-Patchwork-Id: 1377808 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=reject dis=none) header.from=prevas.dk Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=prevas.dk header.i=@prevas.dk header.a=rsa-sha256 header.s=selector1 header.b=LKmoHCGx; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4C5m3l552Mz9s0b for ; Wed, 7 Oct 2020 18:21:39 +1100 (AEDT) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 3EF4F823DF; Wed, 7 Oct 2020 09:21:15 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=prevas.dk Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=prevas.dk header.i=@prevas.dk header.b="LKmoHCGx"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id D05A3823AF; Wed, 7 Oct 2020 09:21:13 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FORGED_SPF_HELO,MSGID_FROM_MTA_HEADER, SPF_HELO_PASS,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from EUR02-VE1-obe.outbound.protection.outlook.com (mail-ve1eur02on0713.outbound.protection.outlook.com [IPv6:2a01:111:f400:fe06::713]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id AEAE5823AF for ; Wed, 7 Oct 2020 09:21:07 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=pass (p=reject dis=none) header.from=prevas.dk Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=rasmus.villemoes@prevas.dk ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TtcoEj9989HenuZ2HgIC+gNK/VjCnpY7KoQ05TCZui3OGljnqcrjNOeUE+wxALk3hviNj0w7vtt2y2CZq8QiK1nr+f80aBGdz+saKZkqO39Xt6OCzGaffekAdj3WdF1yqNjpHtVmPnXUFJmUzeuDwXzWPnnhW3LyxGsy2MUIGdGP0QTfbfh9cPhWtdz5A+U3M02wPOUTVkYpwglUoe21AXLuKXfWtdEQ1D8FbONNsUzQqQpnD+Q87brMMa2uygBAObfYo9l0uhN80TKnrpNJTGJHvDLMJJr1ndH9yCKQi71AUuLLWH7llHSyv26aFO6DdVKh0f7ajLlxgls03WVPhQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=src1T/B6clzMPILNab6hhAjMq+ay44v0sRrFYlv5Xgg=; b=LxkZGWw+eK4bLOkx1o+IjvfurCY2E0VQ6RCh6V+NUA1KA+817E1BlMIL+eb7H1W4qPhdRvKxy1HuHQmOVdbRIfXYVC+2z99FRk8wunyFgVI6UionU45cBaQXhZVvLHqVDTViR5N4plGQv+cLkakyP7krwjPgKdX2zOpI/+idS0+eydqPiR9D9GRoQuH3W1DoDfEoM9zjozXi2NHgul34/RpAwDqWsoTEzAmepVX6N3gn1xNQLkEFg49FYffQJPe7P59Xh/qh+nALpb1m6Vly/QKLDuALVAEBHfGUm8hbJRxbpkGQs4BiK6tQtctBeVsgTpy4LBFVyafQYc0cm0JwSQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=prevas.dk; dmarc=pass action=none header.from=prevas.dk; dkim=pass header.d=prevas.dk; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=prevas.dk; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=src1T/B6clzMPILNab6hhAjMq+ay44v0sRrFYlv5Xgg=; b=LKmoHCGxyX8q+QDVOi7Zz3ffX5ra4tQIOJMxHv1lJxejMTBOl7AyzFiuQjXvONDcvYYBuMHhzhWKQ0BFdSjI8zSpKpbyp158/BOcx3C3Ml4G/Akl6145zvk7JLr2P25WaE8nv9JPdmxBnotXJ4FFnXug75L2adavrCt50neBEgk= Authentication-Results: lists.denx.de; dkim=none (message not signed) header.d=none;lists.denx.de; dmarc=none action=none header.from=prevas.dk; Received: from AM6PR10MB1880.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:2f::12) by AM7PR10MB3333.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:20b:10c::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.22; Wed, 7 Oct 2020 07:21:06 +0000 Received: from AM6PR10MB1880.EURPRD10.PROD.OUTLOOK.COM ([fe80::dc8a:f8d9:a15f:44ce]) by AM6PR10MB1880.EURPRD10.PROD.OUTLOOK.COM ([fe80::dc8a:f8d9:a15f:44ce%7]) with mapi id 15.20.3433.045; Wed, 7 Oct 2020 07:21:06 +0000 From: Rasmus Villemoes To: u-boot@lists.denx.de Cc: Simon Glass , Heinrich Schuchardt , Wolfgang Denk , Tom Rini , Rasmus Villemoes Subject: [PATCH v2 2/3] allow positional arguments with "run" command Date: Wed, 7 Oct 2020 09:20:51 +0200 Message-Id: <20201007072052.28200-3-rasmus.villemoes@prevas.dk> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20201007072052.28200-1-rasmus.villemoes@prevas.dk> References: <20200925111942.4629-1-rasmus.villemoes@prevas.dk> <20201007072052.28200-1-rasmus.villemoes@prevas.dk> X-Originating-IP: [81.216.59.226] X-ClientProxiedBy: AM0PR04CA0005.eurprd04.prod.outlook.com (2603:10a6:208:122::18) To AM6PR10MB1880.EURPRD10.PROD.OUTLOOK.COM (2603:10a6:209:2f::12) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from prevas-ravi.prevas.se (81.216.59.226) by AM0PR04CA0005.eurprd04.prod.outlook.com (2603:10a6:208:122::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3455.21 via Frontend Transport; Wed, 7 Oct 2020 07:21:05 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: d3f79f89-6915-4f76-dfe1-08d86a918e16 X-MS-TrafficTypeDiagnostic: AM7PR10MB3333: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:1051; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: ACY/phS39X3FK+2sFAtY6FTrxd9zNZepH7oUbVSLoDc4nDHOT5FNpVkwyGKqxaHk1L6OmRSZpANOLq7NCjBl7rE4CXtlv9NEUQnnwQQVlSUANgy5/vNzSuvnfITF0nGiT9x7Y0N+zoml+wuVMVjhy/fQojaCGbNqwsjp6z7KGmQRUP2Ez4xBDJv5lO1F4hbPmIiypTumPAm1R33r2KrfmyVGwqmbA5igaEfAJEuAEPERnpI/Cy2pybHrtTJbE/NfS7VbwnZexDoDyCtBgy2yHKcGQheP9BC3bqMC9TNp21qRRHyQlKvDLrulkHit3STKrP4Fx5ejDsTPNA0gRKoufw== X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM6PR10MB1880.EURPRD10.PROD.OUTLOOK.COM; PTR:; CAT:NONE; SFS:(396003)(346002)(136003)(39840400004)(366004)(376002)(107886003)(66476007)(66556008)(8676002)(36756003)(66946007)(26005)(16526019)(8976002)(8936002)(186003)(6512007)(478600001)(2616005)(956004)(6506007)(6486002)(5660300002)(1076003)(52116002)(83380400001)(54906003)(4326008)(6666004)(86362001)(316002)(44832011)(2906002)(6916009); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData: pVqmlDLfT2rt6vgipE+NsIEV/L1Jx9XHHMg0ZUcXoR9w4mPc1nVbxqIn0VIE8AZbssyhp/FSPS06tFbDj2fsYfSOOPa1ATI2ODg8ChWH6tXUz5bZ35fhF8jkSIq1DvvAQXLJZuKAMP+9tYlKFuJaiGr6ObvxP5eG7OPdhl0fN2KOkpCOLPm56INFIO7B0644jlnFuAf9Qtm4gLWa44695YvlnjcEp3QFet8ccJXnKeYEUhFqKKaQDMC0Lz6MwoZdviNM52dXkoUGKpkvb44kBTukjdJElBW7/ljodztPal56SGkJSa/vyyMkLlAYCLcYbAoosVgZLxiMh54d3aKKEE8PT+d5799v64UzjQUxPFLT2kFS2PMO7qXIiQ2UNUIDlb2ud6ow1TUIvOevs5+egf0/wjBK7kYRSxBHkNxc/cnkJM1PzY0BXFfes2uF19jl0MGpx1VDkLYZeV5W83WIOV0v4sm/prDfj/pVuwfSKDdO4tQ8kPqWxRqL0ethezPqcwMHFrictbX74xlppK3nugCPGGPpARuVafIWKdTFHGBkW7vWze6hw7d4BaI+kEbYklNYZ7XULZhIO/iIYF9MmIFGbrbExIMJV0Y70cOEavWBEnHstlwwb7fFkyULb73fhcahOs6gIR/7vKOwkHeqmA== X-OriginatorOrg: prevas.dk X-MS-Exchange-CrossTenant-Network-Message-Id: d3f79f89-6915-4f76-dfe1-08d86a918e16 X-MS-Exchange-CrossTenant-AuthSource: AM6PR10MB1880.EURPRD10.PROD.OUTLOOK.COM X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 Oct 2020 07:21:06.1969 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: d350cf71-778d-4780-88f5-071a4cb1ed61 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: JP9p7SJpD7DtQvCMZaBKNlY9CSJ0P1xtSmmcfOCYw3/LwhNgh+rlm+w2Ea0ORKAWb8sBpT93oiPs0g585/ta/tmCWBIycn2Bp6cOXK958nA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM7PR10MB3333 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.102.3 at phobos.denx.de X-Virus-Status: Clean Currently, the only way to emulate functions with arguments in the U-Boot shell is by doing "foo=arg1; bar=arg2; run func" and having "func" refer to $foo and $bar. That works, but is a bit clunky, and also suffers from foo and bar being set globally - if func itself wants to run other "functions" defined in the environment, those other functions better not use the same parameter names: setenv g 'do_g_stuff $foo' setenv f 'do_f_stuff $foo $bar; foo=123; run g; do_more_f_stuff $foo $bar' foo=arg1; bar=arg2; run f Sure, f could do a "saved_foo=$foo; .... foo=$saved_foo" dance, but that makes everything even more clunky. In order to increase readability, allow passing positional arguments to the functions invoked via run: When invoked with a -- separator, the remaining arguments are use to set the local shell variables $1 through $9 (and $#). As in a "real" shell, they are local to the current function, so if f is called with two arguments, and f calls g with one argument, g sees $2 as unset. Then the above can be written setenv g 'do_g_stuff $1' setenv f 'do_f_stuff $1 $2; run g -- 123; do_more_f_stuff $1 $2' run f -- arg1 arg2 Everything except - b_addchr(dest, '?'); + b_addchr(dest, ch); is under CONFIG_CMD_RUN_ARGS, and when CONFIG_CMD_RUN_ARGS=n, the ch there can only be '?'. So no functional change when CONFIG_CMD_RUN_ARGS is not selected. Signed-off-by: Rasmus Villemoes Reviewed-by: Simon Glass --- cmd/Kconfig | 10 ++++++++++ cmd/nvedit.c | 7 ++++++- common/cli.c | 44 ++++++++++++++++++++++++++++++++++++++------ common/cli_hush.c | 32 +++++++++++++++++++++++++++++++- include/cli_hush.h | 9 +++++++++ 5 files changed, 94 insertions(+), 8 deletions(-) diff --git a/cmd/Kconfig b/cmd/Kconfig index 0c984d735d..b8426d19d7 100644 --- a/cmd/Kconfig +++ b/cmd/Kconfig @@ -443,6 +443,16 @@ config CMD_RUN help Run the command in the given environment variable. +config CMD_RUN_ARGS + bool "allow positional arguments with run command" + depends on HUSH_PARSER + depends on CMD_RUN + help + Allow invoking 'run' as 'run f g -- arg1 arg2 ...', which + will run the commands defined in the environment variables f + and g with positional arguments $1..$9 set to the arguments + following the -- separator. + config CMD_IMI bool "iminfo" default y diff --git a/cmd/nvedit.c b/cmd/nvedit.c index 7fce723800..202139bfb9 100644 --- a/cmd/nvedit.c +++ b/cmd/nvedit.c @@ -1575,7 +1575,12 @@ U_BOOT_CMD_COMPLETE( run, CONFIG_SYS_MAXARGS, 1, do_run, "run commands in an environment variable", "var [...]\n" - " - run the commands in the environment variable(s) 'var'", + " - run the commands in the environment variable(s) 'var'\n" + CONFIG_IS_ENABLED(CMD_RUN_ARGS, ( + "run var [...] -- arg1 arg2 [...]\n" + " - run the commands in the environment variable(s) 'var',\n" + " with shell variables $1, $2, ... set to arg1, arg2, ...\n" + )), var_complete ); #endif diff --git a/common/cli.c b/common/cli.c index 6635ab2bcf..f970bd1eae 100644 --- a/common/cli.c +++ b/common/cli.c @@ -131,24 +131,56 @@ int run_command_list(const char *cmd, int len, int flag) #if defined(CONFIG_CMD_RUN) int do_run(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { - int i; + struct run_args ra; + int i, j; + int ret = 0; + int cmds = argc; if (argc < 2) return CMD_RET_USAGE; - for (i = 1; i < argc; ++i) { + if (CONFIG_IS_ENABLED(CMD_RUN_ARGS)) { + for (i = 1; i < argc; ++i) { + if (!strcmp(argv[i], "--")) { + cmds = i; + ++i; + break; + } + } + ra.count = argc - i; + if (ra.count > MAX_RUN_ARGS) { + printf("## Error: At most %d positional arguments allowed\n", + MAX_RUN_ARGS); + return 1; + } + for (j = i; j < argc; ++j) + ra.args[j - i] = argv[j]; + + ra.prev = current_run_args; + current_run_args = &ra; + } + + for (i = 1; i < cmds; ++i) { char *arg; arg = env_get(argv[i]); if (arg == NULL) { printf("## Error: \"%s\" not defined\n", argv[i]); - return 1; + ret = 1; + goto out; } - if (run_command(arg, flag | CMD_FLAG_ENV) != 0) - return 1; + if (run_command(arg, flag | CMD_FLAG_ENV) != 0) { + ret = 1; + goto out; + } } - return 0; + +out: + if (CONFIG_IS_ENABLED(CMD_RUN_ARGS)) + current_run_args = ra.prev; + + return ret; } #endif diff --git a/common/cli_hush.c b/common/cli_hush.c index 072b871f1e..df35c9c8d2 100644 --- a/common/cli_hush.c +++ b/common/cli_hush.c @@ -135,6 +135,11 @@ DECLARE_GLOBAL_DATA_PTR; #define syntax() syntax_err() #define xstrdup strdup #define error_msg printf + +#ifdef CONFIG_CMD_RUN_ARGS +struct run_args *current_run_args; +#endif + #else typedef enum { REDIRECT_INPUT = 1, @@ -2144,6 +2149,10 @@ char *get_local_var(const char *s) #ifdef __U_BOOT__ if (*s == '$') return get_dollar_var(s[1]); + /* To make ${1:-default} work: */ + if (IS_ENABLED(CONFIG_CMD_RUN_ARGS) && + '1' <= s[0] && s[0] <= '9' && !s[1]) + return get_dollar_var(s[0]); #endif for (cur = top_vars; cur; cur=cur->next) @@ -2826,6 +2835,23 @@ static char *get_dollar_var(char ch) case '?': sprintf(buf, "%u", (unsigned int)last_return_code); break; +#ifdef CONFIG_CMD_RUN_ARGS + case '#': + if (!current_run_args) + return NULL; + sprintf(buf, "%u", current_run_args->count); + break; + case '1' ... '9': { + const struct run_args *ra = current_run_args; + int i = ch - '1'; + + if (!ra) + return NULL; + if (i >= ra->count) + return NULL; + return ra->args[i]; + } +#endif default: return NULL; } @@ -2865,10 +2891,14 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i } else switch (ch) { #ifdef __U_BOOT__ case '?': +#ifdef CONFIG_CMD_RUN_ARGS + case '1' ... '9': + case '#': +#endif ctx->child->sp++; b_addchr(dest, SPECIAL_VAR_SYMBOL); b_addchr(dest, '$'); - b_addchr(dest, '?'); + b_addchr(dest, ch); b_addchr(dest, SPECIAL_VAR_SYMBOL); advance = 1; break; diff --git a/include/cli_hush.h b/include/cli_hush.h index 2bd35670c7..d6eb7e908d 100644 --- a/include/cli_hush.h +++ b/include/cli_hush.h @@ -23,4 +23,13 @@ char *get_local_var(const char *s); #if defined(CONFIG_HUSH_INIT_VAR) extern int hush_init_var (void); #endif + +#define MAX_RUN_ARGS 9 +struct run_args { + struct run_args *prev; + int count; + char *args[MAX_RUN_ARGS]; /* [0] holds $1 etc. */ +}; +extern struct run_args *current_run_args; + #endif