summaryrefslogtreecommitdiff
path: root/include/command.h
diff options
context:
space:
mode:
authorBoris Brezillon <boris.brezillon@bootlin.com>2018-12-03 22:54:20 +0100
committerTom Rini <trini@konsulko.com>2019-01-15 15:28:54 -0500
commit80a48dd47e3bf3ede676fae5a630cb6c80de3e69 (patch)
treea31c7ac2e2b5f238dd127b8b7c86c199452d2adb /include/command.h
parent6fb61445bb28a37397fdce5cb2d3f5ffd0e1a4e4 (diff)
common: command: Rework the 'cmd is repeatable' logic
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>
Diffstat (limited to 'include/command.h')
-rw-r--r--include/command.h52
1 files changed, 48 insertions, 4 deletions
diff --git a/include/command.h b/include/command.h
index 89efcecfa9..bb93f022c5 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) \