1/*	$NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $	*/
2
3/*
4 * Copyright (c) 1987, 1993, 1994, 1995
5 *	The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. Neither the names of the copyright holders nor the names of its
16 *    contributors may be used to endorse or promote products derived from
17 *    this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
20 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#if 0
33static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
34#endif
35
36#include <assert.h>
37#include <errno.h>
38#include <stdio.h>
39#include <string.h>
40
41#define __P(x) x
42#define _DIAGASSERT(x) assert(x)
43
44#ifdef __weak_alias
45__weak_alias(getopt,_getopt);
46#endif
47
48
49int	opterr = 1,		/* if error message should be printed */
50	optind = 1,		/* index into parent argv vector */
51	optopt,			/* character checked for validity */
52	optreset;		/* reset getopt */
53char	*optarg;		/* argument associated with option */
54
55static char * _progname __P((char *));
56int getopt_internal __P((int, char * const *, const char *));
57
58static char *
59_progname(nargv0)
60	char * nargv0;
61{
62	char * tmp;
63
64	_DIAGASSERT(nargv0 != NULL);
65
66	tmp = strrchr(nargv0, '/');
67	if (tmp)
68		tmp++;
69	else
70		tmp = nargv0;
71	return(tmp);
72}
73
74#define	BADCH	(int)'?'
75#define	BADARG	(int)':'
76#define	EMSG	""
77
78/*
79 * getopt --
80 *	Parse argc/argv argument vector.
81 */
82int
83getopt(nargc, nargv, ostr)
84	int nargc;
85	char * const nargv[];
86	const char *ostr;
87{
88	static char *__progname = 0;
89	static char *place = EMSG;		/* option letter processing */
90	char *oli;				/* option letter list index */
91        __progname = __progname?__progname:_progname(*nargv);
92
93	_DIAGASSERT(nargv != NULL);
94	_DIAGASSERT(ostr != NULL);
95
96	if (optreset || !*place) {		/* update scanning pointer */
97		optreset = 0;
98		if (optind >= nargc || *(place = nargv[optind]) != '-') {
99			place = EMSG;
100			return (-1);
101		}
102		if (place[1] && *++place == '-'	/* found "--" */
103		    && place[1] == '\0') {
104			++optind;
105			place = EMSG;
106			return (-1);
107		}
108	}					/* option letter okay? */
109	if ((optopt = (int)*place++) == (int)':' ||
110	    !(oli = strchr(ostr, optopt))) {
111		/*
112		 * if the user didn't specify '-' as an option,
113		 * assume it means -1.
114		 */
115		if (optopt == (int)'-')
116			return (-1);
117		if (!*place)
118			++optind;
119		if (opterr && *ostr != ':')
120			(void)fprintf(stderr,
121			    "%s: illegal option -- %c\n", __progname, optopt);
122		return (BADCH);
123	}
124	if (*++oli != ':') {			/* don't need argument */
125		optarg = NULL;
126		if (!*place)
127			++optind;
128	}
129	else {					/* need an argument */
130		if (*place)			/* no white space */
131			optarg = place;
132		else if (nargc <= ++optind) {	/* no arg */
133			place = EMSG;
134			if (*ostr == ':')
135				return (BADARG);
136			if (opterr)
137				(void)fprintf(stderr,
138				    "%s: option requires an argument -- %c\n",
139				    __progname, optopt);
140			return (BADCH);
141		}
142	 	else				/* white space */
143			optarg = nargv[optind];
144		place = EMSG;
145		++optind;
146	}
147	return (optopt);			/* dump back option letter */
148}
149
150