I did some further investigating, and found out that our current
getopt implementation is not SUSv2-compliant.
To wit:
If an executable calls getopt with an option string containing '-',
and is subsequently called with
program -
NetBSD's current getopt implementation returns '-'. According to SUSv2
(XSH5 in particular), getopt should stop parsing and return -1 in the
following cases:
o argv[optind] is NULL (mentioned only for completeness)
o *argv[optind] is not '-' (the character)
o argv[optind] is the string "-"
o argv[optind] is the string "--"
su(1) for example uses the current (wrong) behaviour in a
standards-defying way by just putting '-' in the option string. This
must be handled manually instead.
So, to be more standards compliant, we have to break binary
compatibility (that is, do the __RENAME dance).
From my point of view, there aren't any reasons that "-" should still
be allowed in option strings: You could only validly return '-' as an
option if you find it inside a string of concattenated short options
like "program -abcd-".
We could still allow '-' as the first character in an option string to
be compatible to GNU getopt, which interprets that to return
non-option arguments as option arguments to the option '\01', that is
program -a file -b
returns 'a', '\01' with optarg "file", and 'b'.
Since GNU libc's getopt_long allows this use of '-' as the first char
in the option string, getopt_long tries to be reasonably compatible to
GNU getopt_long (after all, there's no standard for getopt_long), and
I'd like to use share the internal code of getopt and getopt_long, I
think it would be a good idea to introduce the same behavior into
getopt.
There's one other special character in GNU getopt's handling of the
option string: '+' as first character. That specifies that the
arguments of the program should _not_ be reordered, i.e.
program -a file -b
will not be handled as
program -a -b file
cf. my last mails on the subject. Since this is and will be default
behaviour in NetBSD's getopt, we should probably just ignore it (that
is, not recognize it as option '+'). It's not really a problem,
though: if we don't special case it, such programs will just accept
'-+' and then not know what to do with it -- but it's the user's fault
in the first place, since he should know better than to call them with
'-+' ;-)
I've also thought about consistency a lot, and my opinion now is that
getopt_long shouldn't reorder by default, either (in contrast to GNU's
getopt and getopt_long do) because that's the most consistent way with
NetBSD getopt.
If we really mean it, we should also remove all uses of GNU
getopt{,1}.{c,h} files in src/gnu/ -- otherwise there will be some
special programs that _do_ reorder their arguments.
Thanks for reading so far.
Bye,
Thomas
P.S.: Please CC.
--
Thomas Klausner - w...@danbala.tuwien.ac.at
A man may be very industrious, and yet not spend his time well. There is no
more fatal blunderer than he who consumes the greater part of life getting
his living. -- Henry David Thoreau
--
Thomas Klausner - w...@danbala.tuwien.ac.at
A man may be very industrious, and yet not spend his time well. There is no
more fatal blunderer than he who consumes the greater part of life getting
his living. -- Henry David Thoreau
: If we really mean it, we should also remove all uses of GNU
: getopt{,1}.{c,h} files in src/gnu/ -- otherwise there will be some
: special programs that _do_ reorder their arguments.
If programs want to replace getopt, they should be allowed to do so, as that
is how they will function out-of-the-box. We should not supplant those
versions unless we're identical to them (and we obviously won't be).
I'll have more thoughts on the rest of this later.
--
-- Todd Vierling <t...@wasabisystems.com> * http://www.wasabisystems.com/
-- Speed, stability, security, and support. Wasabi NetBSD: Run with it.
imo, the fact that gnu grep does that with its command line arguments
is *totally* evil.
--
|-----< "CODE WARRIOR" >-----|
codew...@daemon.org * "ah! i see you have the internet
twof...@graffiti.com (Andrew Brown) that goes *ping*!"
and...@crossbar.com * "information is power -- share the wealth."
> : If we really mean it, we should also remove all uses of GNU
> : getopt{,1}.{c,h} files in src/gnu/ -- otherwise there will be some
> : special programs that _do_ reorder their arguments.
>
> If programs want to replace getopt, they should be allowed to do so, as that
> is how they will function out-of-the-box. We should not supplant those
> versions unless we're identical to them (and we obviously won't be).
This is a question of consistency. Most of these programs just don't
test if there's a getopt in the system they are installing on. The
issue here is, if we want to be able to do
grep somestring * -r
and have this interpreted as
grep -r somestring *
because it is GNU grep, and that is how GNU grep behaves, or if we
want to have a consistent behaviour among _all_ programs on NetBSD,
independent of whether they are GNU or not.
I'm not sure yet what I think of that, FWIW.
Bye,
Thomas
No, I definitely would not like grep to behave like that.
That might be how GNU-grep works - but its not how grep should.
Its bogus.
As to one of your earlier comments about "-" in optstr, its actually
quite handy - after a simple bug fix to getopt(3) so that --foo is
not interpreted as --. The one can have -: in optstr and get a simple hook
to pickup --long_options of course one could argue that if you want that
you should use gnu getopt, but the munging described above suggests that
gnu getopt is more trouble that its worth.
--sjg
Mutt made me believe that Simon J. Gerraty wrote:
> As to one of your earlier comments about "-" in optstr, its actually
> quite handy - after a simple bug fix to getopt(3) so that --foo is
> not interpreted as --. The one can have -: in optstr and get a simple hook
> to pickup --long_options of course one could argue that if you want that
> you should use gnu getopt, but the munging described above suggests that
> gnu getopt is more trouble that its worth.
I'm not completely sure I understand this paragraph, but here goes:
If you want to parse long-options, just use getopt_long, which has
been in libc for some months now.
Bye,
Thomas