diff mbox series

[U-Boot,v2,4/6] command: commands: Add macros to declare commands with subcmds

Message ID 20181128233921.16675-5-boris.brezillon@bootlin.com
State Superseded
Delegated to: Tom Rini
Headers show
Series cmd: Simplify support for sub-commands | expand

Commit Message

Boris Brezillon Nov. 28, 2018, 11:39 p.m. UTC
Most cmd/xxx.c source files expose several commands through a single
entry point. Some of them are doing the sub-command parsing manually in
their do_<cmd>() function, others are declaring a table of sub-commands
and then use find_cmd_tbl() to delegate the request to the sub command
handler.

In both case, the amount of code to do that is not negligible and
repetitive, not to mention that almost no commands are implementing
a auto-completion hook, which means most u-boot lack auto-completion.

Provide several macros to easily define sub-commands and commands
exposing such sub-commands.

Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
---
Changes in v2:
- Remove _maxargs argument
---
 include/command.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

Comments

Tom Rini Nov. 29, 2018, 2:20 p.m. UTC | #1
On Thu, Nov 29, 2018 at 12:39:19AM +0100, Boris Brezillon wrote:

> Most cmd/xxx.c source files expose several commands through a single
> entry point. Some of them are doing the sub-command parsing manually in
> their do_<cmd>() function, others are declaring a table of sub-commands
> and then use find_cmd_tbl() to delegate the request to the sub command
> handler.
> 
> In both case, the amount of code to do that is not negligible and
> repetitive, not to mention that almost no commands are implementing
> a auto-completion hook, which means most u-boot lack auto-completion.
> 
> Provide several macros to easily define sub-commands and commands
> exposing such sub-commands.
> 
> Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>

Reviewed-by: Tom Rini <trini@konsulko.com>
Boris Brezillon Nov. 29, 2018, 3:22 p.m. UTC | #2
On Thu, 29 Nov 2018 00:39:19 +0100
Boris Brezillon <boris.brezillon@bootlin.com> wrote:

> Most cmd/xxx.c source files expose several commands through a single
> entry point. Some of them are doing the sub-command parsing manually in
> their do_<cmd>() function, others are declaring a table of sub-commands
> and then use find_cmd_tbl() to delegate the request to the sub command
> handler.
> 
> In both case, the amount of code to do that is not negligible and

	  ^cases

> repetitive, not to mention that almost no commands are implementing
> a auto-completion hook, which means most u-boot lack auto-completion.

  ^the						  ^commands

> 
> Provide several macros to easily define sub-commands and commands
> exposing such sub-commands.

"
Provide several macros to easily define commands exposing sub-commands.
"

