1144c6bcdSlogwang /* $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $ */
2144c6bcdSlogwang
3144c6bcdSlogwang /*
4144c6bcdSlogwang * Copyright (c) 1987, 1993, 1994
5144c6bcdSlogwang * The Regents of the University of California. All rights reserved.
6144c6bcdSlogwang *
7144c6bcdSlogwang * Redistribution and use in source and binary forms, with or without
8144c6bcdSlogwang * modification, are permitted provided that the following conditions
9144c6bcdSlogwang * are met:
10144c6bcdSlogwang * 1. Redistributions of source code must retain the above copyright
11144c6bcdSlogwang * notice, this list of conditions and the following disclaimer.
12144c6bcdSlogwang * 2. Redistributions in binary form must reproduce the above copyright
13144c6bcdSlogwang * notice, this list of conditions and the following disclaimer in the
14144c6bcdSlogwang * documentation and/or other materials provided with the distribution.
15144c6bcdSlogwang * 3. Neither the name of the University nor the names of its contributors
16144c6bcdSlogwang * may be used to endorse or promote products derived from this software
17144c6bcdSlogwang * without specific prior written permission.
18144c6bcdSlogwang *
19144c6bcdSlogwang * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20144c6bcdSlogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21144c6bcdSlogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22144c6bcdSlogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23144c6bcdSlogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24144c6bcdSlogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25144c6bcdSlogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26144c6bcdSlogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27144c6bcdSlogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28144c6bcdSlogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29144c6bcdSlogwang * SUCH DAMAGE.
30144c6bcdSlogwang */
31144c6bcdSlogwang
32144c6bcdSlogwang #if defined(LIBC_SCCS) && !defined(lint)
33144c6bcdSlogwang static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
34144c6bcdSlogwang #endif /* LIBC_SCCS and not lint */
35144c6bcdSlogwang #include <sys/cdefs.h>
36144c6bcdSlogwang #ifndef FSTACK
37144c6bcdSlogwang __FBSDID("$FreeBSD$");
38144c6bcdSlogwang
39144c6bcdSlogwang #include "namespace.h"
40144c6bcdSlogwang #endif
41144c6bcdSlogwang #include <stdio.h>
42144c6bcdSlogwang #include <stdlib.h>
43144c6bcdSlogwang #include <string.h>
44144c6bcdSlogwang #include <unistd.h>
45144c6bcdSlogwang #ifndef FSTACK
46144c6bcdSlogwang #include "un-namespace.h"
47144c6bcdSlogwang
48144c6bcdSlogwang #include "libc_private.h"
49*1eaf0ac3Slogwang #else
50*1eaf0ac3Slogwang #include "compat.h"
51144c6bcdSlogwang #endif
52144c6bcdSlogwang
53144c6bcdSlogwang int opterr = 1, /* if error message should be printed */
54144c6bcdSlogwang optind = 1, /* index into parent argv vector */
55144c6bcdSlogwang optopt, /* character checked for validity */
56144c6bcdSlogwang optreset; /* reset getopt */
57144c6bcdSlogwang char *optarg; /* argument associated with option */
58144c6bcdSlogwang
59144c6bcdSlogwang #define BADCH (int)'?'
60144c6bcdSlogwang #define BADARG (int)':'
61144c6bcdSlogwang #define EMSG ""
62144c6bcdSlogwang
63144c6bcdSlogwang /*
64144c6bcdSlogwang * getopt --
65144c6bcdSlogwang * Parse argc/argv argument vector.
66144c6bcdSlogwang */
67144c6bcdSlogwang int
getopt(int nargc,char * const nargv[],const char * ostr)68144c6bcdSlogwang getopt(int nargc, char * const nargv[], const char *ostr)
69144c6bcdSlogwang {
70144c6bcdSlogwang static char *place = EMSG; /* option letter processing */
71144c6bcdSlogwang char *oli; /* option letter list index */
72144c6bcdSlogwang
73144c6bcdSlogwang if (optreset || *place == 0) { /* update scanning pointer */
74144c6bcdSlogwang optreset = 0;
75144c6bcdSlogwang place = nargv[optind];
76144c6bcdSlogwang if (optind >= nargc || *place++ != '-') {
77144c6bcdSlogwang /* Argument is absent or is not an option */
78144c6bcdSlogwang place = EMSG;
79144c6bcdSlogwang return (-1);
80144c6bcdSlogwang }
81144c6bcdSlogwang optopt = *place++;
82144c6bcdSlogwang if (optopt == '-' && *place == 0) {
83144c6bcdSlogwang /* "--" => end of options */
84144c6bcdSlogwang ++optind;
85144c6bcdSlogwang place = EMSG;
86144c6bcdSlogwang return (-1);
87144c6bcdSlogwang }
88144c6bcdSlogwang if (optopt == 0) {
89144c6bcdSlogwang /* Solitary '-', treat as a '-' option
90144c6bcdSlogwang if the program (eg su) is looking for it. */
91144c6bcdSlogwang place = EMSG;
92144c6bcdSlogwang if (strchr(ostr, '-') == NULL)
93144c6bcdSlogwang return (-1);
94144c6bcdSlogwang optopt = '-';
95144c6bcdSlogwang }
96144c6bcdSlogwang } else
97144c6bcdSlogwang optopt = *place++;
98144c6bcdSlogwang
99144c6bcdSlogwang /* See if option letter is one the caller wanted... */
100144c6bcdSlogwang if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
101144c6bcdSlogwang if (*place == 0)
102144c6bcdSlogwang ++optind;
103144c6bcdSlogwang if (opterr && *ostr != ':')
104144c6bcdSlogwang (void)fprintf(stderr,
105144c6bcdSlogwang #ifndef FSTACK
106144c6bcdSlogwang "%s: illegal option -- %c\n", _getprogname(),
107144c6bcdSlogwang #else
108*1eaf0ac3Slogwang "%s: illegal option -- %c\n", getprogname(),
109144c6bcdSlogwang #endif
110144c6bcdSlogwang optopt);
111144c6bcdSlogwang return (BADCH);
112144c6bcdSlogwang }
113144c6bcdSlogwang
114144c6bcdSlogwang /* Does this option need an argument? */
115144c6bcdSlogwang if (oli[1] != ':') {
116144c6bcdSlogwang /* don't need argument */
117144c6bcdSlogwang optarg = NULL;
118144c6bcdSlogwang if (*place == 0)
119144c6bcdSlogwang ++optind;
120144c6bcdSlogwang } else {
121144c6bcdSlogwang /* Option-argument is either the rest of this argument or the
122144c6bcdSlogwang entire next argument. */
123144c6bcdSlogwang if (*place)
124144c6bcdSlogwang optarg = place;
125144c6bcdSlogwang else if (oli[2] == ':')
126144c6bcdSlogwang /*
127144c6bcdSlogwang * GNU Extension, for optional arguments if the rest of
128144c6bcdSlogwang * the argument is empty, we return NULL
129144c6bcdSlogwang */
130144c6bcdSlogwang optarg = NULL;
131144c6bcdSlogwang else if (nargc > ++optind)
132144c6bcdSlogwang optarg = nargv[optind];
133144c6bcdSlogwang else {
134144c6bcdSlogwang /* option-argument absent */
135144c6bcdSlogwang place = EMSG;
136144c6bcdSlogwang if (*ostr == ':')
137144c6bcdSlogwang return (BADARG);
138144c6bcdSlogwang if (opterr)
139144c6bcdSlogwang (void)fprintf(stderr,
140144c6bcdSlogwang #ifndef FSTACK
141144c6bcdSlogwang "%s: option requires an argument -- %c\n",
142144c6bcdSlogwang _getprogname(), optopt);
143144c6bcdSlogwang #else
144*1eaf0ac3Slogwang "%s: option requires an argument -- %c\n",
145*1eaf0ac3Slogwang getprogname(), optopt);
146144c6bcdSlogwang #endif
147144c6bcdSlogwang return (BADCH);
148144c6bcdSlogwang }
149144c6bcdSlogwang place = EMSG;
150144c6bcdSlogwang ++optind;
151144c6bcdSlogwang }
152144c6bcdSlogwang return (optopt); /* return option letter */
153144c6bcdSlogwang }
154