public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
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>

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox