16d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* $OpenBSD: getopt_long.c,v 1.24 2010/07/22 19:31:53 blambert Exp $ */ 26d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* $NetBSD: getopt_long.c,v 1.15 2002/01/31 22:43:40 tv Exp $ */ 36d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 46d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 56d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> 66d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 76d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Permission to use, copy, modify, and distribute this software for any 86d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * purpose with or without fee is hereby granted, provided that the above 96d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * copyright notice and this permission notice appear in all copies. 106d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 116d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 126d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 136d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 146d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 156d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 166d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 176d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 186d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 196d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Sponsored in part by the Defense Advanced Research Projects 206d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Agency (DARPA) and Air Force Research Laboratory, Air Force 216d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Materiel Command, USAF, under agreement number F39502-99-1-0512. 226d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 236d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/*- 246d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Copyright (c) 2000 The NetBSD Foundation, Inc. 256d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * All rights reserved. 266d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 276d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * This code is derived from software contributed to The NetBSD Foundation 286d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * by Dieter Baron and Thomas Klausner. 296d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 306d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Redistribution and use in source and binary forms, with or without 316d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * modification, are permitted provided that the following conditions 326d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * are met: 336d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 1. Redistributions of source code must retain the above copyright 346d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * notice, this list of conditions and the following disclaimer. 356d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 2. Redistributions in binary form must reproduce the above copyright 366d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * notice, this list of conditions and the following disclaimer in the 376d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * documentation and/or other materials provided with the distribution. 386d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 396d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 406d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 416d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 426d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 436d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 446d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 456d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 466d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 476d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 486d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 496d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * POSSIBILITY OF SUCH DAMAGE. 506d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 516d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 526d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#include <errno.h> 536d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#include <getopt.h> 54f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca#include <stdio.h> 556d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#include <stdlib.h> 566d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#include <string.h> 576d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 586d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaint opterr = 1; /* if error message should be printed */ 596d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaint optind = 1; /* index into parent argv vector */ 606d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaint optopt = '?'; /* character checked for validity */ 616d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaint optreset; /* reset getopt */ 626d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecachar *optarg; /* argument associated with option */ 636d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 646d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define PRINT_ERROR ((opterr) && (*options != ':')) 656d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 666d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ 676d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ 686d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ 696d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 706d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* return values */ 716d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define BADCH (int)'?' 726d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define BADARG ((*options == ':') ? (int)':' : (int)'?') 736d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define INORDER (int)1 746d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 756d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca#define EMSG "" 766d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 776d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int getopt_internal(int, char * const *, const char *, 786d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca const struct option *, int *, int); 796d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int parse_long_options(char * const *, const char *, 806d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca const struct option *, int *, int); 816d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int gcd(int, int); 826d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic void permute_args(int, int, int, char * const *); 836d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 846d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic char *place = EMSG; /* option letter processing */ 856d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 866d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* XXX: set optreset to 1 rather than these two */ 876d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int nonopt_start = -1; /* first non option argument (for permute) */ 886d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int nonopt_end = -1; /* first option after non options (for permute) */ 896d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 906d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* Error messages */ 916d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic const char recargchar[] = "option requires an argument -- %c"; 926d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic const char recargstring[] = "option requires an argument -- %s"; 936d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic const char ambig[] = "ambiguous option -- %.*s"; 946d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic const char noarg[] = "option doesn't take an argument -- %.*s"; 956d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic const char illoptchar[] = "unknown option -- %c"; 966d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic const char illoptstring[] = "unknown option -- %s"; 976d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 986d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 996d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Compute the greatest common divisor of a and b. 1006d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 1016d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int 1026d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecagcd(int a, int b) 1036d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca{ 1046d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca int c; 1056d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1066d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca c = a % b; 1076d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca while (c != 0) { 1086d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca a = b; 1096d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca b = c; 1106d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca c = a % b; 1116d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 1126d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1136d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (b); 1146d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca} 1156d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1166d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 1176d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Exchange the block from nonopt_start to nonopt_end with the block 1186d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * from nonopt_end to opt_end (keeping the same order of arguments 1196d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * in each block). 1206d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 1216d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic void 1226d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecapermute_args(int panonopt_start, int panonopt_end, int opt_end, 1236d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca char * const *nargv) 1246d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca{ 1256d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; 1266d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca char *swap; 1276d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1286d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 1296d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * compute lengths of blocks and number and size of cycles 1306d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 1316d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nnonopts = panonopt_end - panonopt_start; 1326d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nopts = opt_end - panonopt_end; 1336d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca ncycle = gcd(nnonopts, nopts); 1346d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca cyclelen = (opt_end - panonopt_start) / ncycle; 1356d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1366d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca for (i = 0; i < ncycle; i++) { 1376d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca cstart = panonopt_end+i; 1386d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca pos = cstart; 1396d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca for (j = 0; j < cyclelen; j++) { 1406d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (pos >= panonopt_end) 1416d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca pos -= nnonopts; 1426d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else 1436d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca pos += nopts; 1446d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca swap = nargv[pos]; 1456d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* LINTED const cast */ 1466d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca ((char **) nargv)[pos] = nargv[cstart]; 1476d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* LINTED const cast */ 1486d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca ((char **)nargv)[cstart] = swap; 1496d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 1506d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 1516d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca} 1526d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1536d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 1546d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * parse_long_options -- 1556d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Parse long options in argc/argv argument vector. 1566d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Returns -1 if short_too is set and the option does not match long_options. 1576d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 1586d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int 1596d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaparse_long_options(char * const *nargv, const char *options, 1606d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca const struct option *long_options, int *idx, int short_too) 1616d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca{ 1626d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca char *current_argv, *has_equal; 1636d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca size_t current_argv_len; 1646d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca int i, match; 1656d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1666d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca current_argv = place; 1676d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca match = -1; 1686d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1696d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind++; 1706d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1716d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if ((has_equal = strchr(current_argv, '=')) != NULL) { 1726d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* argument found (--option=arg) */ 1736d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca current_argv_len = has_equal - current_argv; 1746d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca has_equal++; 1756d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } else 1766d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca current_argv_len = strlen(current_argv); 1776d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1786d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca for (i = 0; long_options[i].name; i++) { 1796d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* find matching long option */ 1806d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (strncmp(current_argv, long_options[i].name, 1816d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca current_argv_len)) 1826d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca continue; 1836d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1846d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (strlen(long_options[i].name) == current_argv_len) { 1856d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* exact match */ 1866d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca match = i; 1876d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca break; 1886d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 1896d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 1906d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * If this is a known short option, don't allow 1916d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * a partial match of a single character. 1926d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 1936d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (short_too && current_argv_len == 1) 1946d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca continue; 1956d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 1966d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (match == -1) /* partial match */ 1976d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca match = i; 1986d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else { 1996d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* ambiguous abbreviation */ 2006d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (PRINT_ERROR) 201f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca fprintf(stderr, ambig, (int)current_argv_len, 2026d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca current_argv); 2036d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = 0; 2046d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (BADCH); 2056d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2066d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2076d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (match != -1) { /* option found */ 2086d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (long_options[match].has_arg == no_argument 2096d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca && has_equal) { 2106d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (PRINT_ERROR) 211f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca fprintf(stderr, noarg, (int)current_argv_len, 2126d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca current_argv); 2136d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 2146d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * XXX: GNU sets optopt to val regardless of flag 2156d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 2166d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (long_options[match].flag == NULL) 2176d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = long_options[match].val; 2186d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else 2196d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = 0; 2206d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (BADARG); 2216d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2226d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (long_options[match].has_arg == required_argument || 2236d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca long_options[match].has_arg == optional_argument) { 2246d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (has_equal) 2256d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optarg = has_equal; 2266d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else if (long_options[match].has_arg == 2276d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca required_argument) { 2286d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 2296d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * optional argument doesn't use next nargv 2306d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 2316d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optarg = nargv[optind++]; 2326d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2336d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2346d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if ((long_options[match].has_arg == required_argument) 2356d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca && (optarg == NULL)) { 2366d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 2376d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Missing argument; leading ':' indicates no error 2386d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * should be generated. 2396d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 2406d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (PRINT_ERROR) 241f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca fprintf(stderr, recargstring, 2426d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca current_argv); 2436d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 2446d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * XXX: GNU sets optopt to val regardless of flag 2456d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 2466d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (long_options[match].flag == NULL) 2476d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = long_options[match].val; 2486d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else 2496d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = 0; 2506d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca --optind; 2516d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (BADARG); 2526d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2536d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } else { /* unknown option */ 2546d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (short_too) { 2556d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca --optind; 2566d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (-1); 2576d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2586d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (PRINT_ERROR) 259f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca fprintf(stderr, illoptstring, current_argv); 2606d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = 0; 2616d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (BADCH); 2626d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 2636d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (idx) 2646d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca *idx = match; 2656d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (long_options[match].flag) { 2666d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca *long_options[match].flag = long_options[match].val; 2676d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (0); 2686d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } else 2696d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (long_options[match].val); 2706d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca} 2716d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 2726d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 2736d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * getopt_internal -- 2746d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Parse argc/argv argument vector. Called by user level routines. 2756d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 2766d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastatic int 2776d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecagetopt_internal(int nargc, char * const *nargv, const char *options, 2786d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca const struct option *long_options, int *idx, int flags) 2796d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca{ 2806d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca char *oli; /* option letter list index */ 2816d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca int optchar, short_too; 2826d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca static int posixly_correct = -1; 2836d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 2846d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (options == NULL) 2856d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (-1); 2866d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 2876d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 2886d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Disable GNU extensions if POSIXLY_CORRECT is set or options 2896d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * string begins with a '+'. 2906d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 2916d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (posixly_correct == -1) 2926d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); 2936d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (posixly_correct || *options == '+') 2946d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca flags &= ~FLAG_PERMUTE; 2956d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else if (*options == '-') 2966d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca flags |= FLAG_ALLARGS; 2976d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (*options == '+' || *options == '-') 2986d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca options++; 2996d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 3006d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 3016d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * XXX Some GNU programs (like cvs) set optind to 0 instead of 3026d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * XXX using optreset. Work around this braindamage. 3036d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 3046d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (optind == 0) 3056d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind = optreset = 1; 3066d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 3076d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optarg = NULL; 3086d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (optreset) 3096d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nonopt_start = nonopt_end = -1; 3106d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecastart: 3116d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (optreset || !*place) { /* update scanning pointer */ 3126d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optreset = 0; 3136d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (optind >= nargc) { /* end of argument vector */ 3146d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; 3156d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (nonopt_end != -1) { 3166d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* do permutation, if we have to */ 3176d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca permute_args(nonopt_start, nonopt_end, 3186d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind, nargv); 3196d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind -= nonopt_end - nonopt_start; 3206d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3216d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else if (nonopt_start != -1) { 3226d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 3236d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * If we skipped non-options, set optind 3246d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * to the first of them. 3256d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 3266d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind = nonopt_start; 3276d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3286d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nonopt_start = nonopt_end = -1; 3296d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (-1); 3306d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3316d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (*(place = nargv[optind]) != '-' || 3326d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca (place[1] == '\0' && strchr(options, '-') == NULL)) { 3336d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; /* found non-option */ 3346d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (flags & FLAG_ALLARGS) { 3356d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 3366d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * GNU extension: 3376d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * return non-option as argument to option 1 3386d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 3396d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optarg = nargv[optind++]; 3406d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (INORDER); 3416d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3426d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (!(flags & FLAG_PERMUTE)) { 3436d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 3446d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * If no permutation wanted, stop parsing 3456d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * at first non-option. 3466d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 3476d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (-1); 3486d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3496d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* do permutation */ 3506d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (nonopt_start == -1) 3516d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nonopt_start = optind; 3526d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else if (nonopt_end != -1) { 3536d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca permute_args(nonopt_start, nonopt_end, 3546d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind, nargv); 3556d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nonopt_start = optind - 3566d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca (nonopt_end - nonopt_start); 3576d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nonopt_end = -1; 3586d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3596d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind++; 3606d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* process next argument */ 3616d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca goto start; 3626d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3636d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (nonopt_start != -1 && nonopt_end == -1) 3646d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nonopt_end = optind; 3656d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 3666d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 3676d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * If we have "-" do nothing, if "--" we are done. 3686d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 3696d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { 3706d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind++; 3716d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; 3726d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 3736d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * We found an option (--), so if we skipped 3746d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * non-options, we have to permute. 3756d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 3766d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (nonopt_end != -1) { 3776d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca permute_args(nonopt_start, nonopt_end, 3786d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind, nargv); 3796d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optind -= nonopt_end - nonopt_start; 3806d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3816d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca nonopt_start = nonopt_end = -1; 3826d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (-1); 3836d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3846d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 3856d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 3866d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 3876d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Check long options if: 3886d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 1) we were passed some 3896d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 2) the arg is not just "-" 3906d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 3) either the arg starts with -- we are getopt_long_only() 3916d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 3926d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (long_options != NULL && place != nargv[optind] && 3936d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca (*place == '-' || (flags & FLAG_LONGONLY))) { 3946d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca short_too = 0; 3956d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (*place == '-') 3966d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place++; /* --foo long option */ 3976d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else if (*place != ':' && strchr(options, *place) != NULL) 3986d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca short_too = 1; /* could be short option too */ 3996d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 4006d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optchar = parse_long_options(nargv, options, long_options, 4016d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca idx, short_too); 4026d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (optchar != -1) { 4036d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; 4046d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (optchar); 4056d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 4066d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 4076d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 4086d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if ((optchar = (int)*place++) == (int)':' || 4096d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca (optchar == (int)'-' && *place != '\0') || 4106d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca (oli = strchr(options, optchar)) == NULL) { 4116d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 4126d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * If the user specified "-" and '-' isn't listed in 4136d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * options, return -1 (non-option) as per POSIX. 4146d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Otherwise, it is an unknown option character (or ':'). 4156d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 4166d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (optchar == (int)'-' && *place == '\0') 4176d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (-1); 4186d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (!*place) 4196d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca ++optind; 4206d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (PRINT_ERROR) 421f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca fprintf(stderr, illoptchar, optchar); 4226d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = optchar; 4236d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (BADCH); 4246d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 4256d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (long_options != NULL && optchar == 'W' && oli[1] == ';') { 4266d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* -W long-option */ 4276d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (*place) /* no space */ 4286d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* NOTHING */; 4296d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else if (++optind >= nargc) { /* no arg */ 4306d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; 4316d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (PRINT_ERROR) 432f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca fprintf(stderr, recargchar, optchar); 4336d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = optchar; 4346d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (BADARG); 4356d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } else /* white space */ 4366d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = nargv[optind]; 4376d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optchar = parse_long_options(nargv, options, long_options, 4386d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca idx, 0); 4396d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; 4406d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (optchar); 4416d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 4426d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (*++oli != ':') { /* doesn't take argument */ 4436d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (!*place) 4446d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca ++optind; 4456d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } else { /* takes (optional) argument */ 4466d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optarg = NULL; 4476d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (*place) /* no white space */ 4486d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optarg = place; 4496d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca else if (oli[1] != ':') { /* arg not optional */ 4506d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (++optind >= nargc) { /* no arg */ 4516d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; 4526d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca if (PRINT_ERROR) 453f9bb5323eb96f47cfb4ab5f93165323df0a1fd61José Fonseca fprintf(stderr, recargchar, optchar); 4546d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optopt = optchar; 4556d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (BADARG); 4566d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } else 4576d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca optarg = nargv[optind]; 4586d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 4596d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca place = EMSG; 4606d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca ++optind; 4616d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca } 4626d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* dump back option letter */ 4636d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (optchar); 4646d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca} 4656d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 4666d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 4676d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * getopt -- 4686d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Parse argc/argv argument vector. 4696d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 4706d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * [eventually this will replace the BSD getopt] 4716d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 4726d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaint 4736d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecagetopt(int nargc, char * const *nargv, const char *options) 4746d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca{ 4756d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 4766d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca /* 4776d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * We don't pass FLAG_PERMUTE to getopt_internal() since 4786d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * the BSD getopt(3) (unlike GNU) has never done this. 4796d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * 4806d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Furthermore, since many privileged programs call getopt() 4816d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * before dropping privileges it makes sense to keep things 4826d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * as simple (and bug-free) as possible. 4836d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 4846d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); 4856d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca} 4866d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 4876d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 4886d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * getopt_long -- 4896d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Parse argc/argv argument vector. 4906d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 4916d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaint 4926d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecagetopt_long(int nargc, char * const *nargv, const char *options, 4936d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca const struct option *long_options, int *idx) 4946d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca{ 4956d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 4966d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (getopt_internal(nargc, nargv, options, long_options, idx, 4976d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca FLAG_PERMUTE)); 4986d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca} 4996d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 5006d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca/* 5016d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * getopt_long_only -- 5026d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca * Parse argc/argv argument vector. 5036d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca */ 5046d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecaint 5056d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonsecagetopt_long_only(int nargc, char * const *nargv, const char *options, 5066d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca const struct option *long_options, int *idx) 5076d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca{ 5086d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca 5096d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca return (getopt_internal(nargc, nargv, options, long_options, idx, 5106d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca FLAG_PERMUTE|FLAG_LONGONLY)); 5116d670f6c0f3b9383b8b4c8ed12beaeec56928266José Fonseca} 512