1*f445c897SJohn Marino /* $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $ */
2*f445c897SJohn Marino
301e196c8SJohn Marino /*
401e196c8SJohn Marino * Copyright (c) 1987, 1993, 1994
501e196c8SJohn Marino * The Regents of the University of California. All rights reserved.
601e196c8SJohn Marino *
701e196c8SJohn Marino * Redistribution and use in source and binary forms, with or without
801e196c8SJohn Marino * modification, are permitted provided that the following conditions
901e196c8SJohn Marino * are met:
1001e196c8SJohn Marino * 1. Redistributions of source code must retain the above copyright
1101e196c8SJohn Marino * notice, this list of conditions and the following disclaimer.
1201e196c8SJohn Marino * 2. Redistributions in binary form must reproduce the above copyright
1301e196c8SJohn Marino * notice, this list of conditions and the following disclaimer in the
1401e196c8SJohn Marino * documentation and/or other materials provided with the distribution.
15*f445c897SJohn Marino * 3. Neither the name of the University nor the names of its contributors
1601e196c8SJohn Marino * may be used to endorse or promote products derived from this software
1701e196c8SJohn Marino * without specific prior written permission.
1801e196c8SJohn Marino *
1901e196c8SJohn Marino * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2001e196c8SJohn Marino * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2101e196c8SJohn Marino * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2201e196c8SJohn Marino * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2301e196c8SJohn Marino * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2401e196c8SJohn Marino * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2501e196c8SJohn Marino * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2601e196c8SJohn Marino * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2701e196c8SJohn Marino * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2801e196c8SJohn Marino * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2901e196c8SJohn Marino * SUCH DAMAGE.
3001e196c8SJohn Marino */
3101e196c8SJohn Marino
3201e196c8SJohn Marino #ifdef HAVE_CONFIG_H
3301e196c8SJohn Marino # include "config.h"
3401e196c8SJohn Marino #endif
3501e196c8SJohn Marino #if !defined(HAVE_GETOPT) || defined(WANT_GETOPT_LONG) || defined(BROKEN_GETOPT)
36*f445c897SJohn Marino #include <sys/cdefs.h>
3701e196c8SJohn Marino
3801e196c8SJohn Marino #include <stdio.h>
3901e196c8SJohn Marino #include <stdlib.h>
4001e196c8SJohn Marino #include <string.h>
4101e196c8SJohn Marino
4201e196c8SJohn Marino
4301e196c8SJohn Marino #define BADCH (int)'?'
4401e196c8SJohn Marino #define BADARG (int)':'
4501e196c8SJohn Marino #define EMSG ""
4601e196c8SJohn Marino
4701e196c8SJohn Marino int opterr = 1, /* if error message should be printed */
4801e196c8SJohn Marino optind = 1, /* index into parent argv vector */
4901e196c8SJohn Marino optopt = BADCH, /* character checked for validity */
5001e196c8SJohn Marino optreset; /* reset getopt */
5101e196c8SJohn Marino char *optarg; /* argument associated with option */
5201e196c8SJohn Marino
5301e196c8SJohn Marino /*
5401e196c8SJohn Marino * getopt --
5501e196c8SJohn Marino * Parse argc/argv argument vector.
5601e196c8SJohn Marino */
5701e196c8SJohn Marino int
getopt(int nargc,char * const nargv[],const char * ostr)58*f445c897SJohn Marino getopt(int nargc, char * const nargv[], const char *ostr)
5901e196c8SJohn Marino {
6001e196c8SJohn Marino extern char *__progname;
61*f445c897SJohn Marino static const char *place = EMSG; /* option letter processing */
6201e196c8SJohn Marino char *oli; /* option letter list index */
6301e196c8SJohn Marino
6401e196c8SJohn Marino #ifndef BSD4_4
6501e196c8SJohn Marino if (!__progname) {
6601e196c8SJohn Marino if (__progname = strrchr(nargv[0], '/'))
6701e196c8SJohn Marino ++__progname;
6801e196c8SJohn Marino else
6901e196c8SJohn Marino __progname = nargv[0];
7001e196c8SJohn Marino }
7101e196c8SJohn Marino #endif
7201e196c8SJohn Marino
73*f445c897SJohn Marino if (optreset || *place == 0) { /* update scanning pointer */
7401e196c8SJohn Marino optreset = 0;
75*f445c897SJohn Marino place = nargv[optind];
76*f445c897SJohn Marino if (optind >= nargc || *place++ != '-') {
77*f445c897SJohn Marino /* Argument is absent or is not an option */
7801e196c8SJohn Marino place = EMSG;
7901e196c8SJohn Marino return (-1);
8001e196c8SJohn Marino }
81*f445c897SJohn Marino optopt = *place++;
82*f445c897SJohn Marino if (optopt == '-' && *place == 0) {
83*f445c897SJohn Marino /* "--" => end of options */
8401e196c8SJohn Marino ++optind;
8501e196c8SJohn Marino place = EMSG;
8601e196c8SJohn Marino return (-1);
8701e196c8SJohn Marino }
88*f445c897SJohn Marino if (optopt == 0) {
89*f445c897SJohn Marino /* Solitary '-', treat as a '-' option
90*f445c897SJohn Marino if the program (eg su) is looking for it. */
91*f445c897SJohn Marino place = EMSG;
92*f445c897SJohn Marino if (strchr(ostr, '-') == NULL)
93*f445c897SJohn Marino return -1;
94*f445c897SJohn Marino optopt = '-';
95*f445c897SJohn Marino }
96*f445c897SJohn Marino } else
97*f445c897SJohn Marino optopt = *place++;
98*f445c897SJohn Marino
99*f445c897SJohn Marino /* See if option letter is one the caller wanted... */
100*f445c897SJohn Marino if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
101*f445c897SJohn Marino if (*place == 0)
10201e196c8SJohn Marino ++optind;
10301e196c8SJohn Marino if (opterr && *ostr != ':')
10401e196c8SJohn Marino (void)fprintf(stderr,
105*f445c897SJohn Marino "%s: unknown option -- %c\n", __progname, optopt);
10601e196c8SJohn Marino return (BADCH);
10701e196c8SJohn Marino }
108*f445c897SJohn Marino
109*f445c897SJohn Marino /* Does this option need an argument? */
110*f445c897SJohn Marino if (oli[1] != ':') {
111*f445c897SJohn Marino /* don't need argument */
11201e196c8SJohn Marino optarg = NULL;
113*f445c897SJohn Marino if (*place == 0)
11401e196c8SJohn Marino ++optind;
115*f445c897SJohn Marino } else {
116*f445c897SJohn Marino /* Option-argument is either the rest of this argument or the
117*f445c897SJohn Marino entire next argument. */
118*f445c897SJohn Marino if (*place)
119*f445c897SJohn Marino optarg = __UNCONST(place);
120*f445c897SJohn Marino else if (oli[2] == ':')
121*f445c897SJohn Marino /*
122*f445c897SJohn Marino * GNU Extension, for optional arguments if the rest of
123*f445c897SJohn Marino * the argument is empty, we return NULL
124*f445c897SJohn Marino */
125*f445c897SJohn Marino optarg = NULL;
126*f445c897SJohn Marino else if (nargc > ++optind)
127*f445c897SJohn Marino optarg = nargv[optind];
128*f445c897SJohn Marino else {
129*f445c897SJohn Marino /* option-argument absent */
13001e196c8SJohn Marino place = EMSG;
13101e196c8SJohn Marino if (*ostr == ':')
13201e196c8SJohn Marino return (BADARG);
13301e196c8SJohn Marino if (opterr)
13401e196c8SJohn Marino (void)fprintf(stderr,
13501e196c8SJohn Marino "%s: option requires an argument -- %c\n",
13601e196c8SJohn Marino __progname, optopt);
13701e196c8SJohn Marino return (BADCH);
13801e196c8SJohn Marino }
13901e196c8SJohn Marino place = EMSG;
14001e196c8SJohn Marino ++optind;
14101e196c8SJohn Marino }
142*f445c897SJohn Marino return (optopt); /* return option letter */
14301e196c8SJohn Marino }
14401e196c8SJohn Marino #endif
14501e196c8SJohn Marino #ifdef MAIN
14601e196c8SJohn Marino #ifndef BSD4_4
14701e196c8SJohn Marino char *__progname;
14801e196c8SJohn Marino #endif
14901e196c8SJohn Marino
15001e196c8SJohn Marino int
main(argc,argv)15101e196c8SJohn Marino main(argc, argv)
15201e196c8SJohn Marino int argc;
15301e196c8SJohn Marino char *argv[];
15401e196c8SJohn Marino {
15501e196c8SJohn Marino int c;
15601e196c8SJohn Marino char *opts = argv[1];
15701e196c8SJohn Marino
15801e196c8SJohn Marino --argc;
15901e196c8SJohn Marino ++argv;
16001e196c8SJohn Marino
16101e196c8SJohn Marino while ((c = getopt(argc, argv, opts)) != EOF) {
16201e196c8SJohn Marino switch (c) {
16301e196c8SJohn Marino case '-':
16401e196c8SJohn Marino if (optarg)
16501e196c8SJohn Marino printf("--%s ", optarg);
16601e196c8SJohn Marino break;
16701e196c8SJohn Marino case '?':
16801e196c8SJohn Marino exit(1);
16901e196c8SJohn Marino break;
17001e196c8SJohn Marino default:
17101e196c8SJohn Marino if (optarg)
17201e196c8SJohn Marino printf("-%c %s ", c, optarg);
17301e196c8SJohn Marino else
17401e196c8SJohn Marino printf("-%c ", c);
17501e196c8SJohn Marino break;
17601e196c8SJohn Marino }
17701e196c8SJohn Marino }
17801e196c8SJohn Marino
17901e196c8SJohn Marino if (optind < argc) {
18001e196c8SJohn Marino printf("-- ");
18101e196c8SJohn Marino for (; optind < argc; ++optind) {
18201e196c8SJohn Marino printf("%s ", argv[optind]);
18301e196c8SJohn Marino }
18401e196c8SJohn Marino }
18501e196c8SJohn Marino printf("\n");
18601e196c8SJohn Marino exit(0);
18701e196c8SJohn Marino }
18801e196c8SJohn Marino #endif
189