1267745Spfg/*	$NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $	*/
2126696Sache
31573Srgrimes/*
41573Srgrimes * Copyright (c) 1987, 1993, 1994
51573Srgrimes *	The Regents of the University of California.  All rights reserved.
61573Srgrimes *
71573Srgrimes * Redistribution and use in source and binary forms, with or without
81573Srgrimes * modification, are permitted provided that the following conditions
91573Srgrimes * are met:
101573Srgrimes * 1. Redistributions of source code must retain the above copyright
111573Srgrimes *    notice, this list of conditions and the following disclaimer.
121573Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
131573Srgrimes *    notice, this list of conditions and the following disclaimer in the
141573Srgrimes *    documentation and/or other materials provided with the distribution.
15251069Semaste * 3. Neither the name of the University nor the names of its contributors
161573Srgrimes *    may be used to endorse or promote products derived from this software
171573Srgrimes *    without specific prior written permission.
181573Srgrimes *
191573Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
201573Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
211573Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
221573Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
231573Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
241573Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
251573Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
261573Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
271573Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
281573Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
291573Srgrimes * SUCH DAMAGE.
301573Srgrimes */
311573Srgrimes
321573Srgrimes#if defined(LIBC_SCCS) && !defined(lint)
3323658Speterstatic char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
341573Srgrimes#endif /* LIBC_SCCS and not lint */
3592986Sobrien#include <sys/cdefs.h>
3692986Sobrien__FBSDID("$FreeBSD: releng/11.0/lib/libc/stdlib/getopt.c 267745 2014-06-22 20:13:57Z pfg $");
371573Srgrimes
3893399Smarkm#include "namespace.h"
391573Srgrimes#include <stdio.h>
401573Srgrimes#include <stdlib.h>
411573Srgrimes#include <string.h>
42126696Sache#include <unistd.h>
4393399Smarkm#include "un-namespace.h"
441573Srgrimes
4593399Smarkm#include "libc_private.h"
4693399Smarkm
471573Srgrimesint	opterr = 1,		/* if error message should be printed */
481573Srgrimes	optind = 1,		/* index into parent argv vector */
491573Srgrimes	optopt,			/* character checked for validity */
501573Srgrimes	optreset;		/* reset getopt */
511573Srgrimeschar	*optarg;		/* argument associated with option */
521573Srgrimes
531573Srgrimes#define	BADCH	(int)'?'
541573Srgrimes#define	BADARG	(int)':'
551573Srgrimes#define	EMSG	""
561573Srgrimes
571573Srgrimes/*
581573Srgrimes * getopt --
591573Srgrimes *	Parse argc/argv argument vector.
601573Srgrimes */
611573Srgrimesint
62267745Spfggetopt(int nargc, char * const nargv[], const char *ostr)
631573Srgrimes{
641573Srgrimes	static char *place = EMSG;		/* option letter processing */
651573Srgrimes	char *oli;				/* option letter list index */
661573Srgrimes
67126696Sache	if (optreset || *place == 0) {		/* update scanning pointer */
681573Srgrimes		optreset = 0;
69126696Sache		place = nargv[optind];
70126696Sache		if (optind >= nargc || *place++ != '-') {
71126696Sache			/* Argument is absent or is not an option */
721573Srgrimes			place = EMSG;
7323658Speter			return (-1);
741573Srgrimes		}
75126696Sache		optopt = *place++;
76126696Sache		if (optopt == '-' && *place == 0) {
77126696Sache			/* "--" => end of options */
781573Srgrimes			++optind;
791573Srgrimes			place = EMSG;
8023658Speter			return (-1);
811573Srgrimes		}
82126696Sache		if (optopt == 0) {
83126696Sache			/* Solitary '-', treat as a '-' option
84126696Sache			   if the program (eg su) is looking for it. */
85126696Sache			place = EMSG;
86126696Sache			if (strchr(ostr, '-') == NULL)
87126696Sache				return (-1);
88126696Sache			optopt = '-';
89126696Sache		}
90126696Sache	} else
91126696Sache		optopt = *place++;
92126696Sache
93126696Sache	/* See if option letter is one the caller wanted... */
94126696Sache	if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
95126696Sache		if (*place == 0)
961573Srgrimes			++optind;
97126696Sache		if (opterr && *ostr != ':')
98126696Sache			(void)fprintf(stderr,
99126696Sache			    "%s: illegal option -- %c\n", _getprogname(),
100126696Sache			    optopt);
1011573Srgrimes		return (BADCH);
1021573Srgrimes	}
103126696Sache
104126696Sache	/* Does this option need an argument? */
105126696Sache	if (oli[1] != ':') {
106126696Sache		/* don't need argument */
1071573Srgrimes		optarg = NULL;
108126696Sache		if (*place == 0)
1091573Srgrimes			++optind;
110126696Sache	} else {
111126696Sache		/* Option-argument is either the rest of this argument or the
112126696Sache		   entire next argument. */
113126696Sache		if (*place)
1141573Srgrimes			optarg = place;
115267745Spfg		else if (oli[2] == ':')
116267745Spfg			/*
117267745Spfg			 * GNU Extension, for optional arguments if the rest of
118267745Spfg			 * the argument is empty, we return NULL
119267745Spfg			 */
120267745Spfg			optarg = NULL;
121126696Sache		else if (nargc > ++optind)
122126696Sache			optarg = nargv[optind];
123126696Sache		else {
124126696Sache			/* option-argument absent */
1251573Srgrimes			place = EMSG;
1261573Srgrimes			if (*ostr == ':')
12781746Sjkoshy				return (BADARG);
1281573Srgrimes			if (opterr)
1291573Srgrimes				(void)fprintf(stderr,
1301573Srgrimes				    "%s: option requires an argument -- %c\n",
13193399Smarkm				    _getprogname(), optopt);
13281746Sjkoshy			return (BADCH);
1331573Srgrimes		}
1341573Srgrimes		place = EMSG;
1351573Srgrimes		++optind;
1361573Srgrimes	}
137126696Sache	return (optopt);			/* return option letter */
1381573Srgrimes}
139