[Toybox] [PATCH] Minor formatting and cleanup in getopt.c

Oliver Webb aquahobbyist at proton.me
Fri Mar 1 15:37:18 PST 2024


On Thursday, February 29th, 2024 at 19:03, Rob Landley <rob at landley.net> wrote:
> On 2/28/24 18:23, Oliver Webb via Toybox wrote:
> 
> > I've been looking at some of the other pending commands, And found a getopt implementation from 2017 by AOSP.
> > Looking at the source code, it doesn't seem unclean, nor overly large (about 100 lines).
> > It does use getopt_long_only, a GNU extension of glibc, but musl has that so it will work
> > on both glibc and musl. It is GNU compatible too, all test cases pass (even for TEST_HOST).
> 
> 
> It's mostly that:
> 
> A) I'm not a shell getopt user and haven't put in the focus to come up to speed
> on it yet,
> 
> B) the shell has a "getopts" (plural) builtin that I need to write, but which
> this doesn't share code with. And LOTS of stuff confuses the two. (There's a
> comment in this source about "BSD getopts", when this is "getopt".) Of COURSE
> the semantics of the two are subtly different.
> 
> C) I'd really wanted to get it to use lib/args.c instead of having two getopt()
> implementations in toybox (one from lib/ and one pulled in from libc).
> 
> Sigh. That said, I've been sitting on this for a long time without doing
> anything about it, and the perfect is the enemy of the good.
> 
> The libc version isn't bad, it just bloats the static binary pulling in two
> implementations of approximately the same code. I don't know if switching it
> over to lib/args.c is even possible (the semantics are close, but I'd need one
> to be a strict subset of the other),

I don't know how closely the lib/args.c code is tied into the infrastructure of toybox,
or if you can use it like how getopt should work by calling it directly with a struct pointer
(From looking at lib/args.c, it seems like it? Although there is the GLOBALS stuff which can't
easily be separated from the infrastructure)

The difference between lib/args.c option strings and getopt() option strings is like the difference
between ERE's and PCRE's, yes they share a common base, but the differences start to become very
apparent once you move from that base. Evaluating this it seems like we could either:

1) Change lib/args.c to be a superset of getopt(3), and pry it from the GLOBALS so we can use it on it's own.
Which is a large amount of effort and will only be used by 2 commands.

2) Have a -t option or something similar to it to parse toybox option strings, which still requires
prying lib/args.c off the infrastructure, and likely won't be used by anything. And we still will have
to pull in getopt() from libc.

3) Continue using getopt()

> The existence of the -T option is a damning indictment of the entire gnu
> project. As if we needed more of those. The -s option isn't doing them any
> favors either: PICK ONE. But then again, this is gnu we're talking about:

getopt -s should probably be like cpio -H, ignored and set to the one thing everyone uses,
and kept in the option string so that we don't error and autoconf doesn't whine.
ideally without using eval which is a horrible nightmare for security.
the 4 options GNU lets you pick from are sh (Bourne Shell?) bash csh and tcsh.
Bash is a superset of sh, and {t,}csh isn't used by anything these days from my knowledge.

> Rob

-   Oliver Webb <aquahobbyist at proton.me>


More information about the Toybox mailing list