bug-gnulib
[Top][All Lists]
Advanced

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

[Bug-gnulib] Re: getopt trouble on uClibc systems


From: Simon Josefsson
Subject: [Bug-gnulib] Re: getopt trouble on uClibc systems
Date: Fri, 02 Jul 2004 09:46:16 +0200
User-agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3.50 (gnu/linux)

Paul Eggert <address@hidden> writes:

> Simon Josefsson <address@hidden> writes:
>
>> * The variables are wrapped around HAVE_OPTFOO.
>
> Come to think of it, shouldn't you replace the variables instead?  It
> seems to me that the logic that applies to getopt (some nonstandard
> and/or broken systems don't let you define your own getopt function)
> will also apply (in similar form) to those variables.

I'm not convinced -- I believe there is a difference between getopt
and say opterr, so different logic apply.  For opterr, we can easily
test whether the system provided opterr is good enough.  If this
program compile, link, run and return 0:

#include <unistd.h>
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#endif
extern int opterr;
int main (void) { return opterr == 1 ? 0 : 1; }

Then the system provided opterr is good enough, and there is no need
to replace it.

If the program doesn't work, for any reason, we should provide a
replacement, which may or may not have to be renamed depending on
whether the system provide a incompatible opterr.  Currently we don't
know of any systems that has incompatible opterr, so for now we simply
assume that if opterr exists (via AC_CHECK_FUNCS), it is of proper
type, and working (i.e. initially has value 1).

But for getopt, we don't have a simple test case to see if the system
provided getopt is good enough.  Instead we always replace it if, say,
getopt_long isn't available, because that suggest the system doesn't
provide a GNU getopt.

I understand the argument that since we don't DTRT for getopt (i.e.,
the right thing being test for a specific behaviour, rather than
testing lack of getopt_long), we'd might as well do the same for
opterr etc, for consistency.  But if it is simple to DTRT for opterr
etc, I think it is better to do so.

However, and perhaps surprisingly, if it turns out that AC_CHECK_FUNCS
is not sufficient to test whether opterr etc is working -- that is,
instead getopt.m4 would have to compile the above long program -- then
I believe TRT has become too ugly to support, and we should redefine
the variables directly, just like for getopt.  It results in needless
redefinition on some systems, but simpler logic.

> For example, if you use the system optind, many linkers will pull in
> the entire system getopt object module, which is a waste and may
> cause a problem if they define (say) getopt_long but not
> getopt_long_only.

If this situation exists, using my logic, the solution to that problem
would be to redefine getopt_long to rpl_getopt_long -- similar to
getopt.

> Another thing.  Once you make the above change, you can use a more
> reliable way to check for the system getopt.  For example, you can
> write a little test program that checks that
> _GNU_GETOPT_INTERFACE_VERSION is 2 and refuses to compile otherwise.

On uClibc _GNU_GETOPT_INTERFACE_VERSION is 2, but libc.a does not
contain all symbols for that interface.

> If you want to get fancier, the test program could instead use all
> the desired features (e.g., getopt_long) in such a way that there
> will be a compilation or link error if the features don't work.

And then replace all symbols?

Alternatively, you could also have one long test case that tests
desired behaviour for each of the interfaces, getopt, getopt_long,
opterr, optind etc.  And only provide a replacement where the system
implementation isn't sufficient.

I guess what I have been trying to say is that I don't view getopt*,
opt* as one united interface.  Instead, I view each of getopt,
getopt_long, opterr etc as a separate interface, and should thus be
tested for and replaced individually.

As a final word, I realize that my approach result in more CPP
#ifdef's.  I dislike those, and that alone could win me over to your
approach.  To clean things up, I would have put opterr, optind etc in
one file per variable, and then use an automake conditional to decide
whether to compile each file.  But I doubt this is an appropriate
solution here.  (Btw, I find that automake conditionals are quite
stable and portable today, and no longer as fragile as they used to
be.  I use automake conditionals in all my projects.  They might be
useful to use in gnulib in some situations.)

Thanks,
Simon




reply via email to

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