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

Micah Cowan vox-tech@lists.lugod.org
28 Mar 2002 10:12:29 -0800


On Thu, 2002-03-28 at 00:35, Mark K. Kim wrote:
> Keywords: getopt, license issues, GPL, BSD, optind

> I implemented everything.  optarg, opterr, and optopt work exactly
> identical to GNU's getopt.  However, optind is a little different because
> my library doesn't reshuffle argv[] like GNU's getopt.  That's okay with
> me, but things get hairy if "optstr" doesn't have '-' as its first
> character -- then the programmer is expected to search the remaining
> argv[] starting with "optind"... but due to GNU getopt's flexible nature,
> there could be unhandled entries in argv[] not only at the end but in the
> middle, too (creating "holes" of unhandled optarg in argv[]).  So where
> should "optind" point to by the time "getopt"  finishes processing all the
> options and there are "holes" of unhandled optarg only plain strings
> remain?  (That's a little long and confusing; I hope you understand all
> that :)
> 
> 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, and GNU pulls some mildly dirty tricks to get it (such as
permuting argv, despite the fact that it's elements are declared const).

Permuting is probably the easiest way to go; but another alternative
would be to create another function, increment_optind(), instead of
doing ++optind.  This function could then automatically skip options.

Oh, but you mentioned it doesn't currently even handle the middle
options (which is what I thought the point was for your getopt()?).  In
that case, if you hate permuting argv, you could copy it into a
seperate, temporary string, and permute that instead.  You'd still need
increment_optind()---or you could break getopt()'s parameter list by
passing back the allocated string (make sure it gets freed
somewhere...).

If you email me the code, I'd be happy to comment on it (comp.lang.c is
a hobby of mine, though one I haven't gotten around to lately).  I won't
get to it this weekend, though, since I'll be out of town (and away from
email).

Micah