From: Tom Rini <trini@konsulko.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [U-Boot, v4, 3/6] common: command: Rework the 'cmd is repeatable' logic
Date: Tue, 15 Jan 2019 21:38:57 -0500 [thread overview]
Message-ID: <20190116023857.GL27429@bill-the-cat> (raw)
In-Reply-To: <20181203215423.18772-4-boris.brezillon@bootlin.com>
On Mon, Dec 03, 2018 at 10:54:20PM +0100, Boris Brezillon wrote:
> The repeatable property is currently attached to the main command and
> sub-commands have no way to change the repeatable value (the
> ->repeatable field in sub-command entries is ignored).
>
> Replace the ->repeatable field by an extended ->cmd() hook (called
> ->cmd_rep()) which takes a new int pointer to store the repeatable cap
> of the command being executed.
>
> With this trick, we can let sub-commands decide whether they are
> repeatable or not.
>
> We also patch mmc and dtimg who are testing the ->repeatable field
> directly (they now use cmd_is_repeatable() instead), and fix the help
> entry manually since it doesn't use the U_BOOT_CMD() macro.
>
> Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
> Reviewed-by: Tom Rini <trini@konsulko.com>
> ---
> Changes in v4:
> -None
>
> Changes in v3:
> - Add Tom's R-b
>
> Changes in v2:
> - New patch
> ---
> cmd/dtimg.c | 2 +-
> cmd/help.c | 2 +-
> cmd/mmc.c | 4 ++--
> common/command.c | 36 ++++++++++++++++++++++++++++----
> include/command.h | 52 +++++++++++++++++++++++++++++++++++++++++++----
> 5 files changed, 84 insertions(+), 12 deletions(-)
>
> diff --git a/cmd/dtimg.c b/cmd/dtimg.c
> index 65c8d101b98e..ae7d82f26dd2 100644
> --- a/cmd/dtimg.c
> +++ b/cmd/dtimg.c
> @@ -116,7 +116,7 @@ static int do_dtimg(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>
> if (!cp || argc > cp->maxargs)
> return CMD_RET_USAGE;
> - if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
> + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
> return CMD_RET_SUCCESS;
>
> return cp->cmd(cmdtp, flag, argc, argv);
> diff --git a/cmd/help.c b/cmd/help.c
> index 503fa632e74e..fa2010c67eb1 100644
> --- a/cmd/help.c
> +++ b/cmd/help.c
> @@ -29,7 +29,7 @@ U_BOOT_CMD(
>
> /* This does not use the U_BOOT_CMD macro as ? can't be used in symbol names */
> ll_entry_declare(cmd_tbl_t, question_mark, cmd) = {
> - "?", CONFIG_SYS_MAXARGS, 1, do_help,
> + "?", CONFIG_SYS_MAXARGS, cmd_always_repeatable, do_help,
> "alias for 'help'",
> #ifdef CONFIG_SYS_LONGHELP
> ""
> diff --git a/cmd/mmc.c b/cmd/mmc.c
> index 3920a1836a59..42e38900df12 100644
> --- a/cmd/mmc.c
> +++ b/cmd/mmc.c
> @@ -247,7 +247,7 @@ static int do_mmcrpmb(cmd_tbl_t *cmdtp, int flag,
>
> if (cp == NULL || argc > cp->maxargs)
> return CMD_RET_USAGE;
> - if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
> + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
> return CMD_RET_SUCCESS;
>
> mmc = init_mmc_device(curr_device, false);
> @@ -907,7 +907,7 @@ static int do_mmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
>
> if (cp == NULL || argc > cp->maxargs)
> return CMD_RET_USAGE;
> - if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
> + if (flag == CMD_FLAG_REPEAT && !cmd_is_repeatable(cp))
> return CMD_RET_SUCCESS;
>
> if (curr_device < 0) {
> diff --git a/common/command.c b/common/command.c
> index e13cb47ac18b..19f0534a76ea 100644
> --- a/common/command.c
> +++ b/common/command.c
> @@ -501,6 +501,30 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size)
> }
> #endif
>
> +int cmd_always_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[], int *repeatable)
> +{
> + *repeatable = 1;
> +
> + return cmdtp->cmd(cmdtp, flag, argc, argv);
> +}
> +
> +int cmd_never_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[], int *repeatable)
> +{
> + *repeatable = 0;
> +
> + return cmdtp->cmd(cmdtp, flag, argc, argv);
> +}
> +
> +int cmd_discard_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[])
> +{
> + int repeatable;
> +
> + return cmdtp->cmd_rep(cmdtp, flag, argc, argv, &repeatable);
> +}
> +
> /**
> * Call a command function. This should be the only route in U-Boot to call
> * a command, so that we can track whether we are waiting for input or
> @@ -510,13 +534,15 @@ void fixup_cmdtable(cmd_tbl_t *cmdtp, int size)
> * @param flag Some flags normally 0 (see CMD_FLAG_.. above)
> * @param argc Number of arguments (arg 0 must be the command text)
> * @param argv Arguments
> + * @param repeatable Can the command be repeated
> * @return 0 if command succeeded, else non-zero (CMD_RET_...)
> */
> -static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
> +static int cmd_call(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],
> + int *repeatable)
> {
> int result;
>
> - result = (cmdtp->cmd)(cmdtp, flag, argc, argv);
> + result = cmdtp->cmd_rep(cmdtp, flag, argc, argv, repeatable);
> if (result)
> debug("Command failed, result=%d\n", result);
> return result;
> @@ -553,12 +579,14 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[],
>
> /* If OK so far, then do the command */
> if (!rc) {
> + int newrep;
> +
> if (ticks)
> *ticks = get_timer(0);
> - rc = cmd_call(cmdtp, flag, argc, argv);
> + rc = cmd_call(cmdtp, flag, argc, argv, &newrep);
> if (ticks)
> *ticks = get_timer(*ticks);
> - *repeatable &= cmdtp->repeatable;
> + *repeatable &= newrep;
> }
> if (rc == CMD_RET_USAGE)
> rc = cmd_usage(cmdtp);
> diff --git a/include/command.h b/include/command.h
> index 89efcecfa926..bb93f022c514 100644
> --- a/include/command.h
> +++ b/include/command.h
> @@ -29,7 +29,16 @@
> struct cmd_tbl_s {
> char *name; /* Command Name */
> int maxargs; /* maximum number of arguments */
> - int repeatable; /* autorepeat allowed? */
> + /*
> + * Same as ->cmd() except the command
> + * tells us if it can be repeated.
> + * Replaces the old ->repeatable field
> + * which was not able to make
> + * repeatable property different for
> + * the main command and sub-commands.
> + */
> + int (*cmd_rep)(struct cmd_tbl_s *cmd, int flags, int argc,
> + char * const argv[], int *repeatable);
> /* Implementation function */
> int (*cmd)(struct cmd_tbl_s *, int, int, char * const []);
> char *usage; /* Usage message (short) */
> @@ -60,6 +69,19 @@ int complete_subcmdv(cmd_tbl_t *cmdtp, int count, int argc,
>
> extern int cmd_usage(const cmd_tbl_t *cmdtp);
>
> +/* Dummy ->cmd and ->cmd_rep wrappers. */
> +int cmd_always_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[], int *repeatable);
> +int cmd_never_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[], int *repeatable);
> +int cmd_discard_repeatable(cmd_tbl_t *cmdtp, int flag, int argc,
> + char * const argv[]);
> +
> +static inline bool cmd_is_repeatable(cmd_tbl_t *cmdtp)
> +{
> + return cmdtp->cmd_rep == cmd_always_repeatable;
> +}
> +
> #ifdef CONFIG_AUTO_COMPLETE
> extern int var_complete(int argc, char * const argv[], char last_char, int maxv, char *cmdv[]);
> extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int *colp);
> @@ -188,16 +210,28 @@ int board_run_command(const char *cmdline);
> #endif
>
> #ifdef CONFIG_CMDLINE
> +#define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \
> + _usage, _help, _comp) \
> + { #_name, _maxargs, _cmd_rep, cmd_discard_repeatable, \
> + _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
> +
> #define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \
> _usage, _help, _comp) \
> - { #_name, _maxargs, _rep, _cmd, _usage, \
> - _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
> + { #_name, _maxargs, \
> + _rep ? cmd_always_repeatable : cmd_never_repeatable, \
> + _cmd, _usage, _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
>
> #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, _comp) \
> ll_entry_declare(cmd_tbl_t, _name, cmd) = \
> U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, \
> _usage, _help, _comp);
>
> +#define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \
> + _help, _comp) \
> + ll_entry_declare(cmd_tbl_t, _name, cmd) = \
> + U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \
> + _usage, _help, _comp)
> +
> #else
> #define U_BOOT_SUBCMD_START(name) static cmd_tbl_t name[] = {};
> #define U_BOOT_SUBCMD_END
> @@ -209,15 +243,25 @@ int board_run_command(const char *cmdline);
> _cmd(NULL, 0, 0, NULL); \
> return 0; \
> }
> +
> +#define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep, \
> + _usage, _help, _comp) \
> + { #_name, _maxargs, 0 ? _cmd_rep : NULL, NULL, _usage, \
> + _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
> +
> #define U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, \
> _help, _comp) \
> - { #_name, _maxargs, _rep, 0 ? _cmd : NULL, _usage, \
> + { #_name, _maxargs, NULL, 0 ? _cmd : NULL, _usage, \
> _CMD_HELP(_help) _CMD_COMPLETE(_comp) }
>
> #define U_BOOT_CMD_COMPLETE(_name, _maxargs, _rep, _cmd, _usage, _help, \
> _comp) \
> _CMD_REMOVE(sub_ ## _name, _cmd)
>
> +#define U_BOOT_CMDREP_COMPLETE(_name, _maxargs, _cmd_rep, _usage, \
> + _help, _comp) \
> + _CMD_REMOVE(sub_ ## _name, _cmd_rep)
> +
> #endif /* CONFIG_CMDLINE */
>
> #define U_BOOT_CMD(_name, _maxargs, _rep, _cmd, _usage, _help) \
--
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20190115/522c52a8/attachment.sig>
next prev parent reply other threads:[~2019-01-16 2:38 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-12-03 21:54 [U-Boot] [PATCH v4 0/6] cmd: Simplify support for sub-commands Boris Brezillon
2018-12-03 21:54 ` [U-Boot] [PATCH v4 1/6] common: command: Fix command auto-completion Boris Brezillon
2018-12-11 1:04 ` Simon Glass
2018-12-11 11:24 ` Boris Brezillon
2018-12-11 20:37 ` Simon Glass
2019-01-16 2:39 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-12-03 21:54 ` [U-Boot] [PATCH v4 2/6] common: command: Expose a generic helper to auto-complete sub commands Boris Brezillon
2019-01-16 2:39 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-12-03 21:54 ` [U-Boot] [PATCH v4 3/6] common: command: Rework the 'cmd is repeatable' logic Boris Brezillon
2019-01-16 2:38 ` Tom Rini [this message]
2019-01-16 2:39 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-12-03 21:54 ` [U-Boot] [PATCH v4 4/6] command: commands: Add macros to declare commands with subcmds Boris Brezillon
2019-01-16 2:39 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-12-03 21:54 ` [U-Boot] [PATCH v4 5/6] cmd: mtd: Use the subcmd infrastructure to declare mtd sub-commands Boris Brezillon
2019-01-16 2:39 ` [U-Boot] [U-Boot, v4, " Tom Rini
2018-12-03 21:54 ` [U-Boot] [PATCH v4 6/6] cmd: adc: Use the sub-command infrastructure Boris Brezillon
2019-01-16 2:39 ` [U-Boot] [U-Boot, v4, " Tom Rini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190116023857.GL27429@bill-the-cat \
--to=trini@konsulko.com \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.