summaryrefslogtreecommitdiff
path: root/include/command.h
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@bootlin.com>2018-12-03 22:54:21 +0100
committerTom Rini <trini@konsulko.com>2019-01-15 15:28:54 -0500
commitc0cf06e523cbe50dbf38d5c81d0595f5b8517f4a (patch)
tree954992ff69b3a97ff6061a1b6ac927c570303393 /include/command.h
parent80a48dd47e3bf3ede676fae5a630cb6c80de3e69 (diff)
command: commands: Add macros to declare commands with subcmds
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 either case, the amount of code to do that is not negligible and repetitive, not to mention that almost no commands are implementing the auto-completion hook, which means most u-boot commands lack auto-completion. Provide several macros to easily define commands exposing sub-commands. Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com> Reviewed-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'include/command.h')
-rw-r--r--include/command.h78
1 files changed, 78 insertions, 0 deletions
diff --git a/include/command.h b/include/command.h
index bb93f022c5..461b17447c 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 */