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

vox-tech@lists.lugod.org vox-tech@lists.lugod.org
Sat, 30 Mar 2002 07:45:43 -0500


  I often had find alot of interesting (to me) material while digging 
around on things like this.  I would be fabulous if someone could
point me at a online source for the ANSI C or ISO C standards.  It would
be cool to be able to site a section for or against various theories.
  (Well the technically official standard is something you have to pay 
hundreds of dollars for, which is why it's not available everywhere
and is part of the reason so many opinions about what it actually
says exist... but some _through_ coverage would be nice).


On Thu, Mar 28, 2002 at 09:13:19AM -0800, Mark K. Kim wrote:
> The one I tried to link statically on Windows one time said it was GPL,
> but according to Micah it's apparently LGPL with misdocumentation. :P

  readline is GPL, getopt is LGPL... maybe some maintainer got confused? 


> The reason I'm writing my own getopt is because I want static linkage.

  ...and don't want to give your users the ability to revise getopt.  :)

> Anyway, some options I'm thinking about:
>
>    1. Get rid of optind altogether.
>    2. Shuffle argv[] like LGPL getopt.
>    3. Set optind to the beginning of the last set of non-option arguments.
>    4. Set optind to the beginning of the first non-option argument.
>
> I really don't want to shuffle argv[] (option #2)

  I personally prefer the reordering of argv, it makes the command line
more flexible and makes working with the non-options a breeze for the
program after the options are moved out of the way (the program just 
loops from optind to argc).

  If you do not intend to permute the array, then I recommend you abort
processing later options like POSIX 'requires' (explained in quote below).
There is also the middle option mentioned below which you might not
have implemented/thought of (this allows the application to be notified
about each non-option as it is encountered).

  Don't drop optind because it is required to tell which argv stopped
processing.  By incrementing optind a true POSIX application can 
force getopt to skip over arguments it doesn't know about.

  Realize both sets of people POSIX and GNU have good ideas, GNU is
just more flexible because they provide the true standard then on
top of that implement something that is more generally useful but
don't prevent either the application author or the application 
user from getting the true standard.  (The user doesn't even need 
to touch any code in already compiled application!  It's really 
amazing they went through the thought -> effort involved.) 

http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_514.html#SEC524
#         getopt has three ways to deal with options that follow
#         non-options argv elements.
[...]
#         + The default is to permute the contents of argv while scanning
#           it so that eventually all the non-options are at the end.
#           This allows options to be given in any order, even with
#           programs that were not written to expect this.
#         + If the options argument string begins with a hyphen (`-'),
#           this is treated specially. It permits arguments that are not
#           options to be returned as if they were associated with option
#           character `\1'.
#         + POSIX demands the following behavior: The first non-option
#           stops option processing. This mode is selected by either
#           setting the environment variable POSIXLY_CORRECT or beginning
#           the options argument string with a plus sign (`+').


> I can see how a non-shuffling getopt could be useful on systems 
> that won't let you shuffle argv[].

  Okay, this stems from the end of my post to Micah.  As far as I
can tell the only reason getopt shouldn't reorder the arguments
is because it's declaration says that the array will not be modified,
and getopt was spec'ed by the POSIX people as const because they
don't reorder.

  Anything that seems official that I have been able to find says
main has 'const char **argv', getopt has 'char * const *argv'

const char **argv --
  is an array of pointers to const strings.  the strings themselves may
  not be modified, however one can change the pointers in the array to
  point at different strings and can reorder the strings.

char * const *argv --
  is a const array of pointers to strings.  the strings themselves may
  be modified, however the array itself may not be changed.


  So if I didn't mess something up there, ANSI C, doesn't place a 
restriction on changing main's argv... getopt's prototype says it
will not but, for what it's worth, casting a const a non-const then 
changing the data there may not actually be a violation of the 
standard... see Dennis Ritchie's full post for the whole details but 
the kernel of that idea is below.

http://www.lysator.liu.se/c/dmr-on-noalias.html
#    5. Add a constraint (or discussion or example) to assignment that
#       makes clear the illegality of assigning to an object whose actual
#       type is const-qualified, no matter what access path is used.
#       There is a manifest constraint that is easy to check (left side is
#       not const-qualified), but also a non-checkable constraint (left
#       side is not secretly const-qualified).  The effect should be that
#       converting between pointers to const-qualified and plain objects
#       is legal and well-defined; avoiding assignment through pointers
#       that derive ultimately from `const' objects is the programmer's
#       responsibility.

 
On Thu, Mar 28, 2002 at 05:19:46PM -0800, Mark K. Kim wrote:
> I'm not sure what you mean by "middle options"...  It currently behaves
> exactly like GNU getopt as far as required arguments (as in "o:") and
> non-option arguments (as in "-") except it doesn't permute[1] argv and
> optind doesn't work like GNU getopt.  I don't use optional arguments
> (which I believe is a GNU extension) but I'll implement it if I knew how
> to use it :)  And... I don't think there's anything else, is there???

  Doing everything GNU getopt does is impressive, if you are concerned
you missed something I would recommend glibc documentation (which available 
at the URL below)... it contains slightly different information from
the man page.

  http://www.gnu.org/manual/glibc-2.2.3/html_node/libc_514.html#SEC524
(you may need to move around a few nodes above and below for the full
story)

    TTFN,
      Mike