bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: non-POSIX getopt() (Re: Updating FreeBSD port)


From: Eric Blake-1
Subject: Re: non-POSIX getopt() (Re: Updating FreeBSD port)
Date: Thu, 21 Sep 2006 08:55:47 -0700 (PDT)

> = > Finally, does m4 actually use/document the short-options usage, that's
> = > affected by the POSIX vs. GNU differences in getopt()?
> = 
> = Yes, the info documentation for m4's -d discusses the ramifications of
> its
> = argument being optional (and if that text is not clear enough for you,
> = please report it as a bug so we can improve it).
> 
> The bug, IMHO, is in the use of getopt, that departs from POSIX' 
> specifications for the function, thus requiring to compile your own
> version 
> of it, which is a patently bad style.

No.  POSIX does not REQUIRE apps to use getopt() (and m4 does not use
getopt; it uses getopt_long).  It only requires that apps that comply with
POSIX guideline, and provides getopt() as a means to compliance.

On the other hand, GNU Coding Standards require that apps support
long options.  So gnulib provides two modules, getopt and argp, that
make the job of complying with both POSIX and GNU, easier.  M4 chose
to use getopt_long, which is part of the getopt module.  M4 did not
write its own option parser, it is reusing a common one from gnulib;
agreeing entirely with your sentiment that rewriting common code
is bad style.  getopt_long is a GNU invention, so GNU programs expect
it to have the semantics that GNU assigns to it.

The problem is that BSD tried implementing getopt_long to match
GNU, but did it incorrectly (its implementation may make sense for
BSD, but does not match GNU's implementation, yet).  As a result,
the gnulib module currently rejects the BSD implementation as
insufficient, rather than forcing programs like m4 that use the
gnulib module to be aware of the gotchas when using an insufficient
getopt_long emulation.

POSIX does not define what happens with "d::" in an optstring, but
leaves it to the implementation.  In other words, POSIX does not
require getopt() to handle optional arguments, and an application,
like m4, that uses "d::" is inherently extending POSIX.

> "Embrace and Extend" :-/

GNU did exactly that, by inventing getopt_long, and by supporting
"d::" notation for optional arguments even in getopt().

> I wonder, how GNU's getopt implementation, where flags' arguments can be 
> optional, deals with the cases of such an option followed by something,
> that 
> begins with a dash itself:
> 
>       m4 -d -X
> 
> Is "-X" an argument for -d, or a separate flag?

I already told you.  GNU semantics for optional arguments is that
the optional argument MUST appear in the SAME command
line argument (whether spelled short or long), otherwise there
was no argument provided.

"m4 -d -e" is two options, and "m4 -d a" is an option and a filename, in
both cases with the debug mode being set to "aeq" (the documented
default when the optional argument is not present).
"m4 -d-e" is one option with an argument "-e", which turns the "e"
debugmode flag off (at least, it will be in m4 2.0.  In m4 1.4.x, it
is a syntax error).
"m4 -da" is one option with an argument of "a", which sets the debug
mode to "a".
"m4 --debug a" is an option and a filename, with the debug mode
being set to "aeq".
"m4 --debug=a" is a single option, with the debug mode being set to "a".
"m4 --debug= a" is an option and a filename, with the debug mode being
set to "aeq".

-- 
Eric Blake


-- 
View this message in context: 
http://www.nabble.com/Re%3A-Updating-FreeBSD-port-tf2305349.html#a6431117
Sent from the Gnulib mailing list archive at Nabble.com.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]