1d4afb5ceSopenharmony_ci
2d4afb5ceSopenharmony_ci/*
3d4afb5ceSopenharmony_ci * Copyright (c) 1987, 1993, 1994, 1996
4d4afb5ceSopenharmony_ci *	The Regents of the University of California.  All rights reserved.
5d4afb5ceSopenharmony_ci *
6d4afb5ceSopenharmony_ci * Redistribution and use in source and binary forms, with or without
7d4afb5ceSopenharmony_ci * modification, are permitted provided that the following conditions
8d4afb5ceSopenharmony_ci * are met:
9d4afb5ceSopenharmony_ci * 1. Redistributions of source code must retain the above copyright
10d4afb5ceSopenharmony_ci *    notice, this list of conditions and the following disclaimer.
11d4afb5ceSopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright
12d4afb5ceSopenharmony_ci *    notice, this list of conditions and the following disclaimer in the
13d4afb5ceSopenharmony_ci *    documentation and/or other materials provided with the distribution.
14d4afb5ceSopenharmony_ci * 3. All advertising materials mentioning features or use of this software
15d4afb5ceSopenharmony_ci *    must display the following acknowledgement:
16d4afb5ceSopenharmony_ci *	This product includes software developed by the University of
17d4afb5ceSopenharmony_ci *	California, Berkeley and its contributors.
18d4afb5ceSopenharmony_ci * 4. Neither the name of the University nor the names of its contributors
19d4afb5ceSopenharmony_ci *    may be used to endorse or promote products derived from this software
20d4afb5ceSopenharmony_ci *    without specific prior written permission.
21d4afb5ceSopenharmony_ci *
22d4afb5ceSopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23d4afb5ceSopenharmony_ci * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24d4afb5ceSopenharmony_ci * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25d4afb5ceSopenharmony_ci * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26d4afb5ceSopenharmony_ci * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27d4afb5ceSopenharmony_ci * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28d4afb5ceSopenharmony_ci * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29d4afb5ceSopenharmony_ci * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30d4afb5ceSopenharmony_ci * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31d4afb5ceSopenharmony_ci * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32d4afb5ceSopenharmony_ci * SUCH DAMAGE.
33d4afb5ceSopenharmony_ci */
34d4afb5ceSopenharmony_ci#include <assert.h>
35d4afb5ceSopenharmony_ci#include <errno.h>
36d4afb5ceSopenharmony_ci#include <stdio.h>
37d4afb5ceSopenharmony_ci#include <stdlib.h>
38d4afb5ceSopenharmony_ci#include <string.h>
39d4afb5ceSopenharmony_ci#include "getopt.h"
40d4afb5ceSopenharmony_ci
41d4afb5ceSopenharmony_ci#define lws_ptr_diff(head, tail) \
42d4afb5ceSopenharmony_ci			((int)((char *)(head) - (char *)(tail)))
43d4afb5ceSopenharmony_ci
44d4afb5ceSopenharmony_ciextern int	  opterr;	/* if error message should be printed */
45d4afb5ceSopenharmony_ciextern int	  optind;	/* index into parent argv vector */
46d4afb5ceSopenharmony_ciextern int	  optopt;	/* character checked for validity */
47d4afb5ceSopenharmony_ciextern int	  optreset;	/* reset getopt */
48d4afb5ceSopenharmony_ciextern char *optarg;	/* argument associated with option */
49d4afb5ceSopenharmony_ci
50d4afb5ceSopenharmony_ci#define __P(x) x
51d4afb5ceSopenharmony_ci#define _DIAGASSERT(x) assert(x)
52d4afb5ceSopenharmony_ci
53d4afb5ceSopenharmony_cistatic char * __progname __P((char *));
54d4afb5ceSopenharmony_ciint getopt_internal __P((int, char * const *, const char *));
55d4afb5ceSopenharmony_ci
56d4afb5ceSopenharmony_cistatic char *
57d4afb5ceSopenharmony_ci__progname(nargv0)
58d4afb5ceSopenharmony_ci	char * nargv0;
59d4afb5ceSopenharmony_ci{
60d4afb5ceSopenharmony_ci	char * tmp;
61d4afb5ceSopenharmony_ci
62d4afb5ceSopenharmony_ci	_DIAGASSERT(nargv0 != NULL);
63d4afb5ceSopenharmony_ci
64d4afb5ceSopenharmony_ci	tmp = strrchr(nargv0, '/');
65d4afb5ceSopenharmony_ci	if (tmp)
66d4afb5ceSopenharmony_ci		tmp++;
67d4afb5ceSopenharmony_ci	else
68d4afb5ceSopenharmony_ci		tmp = nargv0;
69d4afb5ceSopenharmony_ci	return(tmp);
70d4afb5ceSopenharmony_ci}
71d4afb5ceSopenharmony_ci
72d4afb5ceSopenharmony_ci#define	BADCH	(int)'?'
73d4afb5ceSopenharmony_ci#define	BADARG	(int)':'
74d4afb5ceSopenharmony_ci#define	EMSG	""
75d4afb5ceSopenharmony_ci
76d4afb5ceSopenharmony_ci/*
77d4afb5ceSopenharmony_ci * getopt --
78d4afb5ceSopenharmony_ci *	Parse argc/argv argument vector.
79d4afb5ceSopenharmony_ci */
80d4afb5ceSopenharmony_ciint
81d4afb5ceSopenharmony_cigetopt_internal(nargc, nargv, ostr)
82d4afb5ceSopenharmony_ci	int nargc;
83d4afb5ceSopenharmony_ci	char * const *nargv;
84d4afb5ceSopenharmony_ci	const char *ostr;
85d4afb5ceSopenharmony_ci{
86d4afb5ceSopenharmony_ci	static char *place = EMSG;		/* option letter processing */
87d4afb5ceSopenharmony_ci	char *oli;				/* option letter list index */
88d4afb5ceSopenharmony_ci
89d4afb5ceSopenharmony_ci	_DIAGASSERT(nargv != NULL);
90d4afb5ceSopenharmony_ci	_DIAGASSERT(ostr != NULL);
91d4afb5ceSopenharmony_ci
92d4afb5ceSopenharmony_ci	if (optreset || !*place) {		/* update scanning pointer */
93d4afb5ceSopenharmony_ci		optreset = 0;
94d4afb5ceSopenharmony_ci		if (optind >= nargc || *(place = nargv[optind]) != '-') {
95d4afb5ceSopenharmony_ci			place = EMSG;
96d4afb5ceSopenharmony_ci			return (-1);
97d4afb5ceSopenharmony_ci		}
98d4afb5ceSopenharmony_ci		if (place[1] && *++place == '-') {	/* found "--" */
99d4afb5ceSopenharmony_ci			/* ++optind; */
100d4afb5ceSopenharmony_ci			place = EMSG;
101d4afb5ceSopenharmony_ci			return (-2);
102d4afb5ceSopenharmony_ci		}
103d4afb5ceSopenharmony_ci	}					/* option letter okay? */
104d4afb5ceSopenharmony_ci	if ((optopt = (int)*place++) == (int)':' ||
105d4afb5ceSopenharmony_ci	    !(oli = strchr(ostr, optopt))) {
106d4afb5ceSopenharmony_ci		/*
107d4afb5ceSopenharmony_ci		 * if the user didn't specify '-' as an option,
108d4afb5ceSopenharmony_ci		 * assume it means -1.
109d4afb5ceSopenharmony_ci		 */
110d4afb5ceSopenharmony_ci		if (optopt == (int)'-')
111d4afb5ceSopenharmony_ci			return (-1);
112d4afb5ceSopenharmony_ci		if (!*place)
113d4afb5ceSopenharmony_ci			++optind;
114d4afb5ceSopenharmony_ci		if (opterr && *ostr != ':')
115d4afb5ceSopenharmony_ci			(void)fprintf(stderr,
116d4afb5ceSopenharmony_ci			    "%s: illegal option -- %c\n", __progname(nargv[0]), optopt);
117d4afb5ceSopenharmony_ci		return (BADCH);
118d4afb5ceSopenharmony_ci	}
119d4afb5ceSopenharmony_ci	if (*++oli != ':') {			/* don't need argument */
120d4afb5ceSopenharmony_ci		optarg = NULL;
121d4afb5ceSopenharmony_ci		if (!*place)
122d4afb5ceSopenharmony_ci			++optind;
123d4afb5ceSopenharmony_ci	} else {				/* need an argument */
124d4afb5ceSopenharmony_ci		if (*place)			/* no white space */
125d4afb5ceSopenharmony_ci			optarg = place;
126d4afb5ceSopenharmony_ci		else if (nargc <= ++optind) {	/* no arg */
127d4afb5ceSopenharmony_ci			place = EMSG;
128d4afb5ceSopenharmony_ci			if ((opterr) && (*ostr != ':'))
129d4afb5ceSopenharmony_ci				(void)fprintf(stderr,
130d4afb5ceSopenharmony_ci				    "%s: option requires an argument -- %c\n",
131d4afb5ceSopenharmony_ci				    __progname(nargv[0]), optopt);
132d4afb5ceSopenharmony_ci			return (BADARG);
133d4afb5ceSopenharmony_ci		} else				/* white space */
134d4afb5ceSopenharmony_ci			optarg = nargv[optind];
135d4afb5ceSopenharmony_ci		place = EMSG;
136d4afb5ceSopenharmony_ci		++optind;
137d4afb5ceSopenharmony_ci	}
138d4afb5ceSopenharmony_ci	return (optopt);			/* dump back option letter */
139d4afb5ceSopenharmony_ci}
140d4afb5ceSopenharmony_ci
141d4afb5ceSopenharmony_ci#if 0
142d4afb5ceSopenharmony_ci/*
143d4afb5ceSopenharmony_ci * getopt --
144d4afb5ceSopenharmony_ci *	Parse argc/argv argument vector.
145d4afb5ceSopenharmony_ci */
146d4afb5ceSopenharmony_ciint
147d4afb5ceSopenharmony_cigetopt2(nargc, nargv, ostr)
148d4afb5ceSopenharmony_ci	int nargc;
149d4afb5ceSopenharmony_ci	char * const *nargv;
150d4afb5ceSopenharmony_ci	const char *ostr;
151d4afb5ceSopenharmony_ci{
152d4afb5ceSopenharmony_ci	int retval;
153d4afb5ceSopenharmony_ci
154d4afb5ceSopenharmony_ci	if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) {
155d4afb5ceSopenharmony_ci		retval = -1;
156d4afb5ceSopenharmony_ci		++optind;
157d4afb5ceSopenharmony_ci	}
158d4afb5ceSopenharmony_ci	return(retval);
159d4afb5ceSopenharmony_ci}
160d4afb5ceSopenharmony_ci#endif
161d4afb5ceSopenharmony_ci
162d4afb5ceSopenharmony_ci/*
163d4afb5ceSopenharmony_ci * getopt_long --
164d4afb5ceSopenharmony_ci *	Parse argc/argv argument vector.
165d4afb5ceSopenharmony_ci */
166d4afb5ceSopenharmony_ciint
167d4afb5ceSopenharmony_cigetopt_long(nargc, nargv, options, long_options, index)
168d4afb5ceSopenharmony_ci	int nargc;
169d4afb5ceSopenharmony_ci	char ** nargv;
170d4afb5ceSopenharmony_ci	char * options;
171d4afb5ceSopenharmony_ci	struct option * long_options;
172d4afb5ceSopenharmony_ci	int * index;
173d4afb5ceSopenharmony_ci{
174d4afb5ceSopenharmony_ci	int retval;
175d4afb5ceSopenharmony_ci
176d4afb5ceSopenharmony_ci	_DIAGASSERT(nargv != NULL);
177d4afb5ceSopenharmony_ci	_DIAGASSERT(options != NULL);
178d4afb5ceSopenharmony_ci	_DIAGASSERT(long_options != NULL);
179d4afb5ceSopenharmony_ci	/* index may be NULL */
180d4afb5ceSopenharmony_ci
181d4afb5ceSopenharmony_ci	if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
182d4afb5ceSopenharmony_ci		char *current_argv = nargv[optind++] + 2, *has_equal;
183d4afb5ceSopenharmony_ci		int i, current_argv_len, match = -1;
184d4afb5ceSopenharmony_ci
185d4afb5ceSopenharmony_ci		if (*current_argv == '\0') {
186d4afb5ceSopenharmony_ci			return(-1);
187d4afb5ceSopenharmony_ci		}
188d4afb5ceSopenharmony_ci		if ((has_equal = strchr(current_argv, '=')) != NULL) {
189d4afb5ceSopenharmony_ci			current_argv_len = lws_ptr_diff(has_equal, current_argv);
190d4afb5ceSopenharmony_ci			has_equal++;
191d4afb5ceSopenharmony_ci		} else
192d4afb5ceSopenharmony_ci			current_argv_len = (int)strlen(current_argv);
193d4afb5ceSopenharmony_ci
194d4afb5ceSopenharmony_ci		for (i = 0; long_options[i].name; i++) {
195d4afb5ceSopenharmony_ci			if (strncmp(current_argv, long_options[i].name, current_argv_len))
196d4afb5ceSopenharmony_ci				continue;
197d4afb5ceSopenharmony_ci
198d4afb5ceSopenharmony_ci			if (strlen(long_options[i].name) == (unsigned)current_argv_len) {
199d4afb5ceSopenharmony_ci				match = i;
200d4afb5ceSopenharmony_ci				break;
201d4afb5ceSopenharmony_ci			}
202d4afb5ceSopenharmony_ci			if (match == -1)
203d4afb5ceSopenharmony_ci				match = i;
204d4afb5ceSopenharmony_ci		}
205d4afb5ceSopenharmony_ci		if (match != -1) {
206d4afb5ceSopenharmony_ci			if (long_options[match].has_arg == required_argument ||
207d4afb5ceSopenharmony_ci			    long_options[match].has_arg == optional_argument) {
208d4afb5ceSopenharmony_ci				if (has_equal)
209d4afb5ceSopenharmony_ci					optarg = has_equal;
210d4afb5ceSopenharmony_ci				else
211d4afb5ceSopenharmony_ci					optarg = nargv[optind++];
212d4afb5ceSopenharmony_ci			}
213d4afb5ceSopenharmony_ci			if ((long_options[match].has_arg == required_argument)
214d4afb5ceSopenharmony_ci			    && (optarg == NULL)) {
215d4afb5ceSopenharmony_ci				/*
216d4afb5ceSopenharmony_ci				 * Missing argument, leading :
217d4afb5ceSopenharmony_ci				 * indicates no error should be generated
218d4afb5ceSopenharmony_ci				 */
219d4afb5ceSopenharmony_ci				if ((opterr) && (*options != ':'))
220d4afb5ceSopenharmony_ci					(void)fprintf(stderr,
221d4afb5ceSopenharmony_ci				      "%s: option requires an argument -- %s\n",
222d4afb5ceSopenharmony_ci				      __progname(nargv[0]), current_argv);
223d4afb5ceSopenharmony_ci				return (BADARG);
224d4afb5ceSopenharmony_ci			}
225d4afb5ceSopenharmony_ci		} else { /* No matching argument */
226d4afb5ceSopenharmony_ci			if ((opterr) && (*options != ':'))
227d4afb5ceSopenharmony_ci				(void)fprintf(stderr,
228d4afb5ceSopenharmony_ci				    "%s: illegal option -- %s\n", __progname(nargv[0]), current_argv);
229d4afb5ceSopenharmony_ci			return (BADCH);
230d4afb5ceSopenharmony_ci		}
231d4afb5ceSopenharmony_ci		if (long_options[match].flag) {
232d4afb5ceSopenharmony_ci			*long_options[match].flag = long_options[match].val;
233d4afb5ceSopenharmony_ci			retval = 0;
234d4afb5ceSopenharmony_ci		} else
235d4afb5ceSopenharmony_ci			retval = long_options[match].val;
236d4afb5ceSopenharmony_ci		if (index)
237d4afb5ceSopenharmony_ci			*index = match;
238d4afb5ceSopenharmony_ci	}
239d4afb5ceSopenharmony_ci	return(retval);
240d4afb5ceSopenharmony_ci}
241