On Thu, 29 Nov 2018 00:39:19 +0100
Boris Brezillon <[email protected]> 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 <[email protected]>
> ---
> 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 */

_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to