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

Reply via email to