home *** CD-ROM | disk | FTP | other *** search
- /* getopt.c, getopt.h: (yet another) improved getopt clone
- Daniel J. Bernstein, brnstnd@nyu.edu.
- No dependencies.
- Requires stdio.
- 10/20/91: Removed -DGETOPT_SHUT_UP. [sigh]
- 8/26/91: Added -DGETOPT_SHUT_UP.
- 8/25/91: Changed getopt to not skip blank arguments.
- 7/6/91: Baseline. getopt 1.0, public domain.
- No known patent problems.
-
- This is a clone of the usual getopt() functions. It includes opterr so
- that you can turn off error handling, optpos so that you can find out
- exactly where the processing is up to (instead of just which argument),
- optproblem so that you can accurately diagnose errors yourself, and
- optprogname so that you can set the program name for getopt-generated
- errors. getopt() takes much more care to ensure that all the variables
- still make sense upon errors and EOF. (optproblem is a character. If
- argv[optind] is 0, the problem is a missing argument; otherwise it's an
- illegal option character.) Unless you define GETOPTORIGDEF, the header
- file redefines all names so that you don't have to worry about conflicts
- with libc. Finally, the code is public-domain, so you should feel free
- to use these extra features in your own programs and just attach a copy
- of this.
-
- Note that optind and optpos can be read (or set) any time, but the
- official getopt interface only defines optind when getopt() returns EOF.
- We define optproblem only when getopt() returns '?', optarg all the
- time, and optprogram only after getopt() has been called at least once.
-
- */
-
- #include <stdio.h> /* for EOF and stderr---talk about immodularity! */
- #include "getopt.h"
-
- int optind = 1;
- int optpos = 0;
- int opterr = 1;
- char *optarg = 0;
- int optproblem = 0;
- char *optprogname = 0;
- int opteof = EOF;
-
- int getopt(argc,argv,opts)
- int argc;
- char **argv;
- char *opts;
- {
- int c;
- char *s;
-
- optarg = 0;
- if (!optprogname)
- {
- optprogname = *argv;
- if (!optprogname) /* oh boy */
- optprogname = ""; /*XXX*/
- for (s = optprogname;*s;++s)
- if (*s == '/')
- optprogname = s + 1;
- }
- if (!argv || (optind >= argc) || !argv[optind])
- return opteof;
- while (optpos && !argv[optind][optpos])
- {
- /* we simply skip blank arguments... not any more */
- ++optind;
- optpos = 0;
- if ((optind >= argc) || !argv[optind])
- return opteof;
- }
- if (!optpos)
- {
- if (argv[optind][0] != '-')
- return opteof;
- ++optpos;
- c = argv[optind][1];
- if ((c == '-') || (c == 0))
- {
- /* XXX: this behavior of "-" is stupid */
- if (c)
- ++optind;
- optpos = 0;
- return opteof;
- }
- /* otherwise c is reassigned below */
- }
- c = argv[optind][optpos];
- ++optpos;
- s = opts;
- while (*s)
- {
- if (c == *s)
- {
- if (s[1] == ':')
- {
- optarg = argv[optind] + optpos;
- ++optind;
- optpos = 0;
- if (!*optarg)
- {
- optarg = argv[optind];
- if ((optind >= argc) || !optarg) /* argument past end */
- {
- optproblem = c;
- if (opterr)
- fprintf(stderr,"%s: option requires an argument -- %c\n"
- ,optprogname,c);
- return '?';
- }
- ++optind;
- }
- }
- return c;
- }
- ++s;
- if (*s == ':')
- ++s;
- }
- optproblem = c;
- if (opterr)
- fprintf(stderr,"%s: illegal option -- %c\n",optprogname,c);
- return '?';
- }
-