11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$OpenBSD: getopt_long.c,v 1.20 2005/10/25 15:49:37 jmc Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $	*/
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies.
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Sponsored in part by the Defense Advanced Research Projects
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Agency (DARPA) and Air Force Research Laboratory, Air Force
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Materiel Command, USAF, under agreement number F39502-99-1-0512.
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*-
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2000 The NetBSD Foundation, Inc.
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved.
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This code is derived from software contributed to The NetBSD Foundation
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * by Dieter Baron and Thomas Klausner.
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    documentation and/or other materials provided with the distribution.
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. All advertising materials mentioning features or use of this software
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    must display the following acknowledgement:
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *        This product includes software developed by the NetBSD
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *        Foundation, Inc. and its contributors.
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 4. Neither the name of The NetBSD Foundation nor the names of its
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    contributors may be used to endorse or promote products derived
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    from this software without specific prior written permission.
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * POSSIBILITY OF SUCH DAMAGE.
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <err.h>
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <getopt.h>
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	REPLACE_GETOPT		/* use this getopt as the system getopt(3) */
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef REPLACE_GETOPT
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint	opterr = 1;		/* if error message should be printed */
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint	optind = 1;		/* index into parent argv vector */
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint	optopt = '?';		/* character checked for validity */
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectchar    *optarg;		/* argument associated with option */
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint	optreset;		/* reset getopt */
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define PRINT_ERROR	((opterr) && (*options != ':'))
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define FLAG_PERMUTE	0x01	/* permute non-options to the end of argv */
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define FLAG_ALLARGS	0x02	/* treat non-options as args to option "-1" */
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define FLAG_LONGONLY	0x04	/* operate as getopt_long_only */
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* return values */
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	BADCH		(int)'?'
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	BADARG		((*options == ':') ? (int)':' : (int)'?')
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	INORDER 	(int)1
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	EMSG		""
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int getopt_internal(int, char * const *, const char *,
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			   const struct option *, int *, int);
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int parse_long_options(char * const *, const char *,
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			      const struct option *, int *, int);
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int gcd(int, int);
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void permute_args(int, int, int, char * const *);
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic char *place = EMSG; /* option letter processing */
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* XXX: set optreset to 1 rather than these two */
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int nonopt_start = -1; /* first non option argument (for permute) */
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int nonopt_end = -1;   /* first option after non options (for permute) */
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Error messages */
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char recargchar[] = "option requires an argument -- %c";
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char recargstring[] = "option requires an argument -- %s";
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char ambig[] = "ambiguous option -- %.*s";
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char noarg[] = "option doesn't take an argument -- %.*s";
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char illoptchar[] = "unknown option -- %c";
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char illoptstring[] = "unknown option -- %s";
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Compute the greatest common divisor of a and b.
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgcd(int a, int b)
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int c;
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	c = a % b;
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	while (c != 0) {
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		a = b;
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		b = c;
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		c = a % b;
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (b);
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Exchange the block from nonopt_start to nonopt_end with the block
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * from nonopt_end to opt_end (keeping the same order of arguments
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * in each block).
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectpermute_args(int panonopt_start, int panonopt_end, int opt_end,
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char * const *nargv)
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *swap;
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * compute lengths of blocks and number and size of cycles
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	nnonopts = panonopt_end - panonopt_start;
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	nopts = opt_end - panonopt_end;
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ncycle = gcd(nnonopts, nopts);
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cyclelen = (opt_end - panonopt_start) / ncycle;
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (i = 0; i < ncycle; i++) {
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		cstart = panonopt_end+i;
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		pos = cstart;
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (j = 0; j < cyclelen; j++) {
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (pos >= panonopt_end)
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				pos -= nnonopts;
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				pos += nopts;
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			swap = nargv[pos];
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* LINTED const cast */
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			((char **) nargv)[pos] = nargv[cstart];
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* LINTED const cast */
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			((char **)nargv)[cstart] = swap;
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * parse_long_options --
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	Parse long options in argc/argv argument vector.
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Returns -1 if short_too is set and the option does not match long_options.
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectparse_long_options(char * const *nargv, const char *options,
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const struct option *long_options, int *idx, int short_too)
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *current_argv, *has_equal;
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	size_t current_argv_len;
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int i, match;
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	current_argv = place;
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	match = -1;
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	optind++;
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((has_equal = strchr(current_argv, '=')) != NULL) {
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* argument found (--option=arg) */
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		current_argv_len = has_equal - current_argv;
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		has_equal++;
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		current_argv_len = strlen(current_argv);
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (i = 0; long_options[i].name; i++) {
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* find matching long option */
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (strncmp(current_argv, long_options[i].name,
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    current_argv_len))
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (strlen(long_options[i].name) == current_argv_len) {
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* exact match */
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			match = i;
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * If this is a known short option, don't allow
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * a partial match of a single character.
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (short_too && current_argv_len == 1)
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			continue;
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (match == -1)	/* partial match */
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			match = i;
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else {
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* ambiguous abbreviation */
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (PRINT_ERROR)
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fprintf(stderr,
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        ambig, (int)current_argv_len,
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        current_argv);
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			optopt = 0;
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (BADCH);
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (match != -1) {		/* option found */
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (long_options[match].has_arg == no_argument
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    && has_equal) {
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (PRINT_ERROR)
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fprintf(stderr,
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        noarg, (int)current_argv_len,
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        current_argv);
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * XXX: GNU sets optopt to val regardless of flag
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (long_options[match].flag == NULL)
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optopt = long_options[match].val;
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optopt = 0;
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (BADARG);
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (long_options[match].has_arg == required_argument ||
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    long_options[match].has_arg == optional_argument) {
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (has_equal)
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optarg = has_equal;
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (long_options[match].has_arg ==
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    required_argument) {
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * optional argument doesn't use next nargv
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optarg = nargv[optind++];
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((long_options[match].has_arg == required_argument)
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    && (optarg == NULL)) {
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * Missing argument; leading ':' indicates no error
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * should be generated.
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (PRINT_ERROR)
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fprintf(stderr,
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        recargstring,
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project                        current_argv);
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * XXX: GNU sets optopt to val regardless of flag
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (long_options[match].flag == NULL)
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optopt = long_options[match].val;
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optopt = 0;
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			--optind;
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (BADARG);
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else {			/* unknown option */
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (short_too) {
2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			--optind;
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (PRINT_ERROR)
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			fprintf(stderr, illoptstring, current_argv);
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		optopt = 0;
2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (BADCH);
2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (idx)
2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*idx = match;
2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (long_options[match].flag) {
2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		*long_options[match].flag = long_options[match].val;
2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (0);
2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else
2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (long_options[match].val);
2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * getopt_internal --
2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	Parse argc/argv argument vector.  Called by user level routines.
2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgetopt_internal(int nargc, char * const *nargv, const char *options,
2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const struct option *long_options, int *idx, int flags)
2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char *oli;				/* option letter list index */
2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int optchar, short_too;
2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	static int posixly_correct = -1;
2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (options == NULL)
3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Disable GNU extensions if POSIXLY_CORRECT is set or options
3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * string begins with a '+'.
3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (posixly_correct == -1)
3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (posixly_correct || *options == '+')
3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		flags &= ~FLAG_PERMUTE;
3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else if (*options == '-')
3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		flags |= FLAG_ALLARGS;
3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*options == '+' || *options == '-')
3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		options++;
3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * XXX Some GNU programs (like cvs) set optind to 0 instead of
3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * XXX using optreset.  Work around this braindamage.
3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (optind == 0)
3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		optind = optreset = 1;
3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	optarg = NULL;
3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (optreset)
3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		nonopt_start = nonopt_end = -1;
3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstart:
3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (optreset || !*place) {		/* update scanning pointer */
3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		optreset = 0;
3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (optind >= nargc) {          /* end of argument vector */
3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			place = EMSG;
3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (nonopt_end != -1) {
3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* do permutation, if we have to */
3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				permute_args(nonopt_start, nonopt_end,
3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    optind, nargv);
3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optind -= nonopt_end - nonopt_start;
3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (nonopt_start != -1) {
3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * If we skipped non-options, set optind
3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * to the first of them.
3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optind = nonopt_start;
3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nonopt_start = nonopt_end = -1;
3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*(place = nargv[optind]) != '-' ||
3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    (place[1] == '\0' && strchr(options, '-') == NULL)) {
3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			place = EMSG;		/* found non-option */
3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (flags & FLAG_ALLARGS) {
3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * GNU extension:
3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * return non-option as argument to option 1
3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optarg = nargv[optind++];
3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return (INORDER);
3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (!(flags & FLAG_PERMUTE)) {
3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/*
3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * If no permutation wanted, stop parsing
3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 * at first non-option.
3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				 */
3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return (-1);
3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* do permutation */
3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (nonopt_start == -1)
3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nonopt_start = optind;
3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			else if (nonopt_end != -1) {
3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				permute_args(nonopt_start, nonopt_end,
3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    optind, nargv);
3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nonopt_start = optind -
3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    (nonopt_end - nonopt_start);
3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				nonopt_end = -1;
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			optind++;
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* process next argument */
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto start;
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (nonopt_start != -1 && nonopt_end == -1)
3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nonopt_end = optind;
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * If we have "-" do nothing, if "--" we are done.
3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			optind++;
3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			place = EMSG;
3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * We found an option (--), so if we skipped
3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * non-options, we have to permute.
3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (nonopt_end != -1) {
3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				permute_args(nonopt_start, nonopt_end,
3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				    optind, nargv);
3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optind -= nonopt_end - nonopt_start;
3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nonopt_start = nonopt_end = -1;
3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Check long options if:
4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *  1) we were passed some
4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *  2) the arg is not just "-"
4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *  3) either the arg starts with -- we are getopt_long_only()
4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (long_options != NULL && place != nargv[optind] &&
4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    (*place == '-' || (flags & FLAG_LONGONLY))) {
4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		short_too = 0;
4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*place == '-')
4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			place++;		/* --foo long option */
4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else if (*place != ':' && strchr(options, *place) != NULL)
4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			short_too = 1;		/* could be short option too */
4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		optchar = parse_long_options(nargv, options, long_options,
4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    idx, short_too);
4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (optchar != -1) {
4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			place = EMSG;
4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (optchar);
4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (((optchar = (int)*place++) == (int)':') ||
4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    (optchar == (int)'-' && *place != '\0') ||
4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    (oli = strchr(options, optchar)) == NULL) {
4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * If the user specified "-" and  '-' isn't listed in
4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * options, return -1 (non-option) as per POSIX.
4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Otherwise, it is an unknown option character (or ':').
4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (optchar == (int)'-' && *place == '\0')
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!*place)
4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			++optind;
4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (PRINT_ERROR)
4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			fprintf(stderr, illoptchar, optchar);
4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		optopt = optchar;
4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (BADCH);
4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* -W long-option */
4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*place)			/* no space */
4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* NOTHING */;
4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else if (++optind >= nargc) {	/* no arg */
4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			place = EMSG;
4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (PRINT_ERROR)
4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				fprintf(stderr, recargchar, optchar);
4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			optopt = optchar;
4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (BADARG);
4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} else				/* white space */
4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			place = nargv[optind];
4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		optchar = parse_long_options(nargv, options, long_options,
4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    idx, 0);
4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		place = EMSG;
4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (optchar);
4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (*++oli != ':') {			/* doesn't take argument */
4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (!*place)
4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			++optind;
4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else {				/* takes (optional) argument */
4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		optarg = NULL;
4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (*place)			/* no white space */
4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			optarg = place;
4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* XXX: disable test for :: if PC? (GNU doesn't) */
4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		else if (oli[1] != ':') {	/* arg not optional */
4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (++optind >= nargc) {	/* no arg */
4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				place = EMSG;
4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (PRINT_ERROR)
4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					fprintf(stderr, recargchar, optchar);
4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optopt = optchar;
4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return (BADARG);
4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			} else
4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optarg = nargv[optind];
4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} else if (!(flags & FLAG_PERMUTE)) {
4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * If permutation is disabled, we can accept an
4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * optional arg separated by whitespace so long
4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * as it does not start with a dash (-).
4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (optind + 1 < nargc && *nargv[optind + 1] != '-')
4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				optarg = nargv[++optind];
4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		place = EMSG;
4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		++optind;
4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* dump back option letter */
4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (optchar);
4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef REPLACE_GETOPT
4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * getopt --
4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	Parse argc/argv argument vector.
4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * [eventually this will replace the BSD getopt]
4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgetopt(int nargc, char * const *nargv, const char *options)
4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * We don't pass FLAG_PERMUTE to getopt_internal() since
5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * the BSD getopt(3) (unlike GNU) has never done this.
5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *
5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Furthermore, since many privileged programs call getopt()
5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * before dropping privileges it makes sense to keep things
5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * as simple (and bug-free) as possible.
5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* REPLACE_GETOPT */
5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * getopt_long --
5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	Parse argc/argv argument vector.
5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
5181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgetopt_long(int nargc, char * const *nargv, const char *options,
5191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    const struct option *long_options, int *idx)
5201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
5211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (getopt_internal(nargc, nargv, options, long_options, idx,
5231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    FLAG_PERMUTE));
5241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
5251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
5271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * getopt_long_only --
5281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *	Parse argc/argv argument vector.
5291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
5301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
5311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgetopt_long_only(int nargc, char * const *nargv, const char *options,
5321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project    const struct option *long_options, int *idx)
5331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
5341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (getopt_internal(nargc, nargv, options, long_options, idx,
5361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    FLAG_PERMUTE|FLAG_LONGONLY));
5371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
538