xref: /freebsd/contrib/unifdef/FreeBSD/getopt.c (revision fb3ef04d2028110f06d68b09009f1f2ca0f4128e)
1*fb3ef04dSDag-Erling Smørgrav /*
2*fb3ef04dSDag-Erling Smørgrav  * Copyright (c) 1987, 1993, 1994
3*fb3ef04dSDag-Erling Smørgrav  *	The Regents of the University of California.  All rights reserved.
4*fb3ef04dSDag-Erling Smørgrav  *
5*fb3ef04dSDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
6*fb3ef04dSDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
7*fb3ef04dSDag-Erling Smørgrav  * are met:
8*fb3ef04dSDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
9*fb3ef04dSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer.
10*fb3ef04dSDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
11*fb3ef04dSDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
12*fb3ef04dSDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
13*fb3ef04dSDag-Erling Smørgrav  * 4. Neither the name of the University nor the names of its contributors
14*fb3ef04dSDag-Erling Smørgrav  *    may be used to endorse or promote products derived from this software
15*fb3ef04dSDag-Erling Smørgrav  *    without specific prior written permission.
16*fb3ef04dSDag-Erling Smørgrav  *
17*fb3ef04dSDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18*fb3ef04dSDag-Erling Smørgrav  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*fb3ef04dSDag-Erling Smørgrav  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*fb3ef04dSDag-Erling Smørgrav  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21*fb3ef04dSDag-Erling Smørgrav  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*fb3ef04dSDag-Erling Smørgrav  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*fb3ef04dSDag-Erling Smørgrav  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*fb3ef04dSDag-Erling Smørgrav  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*fb3ef04dSDag-Erling Smørgrav  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*fb3ef04dSDag-Erling Smørgrav  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*fb3ef04dSDag-Erling Smørgrav  * SUCH DAMAGE.
28*fb3ef04dSDag-Erling Smørgrav  */
29*fb3ef04dSDag-Erling Smørgrav 
30*fb3ef04dSDag-Erling Smørgrav #include "unifdef.h"
31*fb3ef04dSDag-Erling Smørgrav 
32*fb3ef04dSDag-Erling Smørgrav int	opterr = 1,		/* if error message should be printed */
33*fb3ef04dSDag-Erling Smørgrav 	optind = 1,		/* index into parent argv vector */
34*fb3ef04dSDag-Erling Smørgrav 	optopt,			/* character checked for validity */
35*fb3ef04dSDag-Erling Smørgrav 	optreset;		/* reset getopt */
36*fb3ef04dSDag-Erling Smørgrav char	*optarg;		/* argument associated with option */
37*fb3ef04dSDag-Erling Smørgrav 
38*fb3ef04dSDag-Erling Smørgrav #define	BADCH	(int)'?'
39*fb3ef04dSDag-Erling Smørgrav #define	BADARG	(int)':'
40*fb3ef04dSDag-Erling Smørgrav 
41*fb3ef04dSDag-Erling Smørgrav static char EMSG[] = "";
42*fb3ef04dSDag-Erling Smørgrav 
43*fb3ef04dSDag-Erling Smørgrav /*
44*fb3ef04dSDag-Erling Smørgrav  * getopt --
45*fb3ef04dSDag-Erling Smørgrav  *	Parse argc/argv argument vector.
46*fb3ef04dSDag-Erling Smørgrav  */
47*fb3ef04dSDag-Erling Smørgrav int
getopt(int nargc,char * nargv[],const char * ostr)48*fb3ef04dSDag-Erling Smørgrav getopt(int nargc, char *nargv[], const char *ostr)
49*fb3ef04dSDag-Erling Smørgrav {
50*fb3ef04dSDag-Erling Smørgrav 	static char *place = EMSG;		/* option letter processing */
51*fb3ef04dSDag-Erling Smørgrav 	const char *oli;			/* option letter list index */
52*fb3ef04dSDag-Erling Smørgrav 
53*fb3ef04dSDag-Erling Smørgrav 	if (optreset || *place == 0) {		/* update scanning pointer */
54*fb3ef04dSDag-Erling Smørgrav 		optreset = 0;
55*fb3ef04dSDag-Erling Smørgrav 		place = nargv[optind];
56*fb3ef04dSDag-Erling Smørgrav 		if (optind >= nargc || *place++ != '-') {
57*fb3ef04dSDag-Erling Smørgrav 			/* Argument is absent or is not an option */
58*fb3ef04dSDag-Erling Smørgrav 			place = EMSG;
59*fb3ef04dSDag-Erling Smørgrav 			return (-1);
60*fb3ef04dSDag-Erling Smørgrav 		}
61*fb3ef04dSDag-Erling Smørgrav 		optopt = *place++;
62*fb3ef04dSDag-Erling Smørgrav 		if (optopt == '-' && *place == 0) {
63*fb3ef04dSDag-Erling Smørgrav 			/* "--" => end of options */
64*fb3ef04dSDag-Erling Smørgrav 			++optind;
65*fb3ef04dSDag-Erling Smørgrav 			place = EMSG;
66*fb3ef04dSDag-Erling Smørgrav 			return (-1);
67*fb3ef04dSDag-Erling Smørgrav 		}
68*fb3ef04dSDag-Erling Smørgrav 		if (optopt == 0) {
69*fb3ef04dSDag-Erling Smørgrav 			/* Solitary '-', treat as a '-' option
70*fb3ef04dSDag-Erling Smørgrav 			   if the program (eg su) is looking for it. */
71*fb3ef04dSDag-Erling Smørgrav 			place = EMSG;
72*fb3ef04dSDag-Erling Smørgrav 			if (strchr(ostr, '-') == NULL)
73*fb3ef04dSDag-Erling Smørgrav 				return (-1);
74*fb3ef04dSDag-Erling Smørgrav 			optopt = '-';
75*fb3ef04dSDag-Erling Smørgrav 		}
76*fb3ef04dSDag-Erling Smørgrav 	} else
77*fb3ef04dSDag-Erling Smørgrav 		optopt = *place++;
78*fb3ef04dSDag-Erling Smørgrav 
79*fb3ef04dSDag-Erling Smørgrav 	/* See if option letter is one the caller wanted... */
80*fb3ef04dSDag-Erling Smørgrav 	if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
81*fb3ef04dSDag-Erling Smørgrav 		if (*place == 0)
82*fb3ef04dSDag-Erling Smørgrav 			++optind;
83*fb3ef04dSDag-Erling Smørgrav 		if (opterr && *ostr != ':')
84*fb3ef04dSDag-Erling Smørgrav 			(void)fprintf(stderr,
85*fb3ef04dSDag-Erling Smørgrav 			    "%s: illegal option -- %c\n", _getprogname(),
86*fb3ef04dSDag-Erling Smørgrav 			    optopt);
87*fb3ef04dSDag-Erling Smørgrav 		return (BADCH);
88*fb3ef04dSDag-Erling Smørgrav 	}
89*fb3ef04dSDag-Erling Smørgrav 
90*fb3ef04dSDag-Erling Smørgrav 	/* Does this option need an argument? */
91*fb3ef04dSDag-Erling Smørgrav 	if (oli[1] != ':') {
92*fb3ef04dSDag-Erling Smørgrav 		/* don't need argument */
93*fb3ef04dSDag-Erling Smørgrav 		optarg = NULL;
94*fb3ef04dSDag-Erling Smørgrav 		if (*place == 0)
95*fb3ef04dSDag-Erling Smørgrav 			++optind;
96*fb3ef04dSDag-Erling Smørgrav 	} else {
97*fb3ef04dSDag-Erling Smørgrav 		/* Option-argument is either the rest of this argument or the
98*fb3ef04dSDag-Erling Smørgrav 		   entire next argument. */
99*fb3ef04dSDag-Erling Smørgrav 		if (*place)
100*fb3ef04dSDag-Erling Smørgrav 			optarg = place;
101*fb3ef04dSDag-Erling Smørgrav 		else if (nargc > ++optind)
102*fb3ef04dSDag-Erling Smørgrav 			optarg = nargv[optind];
103*fb3ef04dSDag-Erling Smørgrav 		else {
104*fb3ef04dSDag-Erling Smørgrav 			/* option-argument absent */
105*fb3ef04dSDag-Erling Smørgrav 			place = EMSG;
106*fb3ef04dSDag-Erling Smørgrav 			if (*ostr == ':')
107*fb3ef04dSDag-Erling Smørgrav 				return (BADARG);
108*fb3ef04dSDag-Erling Smørgrav 			if (opterr)
109*fb3ef04dSDag-Erling Smørgrav 				(void)fprintf(stderr,
110*fb3ef04dSDag-Erling Smørgrav 				    "%s: option requires an argument -- %c\n",
111*fb3ef04dSDag-Erling Smørgrav 				    _getprogname(), optopt);
112*fb3ef04dSDag-Erling Smørgrav 			return (BADCH);
113*fb3ef04dSDag-Erling Smørgrav 		}
114*fb3ef04dSDag-Erling Smørgrav 		place = EMSG;
115*fb3ef04dSDag-Erling Smørgrav 		++optind;
116*fb3ef04dSDag-Erling Smørgrav 	}
117*fb3ef04dSDag-Erling Smørgrav 	return (optopt);			/* return option letter */
118*fb3ef04dSDag-Erling Smørgrav }
119