> 
> Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
> ---
> Changes in v2:
> - Remove _maxargs argument
> ---
>  include/command.h | 78 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 78 insertions(+)
> 
> diff --git a/include/command.h b/include/command.h
> index bb93f022c514..461b17447c0d 100644
> --- a/include/command.h
> +++ b/include/command.h
> @@ -209,6 +209,70 @@ int board_run_command(const char *cmdline);
>  # define _CMD_HELP(x)
>  #endif
>  
> +#ifdef CONFIG_NEEDS_MANUAL_RELOC
> +#define U_BOOT_SUBCMDS_RELOC(_cmdname)					\
> +	static void _cmdname##_subcmds_reloc(void)			\
> +	{								\
> +		static int relocated;					\
> +									\
> +		if (relocated)						\
> +			return;						\
> +									\
> +		fixup_cmdtable(_cmdname##_subcmds,			\
> +			       ARRAY_SIZE(_cmdname##_subcmds));		\
> +		relocated = 1;						\
> +	}
> +#else
> +#define U_BOOT_SUBCMDS_RELOC(_cmdname)					\
> +	static void _cmdname##_subcmds_reloc(void) { }
> +#endif
> +
> +#define U_BOOT_SUBCMDS_DO_CMD(_cmdname)					\
> +	static int do_##_cmdname(cmd_tbl_t *cmdtp, int flag, int argc,	\
> +				 char * const argv[], int *repeatable)	\
> +	{								\
> +		cmd_tbl_t *subcmd;					\
> +									\
> +		_cmdname##_subcmds_reloc();				\
> +									\
> +		/* We need at least the cmd and subcmd names. */	\
> +		if (argc < 2 || argc > CONFIG_SYS_MAXARGS)		\
> +			return CMD_RET_USAGE;				\
> +									\
> +		subcmd = find_cmd_tbl(argv[1], _cmdname##_subcmds,	\
> +				      ARRAY_SIZE(_cmdname##_subcmds));	\
> +		if (!subcmd || argc - 1 > subcmd->maxargs)		\
> +			return CMD_RET_USAGE;				\
> +									\
> +		if (flag == CMD_FLAG_REPEAT &&				\
> +		    !cmd_is_repeatable(subcmd))				\
> +			return CMD_RET_SUCCESS;				\
> +									\
> +		return subcmd->cmd_rep(subcmd, flag, argc - 1,		\
> +				       argv + 1, repeatable);		\
> +	}
> +
> +#ifdef CONFIG_AUTO_COMPLETE
> +#define U_BOOT_SUBCMDS_COMPLETE(_cmdname)				\
> +	static int complete_##_cmdname(int argc, char * const argv[],	\
> +				       char last_char, int maxv,	\
> +				       char *cmdv[])			\
> +	{								\
> +		return complete_subcmdv(_cmdname##_subcmds,		\
> +					ARRAY_SIZE(_cmdname##_subcmds),	\
> +					argc - 1, argv + 1, last_char,	\
> +					maxv, cmdv);			\
> +	}
> +#else
> +#define U_BOOT_SUBCMDS_COMPLETE(_cmdname)
> +#endif
> +
> +#define U_BOOT_SUBCMDS(_cmdname, ...)					\
> +	static cmd_tbl_t _cmdname##_subcmds[] = { __VA_ARGS__ };	\
> +	U_BOOT_SUBCMDS_RELOC(_cmdname)					\
> +	U_BOOT_SUBCMDS_DO_CMD(_cmdname)					\
> +	U_BOOT_SUBCMDS_COMPLETE(_cmdname)
> +
>  #ifdef CONFIG_CMDLINE
>  #define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep,		\
>  				     _usage, _help, _comp)		\
> @@ -271,4 +335,18 @@ int board_run_command(const char *cmdline);
>  	U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,		\
>  					_usage, _help, NULL)
>  
> +#define U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd,	\
> +				     _comp)				\
> +	U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd,	\
> +				  "", "", _comp)
> +
> +#define U_BOOT_SUBCMD_MKENT(_name, _maxargs, _rep, _do_cmd)		\
> +	U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd,	\
> +				     NULL)
> +
> +#define U_BOOT_CMD_WITH_SUBCMDS(_name, _usage, _help, ...)		\
> +	U_BOOT_SUBCMDS(_name, __VA_ARGS__)				\
> +	U_BOOT_CMDREP_COMPLETE(_name, CONFIG_SYS_MAXARGS, do_##_name,	\
> +			       _usage, _help, complete_##_name)
> +
>  #endif	/* __COMMAND_H */
diff mbox series

Patch

diff --git a/include/command.h b/include/command.h
index bb93f022c514..461b17447c0d 100644
--- a/include/command.h
+++ b/include/command.h
@@ -209,6 +209,70 @@  int board_run_command(const char *cmdline);
 # define _CMD_HELP(x)
 #endif
 
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+#define U_BOOT_SUBCMDS_RELOC(_cmdname)					\
+	static void _cmdname##_subcmds_reloc(void)			\
+	{								\
+		static int relocated;					\
+									\
+		if (relocated)						\
+			return;						\
+									\
+		fixup_cmdtable(_cmdname##_subcmds,			\
+			       ARRAY_SIZE(_cmdname##_subcmds));		\
+		relocated = 1;						\
+	}
+#else
+#define U_BOOT_SUBCMDS_RELOC(_cmdname)					\
+	static void _cmdname##_subcmds_reloc(void) { }
+#endif
+
+#define U_BOOT_SUBCMDS_DO_CMD(_cmdname)					\
+	static int do_##_cmdname(cmd_tbl_t *cmdtp, int flag, int argc,	\
+				 char * const argv[], int *repeatable)	\
+	{								\
+		cmd_tbl_t *subcmd;					\
+									\
+		_cmdname##_subcmds_reloc();				\
+									\
+		/* We need at least the cmd and subcmd names. */	\
+		if (argc < 2 || argc > CONFIG_SYS_MAXARGS)		\
+			return CMD_RET_USAGE;				\
+									\
+		subcmd = find_cmd_tbl(argv[1], _cmdname##_subcmds,	\
+				      ARRAY_SIZE(_cmdname##_subcmds));	\
+		if (!subcmd || argc - 1 > subcmd->maxargs)		\
+			return CMD_RET_USAGE;				\
+									\
+		if (flag == CMD_FLAG_REPEAT &&				\
+		    !cmd_is_repeatable(subcmd))				\
+			return CMD_RET_SUCCESS;				\
+									\
+		return subcmd->cmd_rep(subcmd, flag, argc - 1,		\
+				       argv + 1, repeatable);		\
+	}
+
+#ifdef CONFIG_AUTO_COMPLETE
+#define U_BOOT_SUBCMDS_COMPLETE(_cmdname)				\
+	static int complete_##_cmdname(int argc, char * const argv[],	\
+				       char last_char, int maxv,	\
+				       char *cmdv[])			\
+	{								\
+		return complete_subcmdv(_cmdname##_subcmds,		\
+					ARRAY_SIZE(_cmdname##_subcmds),	\
+					argc - 1, argv + 1, last_char,	\
+					maxv, cmdv);			\
+	}
+#else
+#define U_BOOT_SUBCMDS_COMPLETE(_cmdname)
+#endif
+
+#define U_BOOT_SUBCMDS(_cmdname, ...)					\
+	static cmd_tbl_t _cmdname##_subcmds[] = { __VA_ARGS__ };	\
+	U_BOOT_SUBCMDS_RELOC(_cmdname)					\
+	U_BOOT_SUBCMDS_DO_CMD(_cmdname)					\
+	U_BOOT_SUBCMDS_COMPLETE(_cmdname)
+
 #ifdef CONFIG_CMDLINE
 #define U_BOOT_CMDREP_MKENT_COMPLETE(_name, _maxargs, _cmd_rep,		\
 				     _usage, _help, _comp)		\
@@ -271,4 +335,18 @@  int board_run_command(const char *cmdline);
 	U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _cmd,		\
 					_usage, _help, NULL)
 
+#define U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd,	\
+				     _comp)				\
+	U_BOOT_CMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd,	\
+				  "", "", _comp)
+
+#define U_BOOT_SUBCMD_MKENT(_name, _maxargs, _rep, _do_cmd)		\
+	U_BOOT_SUBCMD_MKENT_COMPLETE(_name, _maxargs, _rep, _do_cmd,	\
+				     NULL)
+
+#define U_BOOT_CMD_WITH_SUBCMDS(_name, _usage, _help, ...)		\
+	U_BOOT_SUBCMDS(_name, __VA_ARGS__)				\
+	U_BOOT_CMDREP_COMPLETE(_name, CONFIG_SYS_MAXARGS, do_##_name,	\
+			       _usage, _help, complete_##_name)
+
 #endif	/* __COMMAND_H */