[RFC PATCH v10 11/24] cmd: Add new cli command
Heinrich Schuchardt
xypron.glpk at gmx.de
Thu Oct 5 01:26:52 CEST 2023
On 10/4/23 18:42, Francis Laniel wrote:
> This command can be used to print the current parser with 'cli print'.
Please, provide a commit message that matches the code.
> It can also be used to set the current parser with 'cli set'.
> For the moment, only one value is valid for set: old.
If there is only one valid value, we should not provide the 'cli'
command to save code size. The patch seems to be in the wrong spot in
the series.
>
> Signed-off-by: Francis Laniel <francis.laniel at amarulasolutions.com>
> ---
> cmd/Makefile | 2 +
> cmd/cli.c | 120 ++++++++++++++++++++++++++++++++++++++++++
> common/cli.c | 3 +-
> doc/usage/cmd/cli.rst | 59 +++++++++++++++++++++
> doc/usage/index.rst | 1 +
> 5 files changed, 184 insertions(+), 1 deletion(-)
> create mode 100644 cmd/cli.c
> create mode 100644 doc/usage/cmd/cli.rst
>
> diff --git a/cmd/Makefile b/cmd/Makefile
> index 9bebf321c3..d468cc5065 100644
> --- a/cmd/Makefile
> +++ b/cmd/Makefile
> @@ -226,6 +226,8 @@ obj-$(CONFIG_CMD_AVB) += avb.o
> # Foundries.IO SCP03
> obj-$(CONFIG_CMD_SCP03) += scp03.o
>
> +obj-$(CONFIG_HUSH_PARSER) += cli.o
Don't waste binary code size. We only need the command if at least two
parsers are available.
ifeq ($(CONFIG_HUSH_OLD_PARSER)$(HUSH_2021_PARSER),yy)
obj-y += cli.o
endif
The symbol CONFIG_HUSH_PARSER should be eliminated.
> +
> obj-$(CONFIG_ARM) += arm/
> obj-$(CONFIG_RISCV) += riscv/
> obj-$(CONFIG_SANDBOX) += sandbox/
> diff --git a/cmd/cli.c b/cmd/cli.c
> new file mode 100644
> index 0000000000..7671785b83
> --- /dev/null
> +++ b/cmd/cli.c
> @@ -0,0 +1,120 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +
> +#include <common.h>
> +#include <cli.h>
> +#include <command.h>
> +#include <string.h>
> +#include <asm/global_data.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static const char *gd_flags_to_parser(void)
> +{
> + if (gd->flags & GD_FLG_HUSH_OLD_PARSER)
> + return "old";
> + return NULL;
> +}
> +
> +static int do_cli_get(struct cmd_tbl *cmdtp, int flag, int argc,
> + char *const argv[])
> +{
> + const char *current = gd_flags_to_parser();
> +
> + if (!current) {
> + printf("current cli value is not valid, this should not happen!\n");
> + return CMD_RET_FAILURE;
> + }
> +
> + printf("%s\n", current);
> +
> + return CMD_RET_SUCCESS;
> +}
> +
Please, describe this function (and all the others) in Sphinx style.
/**
* parser_string_to_gd_flags() - converts parser name to bit mask
*
* @parser: parser name
* Return: valid bit mask or -1
*/
> +static int parser_string_to_gd_flags(const char *parser)
> +{
> + if (!strcmp(parser, "old"))
> + return GD_FLG_HUSH_OLD_PARSER;
Please, do not return an invalid bit mask.
if (CONFIG_IS_ENABLED(HUSH_OLD_PARSER) && !strcmp(parser, "old"))
return GD_FLG_HUSH_OLD_PARSER;
if (CONFIG_IS_ENABLED(HUSH_2021_PARSER) && !strcmp(parser, "2021"))
return GD_FLG_HUSH_201_PARSER;
> + return -1;
> +}
> +
> +static void reset_parser_gd_flags(void)
> +{
> + gd->flags &= ~GD_FLG_HUSH_OLD_PARSER;
gd->flags &= ~(GD_FLG_HUSH_OLD_PARSER | GD_FLG_HUSH_2021_PARSER);
If there were only one parser, we wouldn't create this command.
> +}
> +
> +static int do_cli_set(struct cmd_tbl *cmdtp, int flag, int argc,
> + char *const argv[])
> +{
> + char *parser_name;
> + int parser_flag;
> +
> + if (argc < 2)
> + return CMD_RET_USAGE;
> +
> + parser_name = argv[1];
> +
> + parser_flag = parser_string_to_gd_flags(parser_name);
This function should return -1 for for any value that is not supported
be it 'foo', 'old', or '2021'. Then you can eliminate a bunch of error
checking code below.
> + if (parser_flag == -1) {
> + printf("Bad value for parser name: %s\n", parser_name);
> + return CMD_RET_USAGE;
> + }
> +
> + if (parser_flag == GD_FLG_HUSH_OLD_PARSER &&
> + !CONFIG_IS_ENABLED(HUSH_OLD_PARSER)) {
> + printf("Want to set current parser to old, but its code was not compiled!\n");
> + return CMD_RET_FAILURE;
> + }
Superfluous check, see above.
> +
> + if (parser_flag == GD_FLG_HUSH_2021_PARSER &&
> + !CONFIG_IS_ENABLED(HUSH_2021_PARSER)) {
> + printf("Want to set current parser to 2021, but its code was not compiled!\n");
> + return CMD_RET_FAILURE;
> + }
Superfluous check, see above.
> +
> + reset_parser_gd_flags();
> + gd->flags |= parser_flag;
> +
> + cli_init();
> + cli_loop();
> +
> + /* cli_loop() should never return. */
> + return CMD_RET_FAILURE;
Consuming stack space for every invocation of the 'cli set' command
cannot be intended.
Why don't we define cli_loop as __noreturn and ensure that it has no
return statement? Then gcc can generate a simple jump without consuming
stack.
cli_loop should() invoke panic() instead of returning.
> +}
> +
> +static struct cmd_tbl parser_sub[] = {
> + U_BOOT_CMD_MKENT(get, 1, 1, do_cli_get, "", ""),
> + U_BOOT_CMD_MKENT(set, 2, 1, do_cli_set, "", ""),
> +};
> +
> +static int do_cli(struct cmd_tbl *cmdtp, int flag, int argc,
> + char *const argv[])
> +{
> + struct cmd_tbl *cp;
> +
> + if (argc < 2)
> + return CMD_RET_USAGE;
> +
> + /* drop initial "parser" arg */
> + argc--;
> + argv++;
> +
> + cp = find_cmd_tbl(argv[0], parser_sub, ARRAY_SIZE(parser_sub));
> + if (cp)
> + return cp->cmd(cmdtp, flag, argc, argv);
> +
> + return CMD_RET_USAGE;
> +}
> +
> +#if CONFIG_IS_ENABLED(SYS_LONGHELP)
> +static char cli_help_text[] =
> + "get - print current cli\n"
"get - display parser\n"
> + "set - set the current cli, possible value is: old"
'cli ' is only printed automatically in the first line.
"cli set - set parser to one of:\n"
#ifdef CONFIG_HUSH_OLD_PARSER
"\t- old\n"
#endif
#ifdef CONFIG_HUSH_2021_PARSER
"\t- 2021\n"
#endif
Why would we need the 'cli set' command at all if there is only one
parser enabled?
Should we better disable the sub-command in that case?
> + ;
> +#endif
> +
> +U_BOOT_CMD(cli, 3, 1, do_cli,
> + "cli",
> +#if CONFIG_IS_ENABLED(SYS_LONGHELP)
> + cli_help_text
> +#endif
This is wrong. You must pass an empty string at least. Please, follow
the style of the other commands and place the #if in the long text.
> +);
> diff --git a/common/cli.c b/common/cli.c
> index e5fe1060d0..d419671e8c 100644
> --- a/common/cli.c
> +++ b/common/cli.c
> @@ -268,7 +268,8 @@ void cli_loop(void)
> void cli_init(void)
> {
> #ifdef CONFIG_HUSH_PARSER
This Kconfig symbol is superfluous when you already have
CONFIG_HUSH_OLD_PARSER and CONFIG_HUSH_2021_PARSER.
Please, remove CONFIG_HUSH_PARSER from Kconfig.
> - if (!(gd->flags & GD_FLG_HUSH_OLD_PARSER))
> + if (!(gd->flags & GD_FLG_HUSH_OLD_PARSER)
The first part of the if statement is superfluous.
There is no harm in setting the bit again.
> + && CONFIG_IS_ENABLED(HUSH_OLD_PARSER))
> gd->flags |= GD_FLG_HUSH_OLD_PARSER;
> u_boot_hush_start();
> #endif
> diff --git a/doc/usage/cmd/cli.rst b/doc/usage/cmd/cli.rst
> new file mode 100644
> index 0000000000..89ece3203d
> --- /dev/null
> +++ b/doc/usage/cmd/cli.rst
> @@ -0,0 +1,59 @@
> +.. SPDX-License-Identifier: GPL-2.0+
> +
> +cli command
> +===========
> +
> +Synopis
> +-------
> +
> +::
> +
> + cli get
> + cli set cli_flavor
We should show the available values here:
cli set [old|2021]
> +
> +Description
> +-----------
> +
> +The cli command permits getting and changing the current parser at runtime.
The cli command permits displaying and setting the command line parsers.
Currently two parsers are implemented:
old
The 'old' parser is what U-Boot provided until v2023.10.
2021
The '2021' parser provides ....
Please, describe here why the '2021' parser might be preferable. Please,
describe which parser is the default.
> +
> +cli get
> +~~~~~~~
> +
> +It shows the current value of the parser used by the CLI.
The command display the parser used by the command line interface ('old'
or '2021').
> +
> +cli set
> +~~~~~~~
> +
> +It permits setting the value of the parser used by the CLI.
The command sets the parser used by the command line interface.
> +
> +Possible values are old and 2021.
> +Note that, to use a specific parser its code should have been compiled, that
> +is to say you need to enable the corresponding CONFIG_HUSH*.
> +Otherwise, an error message is printed.
Should we use .. note:: here to highlight the information?
> +
> +Examples
> +--------
> +
> +Get the current parser::
> +
> + => cli get
> + old
> +
> +Change the current parser::
> +
> + => cli set old
=> cli set 2021
Who would want to set the current value?
> +
> +Trying to set the current parser to an unknown value::
> +
> + => cli set foo
> + Bad value for parser name: foo
> + cli - cli
> +
> + Usage:
> + cli get - print current cli
> + set - set the current cli, possible value is: old
This looks like a bug. I would have expected at least two possible
values. Otherwise we would not need a 'cli' command.
Please, add a 'Configuration' section describing the relevant
configuration variables.
Best regards
Heinrich
> +
> +Return value
> +------------
> +
> +The return value $? indicates whether the command succeeded.
> diff --git a/doc/usage/index.rst b/doc/usage/index.rst
> index fa702920fa..90a38c5713 100644
> --- a/doc/usage/index.rst
> +++ b/doc/usage/index.rst
> @@ -42,6 +42,7 @@ Shell commands
> cmd/cat
> cmd/cbsysinfo
> cmd/cedit
> + cmd/cli
> cmd/cls
> cmd/cmp
> cmd/coninfo
More information about the U-Boot
mailing list