[vox-tech] writing free getopt, ran into a dilemma...

vox-tech@lists.lugod.org vox-tech@lists.lugod.org
Sat, 30 Mar 2002 04:38:46 -0500


On Thu, Mar 28, 2002 at 10:12:29AM -0800, Micah Cowan wrote:
> On Thu, 2002-03-28 at 00:35, Mark K. Kim wrote:
> > I think I now understand why GNU shuffles argv[].  But I don't need this
> > to be fully compatible with BSD's getopt; I just need it to behave in
> > reasonable manner.  I'd like to hear some ideas and what you think the
> > behavior should be and how it's better than others.
>
> Well, POSIX says that options should always be supplied before
> arguments, so that's why POSIX-conforming implementations don't need to
> permute the order in argv.  Intermixing options with arguments is a GNU
> extension,

  First off Micah is absolutely correct about POSIX and options.  Strict
POSIX stuff only accepts command options as the first bunch of options to 
a command the first non-option found stops parsing of options.  

  This is why if you type 'ls foo* -ltr' on a Solaris version of ls
you will get a standard ls format and then an error about 
'-ltr: file not found' but if you type the same thing on a Linux
system you get a long listing sorted reversely by time (youngest files
last).


> Intermixing options with arguments is a GNU
> extension, and GNU pulls some mildly dirty tricks to get it (such as
> permuting argv, despite the fact that it's elements are declared const).

Micah,

  I am slightly confused, "it's elements are declared const", I've been
having a very hard time finding some site which will state something like
POSIX/ANSI C/ISO C require the following prototypes...


Here is what I believe the valid declarations to be (these from ANSI C):
  int main(void);  
  int main(int argc, const char **argv);

POSIX adds the following one additional main:
  int main(int argc, const char **argv, const char **envp);

POSIX declares:
  int getopt(int argc, char * const *argv, const char *optstring);

However the GNU documentation declares:
  int getopt(int argc, char **argv, const char *optstring);

  /* externs are optional, and "*argv[]" is interchangeable with "**argv" */


- If you think the declaration of main or getopt don't match any of the
  above could you give your version and some online reference for that
  version?


  If the declaration of main above is correct there is nothing to 
prevent someone reordering the elements in the main function's argv... 
which is what is passed into getopt by _almost_ every caller.
  It would seem the GNU people could just remove the const from their 
header so if POSIX actually _requires_ the const then people would be 
able to rightly complain it doesn't "obey" the POSIX standard out of 
the box... but the GNU version gives users at least two ways to get
POSIX compatible getopt at run time (POSIXLY_CORRECT and '+' prefix),
and in theory (not current practice) the coder could request POSIX 
compatibilty at compile time via '#define POSIX_SOURCE'.


  The one valid bug I see is that GNU getopt.h and getopt.c both use 
'char * const *argv' and that conflicts with the documentation 
of 'char **argv'.