getopt.c revision 165903
1203288Srnoland/*	$NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $	*/
2203288Srnoland
3203288Srnoland/*
4203288Srnoland * Copyright (c) 1987, 1993, 1994
5203288Srnoland *	The Regents of the University of California.  All rights reserved.
6203288Srnoland *
7203288Srnoland * Redistribution and use in source and binary forms, with or without
8203288Srnoland * modification, are permitted provided that the following conditions
9203288Srnoland * are met:
10203288Srnoland * 1. Redistributions of source code must retain the above copyright
11203288Srnoland *    notice, this list of conditions and the following disclaimer.
12203288Srnoland * 2. Redistributions in binary form must reproduce the above copyright
13203288Srnoland *    notice, this list of conditions and the following disclaimer in the
14203288Srnoland *    documentation and/or other materials provided with the distribution.
15203288Srnoland * 4. Neither the name of the University nor the names of its contributors
16203288Srnoland *    may be used to endorse or promote products derived from this software
17203288Srnoland *    without specific prior written permission.
18203288Srnoland *
19203288Srnoland * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20203288Srnoland * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21203288Srnoland * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22203288Srnoland * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23203288Srnoland * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24203288Srnoland * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25203288Srnoland * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26203288Srnoland * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27203288Srnoland * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28203288Srnoland * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29203288Srnoland * SUCH DAMAGE.
30203288Srnoland */
31203288Srnoland
32203288Srnoland#if defined(LIBC_SCCS) && !defined(lint)
33203288Srnolandstatic char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
34203288Srnoland#endif /* LIBC_SCCS and not lint */
35203288Srnoland#include <sys/cdefs.h>
36203288Srnoland__FBSDID("$FreeBSD: head/lib/libc/stdlib/getopt.c 165903 2007-01-09 00:28:16Z imp $");
37203288Srnoland
38203288Srnoland#include "namespace.h"
39203288Srnoland#include <stdio.h>
40203288Srnoland#include <stdlib.h>
41203288Srnoland#include <string.h>
42203288Srnoland#include <unistd.h>
43203288Srnoland#include "un-namespace.h"
44203288Srnoland
45203288Srnoland#include "libc_private.h"
46203288Srnoland
47203288Srnolandint	opterr = 1,		/* if error message should be printed */
48203288Srnoland	optind = 1,		/* index into parent argv vector */
49203288Srnoland	optopt,			/* character checked for validity */
50203288Srnoland	optreset;		/* reset getopt */
51203288Srnolandchar	*optarg;		/* argument associated with option */
52203288Srnoland
53203288Srnoland#define	BADCH	(int)'?'
54203288Srnoland#define	BADARG	(int)':'
55203288Srnoland#define	EMSG	""
56203288Srnoland
57203288Srnoland/*
58203288Srnoland * getopt --
59203288Srnoland *	Parse argc/argv argument vector.
60203288Srnoland */
61203288Srnolandint
62203288Srnolandgetopt(nargc, nargv, ostr)
63203288Srnoland	int nargc;
64203288Srnoland	char * const nargv[];
65203288Srnoland	const char *ostr;
66203288Srnoland{
67203288Srnoland	static char *place = EMSG;		/* option letter processing */
68203288Srnoland	char *oli;				/* option letter list index */
69203288Srnoland
70203288Srnoland	if (optreset || *place == 0) {		/* update scanning pointer */
71203288Srnoland		optreset = 0;
72203288Srnoland		place = nargv[optind];
73203288Srnoland		if (optind >= nargc || *place++ != '-') {
74203288Srnoland			/* Argument is absent or is not an option */
75203288Srnoland			place = EMSG;
76203288Srnoland			return (-1);
77203288Srnoland		}
78203288Srnoland		optopt = *place++;
79203288Srnoland		if (optopt == '-' && *place == 0) {
80203288Srnoland			/* "--" => end of options */
81203288Srnoland			++optind;
82203288Srnoland			place = EMSG;
83203288Srnoland			return (-1);
84203288Srnoland		}
85203288Srnoland		if (optopt == 0) {
86203288Srnoland			/* Solitary '-', treat as a '-' option
87203288Srnoland			   if the program (eg su) is looking for it. */
88203288Srnoland			place = EMSG;
89203288Srnoland			if (strchr(ostr, '-') == NULL)
90203288Srnoland				return (-1);
91203288Srnoland			optopt = '-';
92203288Srnoland		}
93203288Srnoland	} else
94203288Srnoland		optopt = *place++;
95203288Srnoland
96203288Srnoland	/* See if option letter is one the caller wanted... */
97203288Srnoland	if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
98203288Srnoland		if (*place == 0)
99203288Srnoland			++optind;
100203288Srnoland		if (opterr && *ostr != ':')
101203288Srnoland			(void)fprintf(stderr,
102203288Srnoland			    "%s: illegal option -- %c\n", _getprogname(),
103203288Srnoland			    optopt);
104203288Srnoland		return (BADCH);
105203288Srnoland	}
106203288Srnoland
107203288Srnoland	/* Does this option need an argument? */
108203288Srnoland	if (oli[1] != ':') {
109203288Srnoland		/* don't need argument */
110203288Srnoland		optarg = NULL;
111203288Srnoland		if (*place == 0)
112203288Srnoland			++optind;
113203288Srnoland	} else {
114203288Srnoland		/* Option-argument is either the rest of this argument or the
115203288Srnoland		   entire next argument. */
116203288Srnoland		if (*place)
117203288Srnoland			optarg = place;
118203288Srnoland		else if (nargc > ++optind)
119203288Srnoland			optarg = nargv[optind];
120203288Srnoland		else {
121203288Srnoland			/* option-argument absent */
122203288Srnoland			place = EMSG;
123203288Srnoland			if (*ostr == ':')
124203288Srnoland				return (BADARG);
125203288Srnoland			if (opterr)
126203288Srnoland				(void)fprintf(stderr,
127203288Srnoland				    "%s: option requires an argument -- %c\n",
128203288Srnoland				    _getprogname(), optopt);
129203288Srnoland			return (BADCH);
130203288Srnoland		}
131203288Srnoland		place = EMSG;
132203288Srnoland		++optind;
133203288Srnoland	}
134203288Srnoland	return (optopt);			/* return option letter */
135203288Srnoland}
136203288Srnoland