Hi Sean, On Fri, 15 May 2026 at 15:58, Sean Anderson <[email protected]> wrote: > > On 5/15/26 16:32, Simon Glass wrote: > > The 'echo' command's option parser is a single strcmp against argv[1] > > that decides whether to suppress the trailing newline. Convert it to > > getopt() so echo follows the same shape as the other commands in this > > series and exercises the '+' prefix that POSIX-style 'stop at first > > non-option' callers need. > > > > The optstring uses the '+' prefix to preserve bash echo behaviour: -n is > > honoured only as the very first argument, so 'echo hello -n' still > > prints 'hello -n\n' verbatim. > > > > Two minor differences from the bash builtin remain, both of which > > the user can work around with quoting or --: > > > > * -x (an unknown short option) returns CMD_RET_USAGE rather than > > printing literally; use 'echo -- -x' to print it. > > * -nfoo (joined form) parses -n and then errors on the trailing > > characters. > > Why? This introduces incompatibility with echo as it exists today as > well as unix-style echo. We can have an (almost) completely-compatible > echo with > > getopt_init_state(&gs, argc, argv); > while (getopt_silent(&gs, "+n") == 'n') > newline = false; > > for (i = gs.index; i < argc; ++i) { > <snip> > > The only difference is that something like "echo -na" will result in > "-na" and not "-na\n". IMO echo is not a good candidate for getopt > due to its unusual argument handling. Even coreutils echo does not > use getopt. So I think we should really leave echo as-is.
Yes, I am including this just so people can see a case where there is only a single arg and we need ordering. It is the worst case I can think of for getopt(). I have not yet really found a best case. There are at least two reasons not to apply this patch: echo is special in how it handles its args (as you say) and it would impact nearly every board. > > > Add three test cases that pin down the new behaviour: trailing -n stays > > literal, -- ends option parsing, and -- is consumed even after a > > recognised flag. The positional loop uses getopt_pop() as an iterator. > > CMD_ECHO selects GETOPT so the parser is linked in on boards that don't > > already enable it. > > > > Signed-off-by: Simon Glass <[email protected]> > > --- > > > > cmd/Kconfig | 1 + > > cmd/echo.c | 23 ++++++++++++++--------- > > test/cmd/test_echo.c | 10 ++++++++++ > > 3 files changed, 25 insertions(+), 9 deletions(-) > > Regards, Simon

