1*4d9fdb46SRobert Mustacchi /* $NetBSD: getopt.c,v 1.1 2009/03/22 22:33:13 joerg Exp $*/
2*4d9fdb46SRobert Mustacchi /* Modified by David Anderson to work with GNU/Linux and freebsd.
3*4d9fdb46SRobert Mustacchi Added {} for clarity.
4*4d9fdb46SRobert Mustacchi Switched to standard dwarfdump formatting.
5*4d9fdb46SRobert Mustacchi Treatment of : modified so that :: gets dwoptarg NULL
6*4d9fdb46SRobert Mustacchi if space follows the letter
7*4d9fdb46SRobert Mustacchi (the dwoptarg is set to null).
8*4d9fdb46SRobert Mustacchi renamed to make it clear this is a private version.
9*4d9fdb46SRobert Mustacchi Oct 17 2017: Created dwgetopt_long(). See dwgetopt.h
10*4d9fdb46SRobert Mustacchi */
11*4d9fdb46SRobert Mustacchi /*
12*4d9fdb46SRobert Mustacchi * Copyright (c) 1987, 1993, 1994
13*4d9fdb46SRobert Mustacchi * The Regents of the University of California. All rights reserved.
14*4d9fdb46SRobert Mustacchi *
15*4d9fdb46SRobert Mustacchi * Redistribution and use in source and binary forms, with or without
16*4d9fdb46SRobert Mustacchi * modification, are permitted provided that the following conditions
17*4d9fdb46SRobert Mustacchi * are met:
18*4d9fdb46SRobert Mustacchi * 1. Redistributions of source code must retain the above copyright
19*4d9fdb46SRobert Mustacchi * notice, this list of conditions and the following disclaimer.
20*4d9fdb46SRobert Mustacchi * 2. Redistributions in binary form must reproduce the above copyright
21*4d9fdb46SRobert Mustacchi * notice, this list of conditions and the following disclaimer in the
22*4d9fdb46SRobert Mustacchi * documentation and/or other materials provided with the distribution.
23*4d9fdb46SRobert Mustacchi * 3. Neither the name of the University nor the names of its contributors
24*4d9fdb46SRobert Mustacchi * may be used to endorse or promote products derived from this software
25*4d9fdb46SRobert Mustacchi * without specific prior written permission.
26*4d9fdb46SRobert Mustacchi *
27*4d9fdb46SRobert Mustacchi * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28*4d9fdb46SRobert Mustacchi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*4d9fdb46SRobert Mustacchi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*4d9fdb46SRobert Mustacchi * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31*4d9fdb46SRobert Mustacchi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32*4d9fdb46SRobert Mustacchi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33*4d9fdb46SRobert Mustacchi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34*4d9fdb46SRobert Mustacchi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35*4d9fdb46SRobert Mustacchi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36*4d9fdb46SRobert Mustacchi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37*4d9fdb46SRobert Mustacchi * SUCH DAMAGE.
38*4d9fdb46SRobert Mustacchi */
39*4d9fdb46SRobert Mustacchi
40*4d9fdb46SRobert Mustacchi /* This does not presently handle the option string
41*4d9fdb46SRobert Mustacchi leading + or leading - features. Such are not used
42*4d9fdb46SRobert Mustacchi by by libdwarfdump. Nor does it understand the
43*4d9fdb46SRobert Mustacchi GNU Env var POSIXLY_CORRECT .
44*4d9fdb46SRobert Mustacchi It does know of the leading ":" in the option string.
45*4d9fdb46SRobert Mustacchi See BADCH below.
46*4d9fdb46SRobert Mustacchi */
47*4d9fdb46SRobert Mustacchi
48*4d9fdb46SRobert Mustacchi #include <stdio.h>
49*4d9fdb46SRobert Mustacchi #ifdef HAVE_STDLIB_H
50*4d9fdb46SRobert Mustacchi #include <stdlib.h>
51*4d9fdb46SRobert Mustacchi #endif /* HAVE_STDLIB_H */
52*4d9fdb46SRobert Mustacchi #include <string.h> /* For strchr */
53*4d9fdb46SRobert Mustacchi #include "dwgetopt.h"
54*4d9fdb46SRobert Mustacchi
55*4d9fdb46SRobert Mustacchi #define STRIP_OFF_CONSTNESS(a) ((void *)(size_t)(const void *)(a))
56*4d9fdb46SRobert Mustacchi
57*4d9fdb46SRobert Mustacchi int dwopterr = 1, /* if error message should be printed */
58*4d9fdb46SRobert Mustacchi dwoptind = 1, /* index into parent argv vector */
59*4d9fdb46SRobert Mustacchi dwoptopt, /* character checked for validity */
60*4d9fdb46SRobert Mustacchi dwoptreset; /* reset getopt */
61*4d9fdb46SRobert Mustacchi char *dwoptarg; /* argument associated with option */
62*4d9fdb46SRobert Mustacchi
63*4d9fdb46SRobert Mustacchi #define BADCH (int)'?'
64*4d9fdb46SRobert Mustacchi #define BADARG (int)':'
65*4d9fdb46SRobert Mustacchi #define EMSG ""
66*4d9fdb46SRobert Mustacchi
67*4d9fdb46SRobert Mustacchi #define TRUE 1
68*4d9fdb46SRobert Mustacchi #define FALSE 0
69*4d9fdb46SRobert Mustacchi
70*4d9fdb46SRobert Mustacchi #if 0 /* FOR DEBUGGING ONLY */
71*4d9fdb46SRobert Mustacchi /* Use for testing dwgetopt only.
72*4d9fdb46SRobert Mustacchi Not a standard function. */
73*4d9fdb46SRobert Mustacchi void
74*4d9fdb46SRobert Mustacchi dwgetoptresetfortestingonly(void)
75*4d9fdb46SRobert Mustacchi {
76*4d9fdb46SRobert Mustacchi dwopterr = 1;
77*4d9fdb46SRobert Mustacchi dwoptind = 1;
78*4d9fdb46SRobert Mustacchi dwoptopt = 0;
79*4d9fdb46SRobert Mustacchi dwoptreset = 0;
80*4d9fdb46SRobert Mustacchi dwoptarg = 0;
81*4d9fdb46SRobert Mustacchi }
82*4d9fdb46SRobert Mustacchi #endif /* FOR DEBUGGING ONLY */
83*4d9fdb46SRobert Mustacchi
84*4d9fdb46SRobert Mustacchi
85*4d9fdb46SRobert Mustacchi static const char *place = EMSG;/* option letter processing */
86*4d9fdb46SRobert Mustacchi
87*4d9fdb46SRobert Mustacchi
88*4d9fdb46SRobert Mustacchi /* Post Condition:
89*4d9fdb46SRobert Mustacchi if return FALSE then *argerr is set false. */
90*4d9fdb46SRobert Mustacchi static int
dwoptnamematches(const struct dwoption * dwlopt,const char * iplace,const char ** argloc,int * argerr)91*4d9fdb46SRobert Mustacchi dwoptnamematches(
92*4d9fdb46SRobert Mustacchi const struct dwoption *dwlopt,
93*4d9fdb46SRobert Mustacchi const char *iplace,
94*4d9fdb46SRobert Mustacchi const char **argloc,
95*4d9fdb46SRobert Mustacchi int *argerr)
96*4d9fdb46SRobert Mustacchi {
97*4d9fdb46SRobert Mustacchi
98*4d9fdb46SRobert Mustacchi const char *eq = 0;
99*4d9fdb46SRobert Mustacchi size_t namelen = 0;
100*4d9fdb46SRobert Mustacchi size_t arglen = 0;
101*4d9fdb46SRobert Mustacchi int d = 0;
102*4d9fdb46SRobert Mustacchi
103*4d9fdb46SRobert Mustacchi for(eq = iplace; *eq; ++eq) {
104*4d9fdb46SRobert Mustacchi if (*eq != '=') {
105*4d9fdb46SRobert Mustacchi continue;
106*4d9fdb46SRobert Mustacchi }
107*4d9fdb46SRobert Mustacchi /* Found =, arg should follow */
108*4d9fdb46SRobert Mustacchi namelen = (eq - iplace);
109*4d9fdb46SRobert Mustacchi if (namelen != (unsigned)strlen(dwlopt->name)) {
110*4d9fdb46SRobert Mustacchi return FALSE;
111*4d9fdb46SRobert Mustacchi }
112*4d9fdb46SRobert Mustacchi eq++;
113*4d9fdb46SRobert Mustacchi arglen = strlen(eq);
114*4d9fdb46SRobert Mustacchi break;
115*4d9fdb46SRobert Mustacchi }
116*4d9fdb46SRobert Mustacchi if (namelen) {
117*4d9fdb46SRobert Mustacchi d = strncmp(iplace,dwlopt->name,namelen);
118*4d9fdb46SRobert Mustacchi if (d) {
119*4d9fdb46SRobert Mustacchi return FALSE;
120*4d9fdb46SRobert Mustacchi }
121*4d9fdb46SRobert Mustacchi if (dwlopt->has_arg == 0) {
122*4d9fdb46SRobert Mustacchi *argerr = TRUE;
123*4d9fdb46SRobert Mustacchi return TRUE;
124*4d9fdb46SRobert Mustacchi }
125*4d9fdb46SRobert Mustacchi if (arglen) {
126*4d9fdb46SRobert Mustacchi /* Discarding const, avoiding warning.
127*4d9fdb46SRobert Mustacchi Data is in user space, so this is ok. */
128*4d9fdb46SRobert Mustacchi dwoptarg = (char *)eq;
129*4d9fdb46SRobert Mustacchi *argloc = (const char *)eq;
130*4d9fdb46SRobert Mustacchi } else {
131*4d9fdb46SRobert Mustacchi /* Has arg = but arg is empty. */
132*4d9fdb46SRobert Mustacchi dwoptarg = 0;
133*4d9fdb46SRobert Mustacchi }
134*4d9fdb46SRobert Mustacchi return TRUE;
135*4d9fdb46SRobert Mustacchi } else {
136*4d9fdb46SRobert Mustacchi d = strcmp(iplace,dwlopt->name);
137*4d9fdb46SRobert Mustacchi if (d) {
138*4d9fdb46SRobert Mustacchi return FALSE;
139*4d9fdb46SRobert Mustacchi }
140*4d9fdb46SRobert Mustacchi if (dwlopt->has_arg == 1) {
141*4d9fdb46SRobert Mustacchi *argerr = TRUE;
142*4d9fdb46SRobert Mustacchi return TRUE;
143*4d9fdb46SRobert Mustacchi }
144*4d9fdb46SRobert Mustacchi dwoptarg = 0;
145*4d9fdb46SRobert Mustacchi return TRUE;
146*4d9fdb46SRobert Mustacchi }
147*4d9fdb46SRobert Mustacchi }
148*4d9fdb46SRobert Mustacchi
149*4d9fdb46SRobert Mustacchi
150*4d9fdb46SRobert Mustacchi
151*4d9fdb46SRobert Mustacchi /* dwgetopt_long
152*4d9fdb46SRobert Mustacchi A reimplemenation of a portion of
153*4d9fdb46SRobert Mustacchi the getopt(3) GNU/Linux getopt_long().
154*4d9fdb46SRobert Mustacchi See dwgetopt.h for more details.
155*4d9fdb46SRobert Mustacchi */
dwgetopt_long(int nargc,char * const nargv[],const char * ostr,const struct dwoption * longopts,int * longindex)156*4d9fdb46SRobert Mustacchi int dwgetopt_long(int nargc, char *const nargv[],
157*4d9fdb46SRobert Mustacchi const char *ostr,
158*4d9fdb46SRobert Mustacchi const struct dwoption* longopts,
159*4d9fdb46SRobert Mustacchi int *longindex)
160*4d9fdb46SRobert Mustacchi {
161*4d9fdb46SRobert Mustacchi char *lplace = 0;
162*4d9fdb46SRobert Mustacchi if (dwoptreset) {
163*4d9fdb46SRobert Mustacchi /* Not really supported. */
164*4d9fdb46SRobert Mustacchi place = EMSG;
165*4d9fdb46SRobert Mustacchi return (-1);
166*4d9fdb46SRobert Mustacchi }
167*4d9fdb46SRobert Mustacchi if (*place) {
168*4d9fdb46SRobert Mustacchi int v = dwgetopt(nargc,nargv,ostr);
169*4d9fdb46SRobert Mustacchi return v;
170*4d9fdb46SRobert Mustacchi }
171*4d9fdb46SRobert Mustacchi /* Use local lplace in case we need to call getopt()
172*4d9fdb46SRobert Mustacchi just below. */
173*4d9fdb46SRobert Mustacchi lplace = nargv[dwoptind];
174*4d9fdb46SRobert Mustacchi if (dwoptind >= nargc || *lplace++ != '-') {
175*4d9fdb46SRobert Mustacchi /* Argument is absent or is not an option */
176*4d9fdb46SRobert Mustacchi place = EMSG;
177*4d9fdb46SRobert Mustacchi return (-1);
178*4d9fdb46SRobert Mustacchi }
179*4d9fdb46SRobert Mustacchi if (*lplace != '-') {
180*4d9fdb46SRobert Mustacchi /* Notice place not disturbed. */
181*4d9fdb46SRobert Mustacchi int v = dwgetopt(nargc,nargv,ostr);
182*4d9fdb46SRobert Mustacchi return v;
183*4d9fdb46SRobert Mustacchi }
184*4d9fdb46SRobert Mustacchi /* Starts with two dashes.
185*4d9fdb46SRobert Mustacchi Now we set the global place */
186*4d9fdb46SRobert Mustacchi place = lplace+1;
187*4d9fdb46SRobert Mustacchi if (!*place) {
188*4d9fdb46SRobert Mustacchi /* "--" => end of options */
189*4d9fdb46SRobert Mustacchi ++dwoptind;
190*4d9fdb46SRobert Mustacchi place = EMSG;
191*4d9fdb46SRobert Mustacchi return (-1);
192*4d9fdb46SRobert Mustacchi }
193*4d9fdb46SRobert Mustacchi
194*4d9fdb46SRobert Mustacchi /* We think this is a longopt. */
195*4d9fdb46SRobert Mustacchi {
196*4d9fdb46SRobert Mustacchi int lo_num = 0;
197*4d9fdb46SRobert Mustacchi
198*4d9fdb46SRobert Mustacchi for(;;lo_num++) {
199*4d9fdb46SRobert Mustacchi const struct dwoption *dwlopt = longopts +lo_num;
200*4d9fdb46SRobert Mustacchi const char * argloc = 0;
201*4d9fdb46SRobert Mustacchi int argerr = 0;
202*4d9fdb46SRobert Mustacchi int resmatch = 0;
203*4d9fdb46SRobert Mustacchi
204*4d9fdb46SRobert Mustacchi if (!dwlopt->name) {
205*4d9fdb46SRobert Mustacchi dwoptind++;
206*4d9fdb46SRobert Mustacchi (void)fprintf(stderr,
207*4d9fdb46SRobert Mustacchi "%s: invalid long option '--%s'\n",
208*4d9fdb46SRobert Mustacchi nargv[0]?nargv[0]:"",
209*4d9fdb46SRobert Mustacchi place);
210*4d9fdb46SRobert Mustacchi /* Leave longindex unchanged. */
211*4d9fdb46SRobert Mustacchi place = EMSG;
212*4d9fdb46SRobert Mustacchi return (BADCH);
213*4d9fdb46SRobert Mustacchi }
214*4d9fdb46SRobert Mustacchi resmatch= dwoptnamematches(dwlopt,place,
215*4d9fdb46SRobert Mustacchi &argloc,&argerr);
216*4d9fdb46SRobert Mustacchi if (resmatch) {
217*4d9fdb46SRobert Mustacchi dwoptarg = 0;
218*4d9fdb46SRobert Mustacchi if (argloc) {
219*4d9fdb46SRobert Mustacchi /* Must drop const here. Ugh. */
220*4d9fdb46SRobert Mustacchi dwoptarg = (char *)argloc;
221*4d9fdb46SRobert Mustacchi }
222*4d9fdb46SRobert Mustacchi }
223*4d9fdb46SRobert Mustacchi if (argerr) {
224*4d9fdb46SRobert Mustacchi /* resmatch == TRUE
225*4d9fdb46SRobert Mustacchi
226*4d9fdb46SRobert Mustacchi arg option missing if required, present
227*4d9fdb46SRobert Mustacchi but not allowed.
228*4d9fdb46SRobert Mustacchi GNU Behavior not well documented.
229*4d9fdb46SRobert Mustacchi Had to experiment.
230*4d9fdb46SRobert Mustacchi
231*4d9fdb46SRobert Mustacchi if argument-not-allowed, and we have one,
232*4d9fdb46SRobert Mustacchi do ???
233*4d9fdb46SRobert Mustacchi
234*4d9fdb46SRobert Mustacchi If argument-required,
235*4d9fdb46SRobert Mustacchi then here GNU
236*4d9fdb46SRobert Mustacchi would take the next argv as the argument.
237*4d9fdb46SRobert Mustacchi we are not currently doing that. */
238*4d9fdb46SRobert Mustacchi /**longindex = lo_num; */
239*4d9fdb46SRobert Mustacchi if (dwlopt->has_arg) {
240*4d9fdb46SRobert Mustacchi /* Missing required arg, this does not
241*4d9fdb46SRobert Mustacchi match GNU getopt_long behavior
242*4d9fdb46SRobert Mustacchi of taking next argv as the arg value.
243*4d9fdb46SRobert Mustacchi and thus making getopt_long succeed. */
244*4d9fdb46SRobert Mustacchi (void)fprintf(stderr,
245*4d9fdb46SRobert Mustacchi "%s: missing required long option argument '--%s'\n",
246*4d9fdb46SRobert Mustacchi nargv[0]?nargv[0]:"",
247*4d9fdb46SRobert Mustacchi place);
248*4d9fdb46SRobert Mustacchi } else {
249*4d9fdb46SRobert Mustacchi /* has arg but should not */
250*4d9fdb46SRobert Mustacchi (void)fprintf(stderr,
251*4d9fdb46SRobert Mustacchi "%s: option '--%s' does not allow an argument\n",
252*4d9fdb46SRobert Mustacchi nargv[0]?nargv[0]:"",
253*4d9fdb46SRobert Mustacchi dwlopt->name);
254*4d9fdb46SRobert Mustacchi }
255*4d9fdb46SRobert Mustacchi dwoptind++;
256*4d9fdb46SRobert Mustacchi place = EMSG;
257*4d9fdb46SRobert Mustacchi return (BADCH);
258*4d9fdb46SRobert Mustacchi }
259*4d9fdb46SRobert Mustacchi if (resmatch) {
260*4d9fdb46SRobert Mustacchi *longindex = lo_num;
261*4d9fdb46SRobert Mustacchi place = EMSG;
262*4d9fdb46SRobert Mustacchi dwoptind++;
263*4d9fdb46SRobert Mustacchi return dwlopt->val;
264*4d9fdb46SRobert Mustacchi }
265*4d9fdb46SRobert Mustacchi }
266*4d9fdb46SRobert Mustacchi /* Can never get here */
267*4d9fdb46SRobert Mustacchi place = EMSG;
268*4d9fdb46SRobert Mustacchi dwoptind++;
269*4d9fdb46SRobert Mustacchi return (-1);
270*4d9fdb46SRobert Mustacchi }
271*4d9fdb46SRobert Mustacchi }
272*4d9fdb46SRobert Mustacchi
273*4d9fdb46SRobert Mustacchi /*
274*4d9fdb46SRobert Mustacchi * getopt --
275*4d9fdb46SRobert Mustacchi * Parse argc/argv argument vector.
276*4d9fdb46SRobert Mustacchi * a: means
277*4d9fdb46SRobert Mustacchi * -afoo
278*4d9fdb46SRobert Mustacchi * -a foo
279*4d9fdb46SRobert Mustacchi * and 'foo' is returned in dwoptarg
280*4d9fdb46SRobert Mustacchi * b:: means
281*4d9fdb46SRobert Mustacchi * -b
282*4d9fdb46SRobert Mustacchi * and dwoptarg is null
283*4d9fdb46SRobert Mustacchi * -bother
284*4d9fdb46SRobert Mustacchi * and dwoptarg is 'other'
285*4d9fdb46SRobert Mustacchi */
286*4d9fdb46SRobert Mustacchi int
dwgetopt(int nargc,char * const nargv[],const char * ostr)287*4d9fdb46SRobert Mustacchi dwgetopt(int nargc, char * const nargv[], const char *ostr)
288*4d9fdb46SRobert Mustacchi {
289*4d9fdb46SRobert Mustacchi char *oli; /* option letter list index */
290*4d9fdb46SRobert Mustacchi
291*4d9fdb46SRobert Mustacchi if (dwoptreset || *place == 0) { /* update scanning pointer */
292*4d9fdb46SRobert Mustacchi dwoptreset = 0;
293*4d9fdb46SRobert Mustacchi place = nargv[dwoptind];
294*4d9fdb46SRobert Mustacchi
295*4d9fdb46SRobert Mustacchi if (dwoptind >= nargc || *place++ != '-') {
296*4d9fdb46SRobert Mustacchi /* Argument is absent or is not an option */
297*4d9fdb46SRobert Mustacchi place = EMSG;
298*4d9fdb46SRobert Mustacchi return (-1);
299*4d9fdb46SRobert Mustacchi }
300*4d9fdb46SRobert Mustacchi dwoptopt = *place++;
301*4d9fdb46SRobert Mustacchi if (dwoptopt == '-' && *place == 0) {
302*4d9fdb46SRobert Mustacchi /* "--" => end of options */
303*4d9fdb46SRobert Mustacchi ++dwoptind;
304*4d9fdb46SRobert Mustacchi place = EMSG;
305*4d9fdb46SRobert Mustacchi return (-1);
306*4d9fdb46SRobert Mustacchi }
307*4d9fdb46SRobert Mustacchi if (dwoptopt == 0) {
308*4d9fdb46SRobert Mustacchi /* Solitary '-', treat as a '-' option
309*4d9fdb46SRobert Mustacchi if the program (eg su) is looking for it. */
310*4d9fdb46SRobert Mustacchi place = EMSG;
311*4d9fdb46SRobert Mustacchi if (strchr(ostr, '-') == NULL) {
312*4d9fdb46SRobert Mustacchi return -1;
313*4d9fdb46SRobert Mustacchi }
314*4d9fdb46SRobert Mustacchi dwoptopt = '-';
315*4d9fdb46SRobert Mustacchi }
316*4d9fdb46SRobert Mustacchi } else {
317*4d9fdb46SRobert Mustacchi dwoptopt = *place++;
318*4d9fdb46SRobert Mustacchi }
319*4d9fdb46SRobert Mustacchi /* See if option letter is one the caller wanted... */
320*4d9fdb46SRobert Mustacchi if (dwoptopt == ':' || (oli = strchr(ostr, dwoptopt)) == NULL) {
321*4d9fdb46SRobert Mustacchi if (*place == 0) {
322*4d9fdb46SRobert Mustacchi ++dwoptind;
323*4d9fdb46SRobert Mustacchi }
324*4d9fdb46SRobert Mustacchi if (dwopterr && *ostr != ':') {
325*4d9fdb46SRobert Mustacchi (void)fprintf(stderr,
326*4d9fdb46SRobert Mustacchi "%s: invalid option -- '%c'\n",
327*4d9fdb46SRobert Mustacchi nargv[0]?nargv[0]:"",
328*4d9fdb46SRobert Mustacchi dwoptopt);
329*4d9fdb46SRobert Mustacchi }
330*4d9fdb46SRobert Mustacchi return (BADCH);
331*4d9fdb46SRobert Mustacchi }
332*4d9fdb46SRobert Mustacchi
333*4d9fdb46SRobert Mustacchi /* Does this option need an argument? */
334*4d9fdb46SRobert Mustacchi if (oli[1] != ':') {
335*4d9fdb46SRobert Mustacchi /* don't need argument */
336*4d9fdb46SRobert Mustacchi dwoptarg = NULL;
337*4d9fdb46SRobert Mustacchi if (*place == 0) {
338*4d9fdb46SRobert Mustacchi ++dwoptind;
339*4d9fdb46SRobert Mustacchi }
340*4d9fdb46SRobert Mustacchi } else {
341*4d9fdb46SRobert Mustacchi int reqnextarg = 1;
342*4d9fdb46SRobert Mustacchi if (oli[1] && (oli[2] == ':')) {
343*4d9fdb46SRobert Mustacchi /* Pair of :: means special treatment of dwoptarg */
344*4d9fdb46SRobert Mustacchi reqnextarg = 0;
345*4d9fdb46SRobert Mustacchi }
346*4d9fdb46SRobert Mustacchi /* Option-argument is either the rest of this argument or the
347*4d9fdb46SRobert Mustacchi entire next argument. */
348*4d9fdb46SRobert Mustacchi if (*place ) {
349*4d9fdb46SRobert Mustacchi /* Whether : or :: */
350*4d9fdb46SRobert Mustacchi dwoptarg = STRIP_OFF_CONSTNESS(place);
351*4d9fdb46SRobert Mustacchi } else if (reqnextarg) {
352*4d9fdb46SRobert Mustacchi /* ! *place */
353*4d9fdb46SRobert Mustacchi if (nargc > (++dwoptind)) {
354*4d9fdb46SRobert Mustacchi dwoptarg = nargv[dwoptind];
355*4d9fdb46SRobert Mustacchi } else {
356*4d9fdb46SRobert Mustacchi place=EMSG;
357*4d9fdb46SRobert Mustacchi /* Next arg required, but is missing */
358*4d9fdb46SRobert Mustacchi if (*ostr == ':') {
359*4d9fdb46SRobert Mustacchi /* Leading : in ostr calls for BADARG return. */
360*4d9fdb46SRobert Mustacchi return (BADARG);
361*4d9fdb46SRobert Mustacchi }
362*4d9fdb46SRobert Mustacchi if (dwopterr) {
363*4d9fdb46SRobert Mustacchi (void)fprintf(stderr,
364*4d9fdb46SRobert Mustacchi "%s: option requires an argument. -- '%c'\n",
365*4d9fdb46SRobert Mustacchi nargv[0]?nargv[0]:"",
366*4d9fdb46SRobert Mustacchi dwoptopt);
367*4d9fdb46SRobert Mustacchi }
368*4d9fdb46SRobert Mustacchi return (BADCH);
369*4d9fdb46SRobert Mustacchi }
370*4d9fdb46SRobert Mustacchi } else {
371*4d9fdb46SRobert Mustacchi /* ! *place */
372*4d9fdb46SRobert Mustacchi /* The key part of :: treatment. */
373*4d9fdb46SRobert Mustacchi dwoptarg = NULL;
374*4d9fdb46SRobert Mustacchi }
375*4d9fdb46SRobert Mustacchi place = EMSG;
376*4d9fdb46SRobert Mustacchi ++dwoptind;
377*4d9fdb46SRobert Mustacchi }
378*4d9fdb46SRobert Mustacchi return (dwoptopt); /* return option letter */
379*4d9fdb46SRobert Mustacchi }
380