15ffd83dbSDimitry Andric //===-- GetOptInc.cpp -----------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "lldb/Host/common/GetOptInc.h"
100b57cec5SDimitry Andric
110b57cec5SDimitry Andric #if defined(REPLACE_GETOPT) || defined(REPLACE_GETOPT_LONG) || \
120b57cec5SDimitry Andric defined(REPLACE_GETOPT_LONG_ONLY)
130b57cec5SDimitry Andric
140b57cec5SDimitry Andric // getopt.cpp
15*fe6060f1SDimitry Andric #include <cerrno>
16*fe6060f1SDimitry Andric #include <cstdlib>
17*fe6060f1SDimitry Andric #include <cstring>
180b57cec5SDimitry Andric
190b57cec5SDimitry Andric #if defined(REPLACE_GETOPT)
200b57cec5SDimitry Andric int opterr = 1; /* if error message should be printed */
210b57cec5SDimitry Andric int optind = 1; /* index into parent argv vector */
220b57cec5SDimitry Andric int optopt = '?'; /* character checked for validity */
230b57cec5SDimitry Andric int optreset; /* reset getopt */
240b57cec5SDimitry Andric char *optarg; /* argument associated with option */
250b57cec5SDimitry Andric #endif
260b57cec5SDimitry Andric
270b57cec5SDimitry Andric #define PRINT_ERROR ((opterr) && (*options != ':'))
280b57cec5SDimitry Andric
290b57cec5SDimitry Andric #define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
300b57cec5SDimitry Andric #define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
310b57cec5SDimitry Andric #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric /* return values */
340b57cec5SDimitry Andric #define BADCH (int)'?'
350b57cec5SDimitry Andric #define BADARG ((*options == ':') ? (int)':' : (int)'?')
360b57cec5SDimitry Andric #define INORDER (int)1
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric #define EMSG ""
390b57cec5SDimitry Andric
400b57cec5SDimitry Andric static int getopt_internal(int, char *const *, const char *,
410b57cec5SDimitry Andric const struct option *, int *, int);
420b57cec5SDimitry Andric static int parse_long_options(char *const *, const char *,
430b57cec5SDimitry Andric const struct option *, int *, int);
440b57cec5SDimitry Andric static int gcd(int, int);
450b57cec5SDimitry Andric static void permute_args(int, int, int, char *const *);
460b57cec5SDimitry Andric
470b57cec5SDimitry Andric static const char *place = EMSG; /* option letter processing */
480b57cec5SDimitry Andric
490b57cec5SDimitry Andric /* XXX: set optreset to 1 rather than these two */
500b57cec5SDimitry Andric static int nonopt_start = -1; /* first non option argument (for permute) */
510b57cec5SDimitry Andric static int nonopt_end = -1; /* first option after non options (for permute) */
520b57cec5SDimitry Andric
530b57cec5SDimitry Andric /*
540b57cec5SDimitry Andric * Compute the greatest common divisor of a and b.
550b57cec5SDimitry Andric */
gcd(int a,int b)560b57cec5SDimitry Andric static int gcd(int a, int b) {
570b57cec5SDimitry Andric int c;
580b57cec5SDimitry Andric
590b57cec5SDimitry Andric c = a % b;
600b57cec5SDimitry Andric while (c != 0) {
610b57cec5SDimitry Andric a = b;
620b57cec5SDimitry Andric b = c;
630b57cec5SDimitry Andric c = a % b;
640b57cec5SDimitry Andric }
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric return (b);
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric
pass()690b57cec5SDimitry Andric static void pass() {}
700b57cec5SDimitry Andric #define warnx(a, ...) pass();
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric /*
730b57cec5SDimitry Andric * Exchange the block from nonopt_start to nonopt_end with the block
740b57cec5SDimitry Andric * from nonopt_end to opt_end (keeping the same order of arguments
750b57cec5SDimitry Andric * in each block).
760b57cec5SDimitry Andric */
permute_args(int panonopt_start,int panonopt_end,int opt_end,char * const * nargv)770b57cec5SDimitry Andric static void permute_args(int panonopt_start, int panonopt_end, int opt_end,
780b57cec5SDimitry Andric char *const *nargv) {
790b57cec5SDimitry Andric int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
800b57cec5SDimitry Andric char *swap;
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric /*
830b57cec5SDimitry Andric * compute lengths of blocks and number and size of cycles
840b57cec5SDimitry Andric */
850b57cec5SDimitry Andric nnonopts = panonopt_end - panonopt_start;
860b57cec5SDimitry Andric nopts = opt_end - panonopt_end;
870b57cec5SDimitry Andric ncycle = gcd(nnonopts, nopts);
880b57cec5SDimitry Andric cyclelen = (opt_end - panonopt_start) / ncycle;
890b57cec5SDimitry Andric
900b57cec5SDimitry Andric for (i = 0; i < ncycle; i++) {
910b57cec5SDimitry Andric cstart = panonopt_end + i;
920b57cec5SDimitry Andric pos = cstart;
930b57cec5SDimitry Andric for (j = 0; j < cyclelen; j++) {
940b57cec5SDimitry Andric if (pos >= panonopt_end)
950b57cec5SDimitry Andric pos -= nnonopts;
960b57cec5SDimitry Andric else
970b57cec5SDimitry Andric pos += nopts;
980b57cec5SDimitry Andric swap = nargv[pos];
990b57cec5SDimitry Andric /* LINTED const cast */
1000b57cec5SDimitry Andric const_cast<char **>(nargv)[pos] = nargv[cstart];
1010b57cec5SDimitry Andric /* LINTED const cast */
1020b57cec5SDimitry Andric const_cast<char **>(nargv)[cstart] = swap;
1030b57cec5SDimitry Andric }
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric }
1060b57cec5SDimitry Andric
1070b57cec5SDimitry Andric /*
1080b57cec5SDimitry Andric * parse_long_options --
1090b57cec5SDimitry Andric * Parse long options in argc/argv argument vector.
1100b57cec5SDimitry Andric * Returns -1 if short_too is set and the option does not match long_options.
1110b57cec5SDimitry Andric */
parse_long_options(char * const * nargv,const char * options,const struct option * long_options,int * idx,int short_too)1120b57cec5SDimitry Andric static int parse_long_options(char *const *nargv, const char *options,
1130b57cec5SDimitry Andric const struct option *long_options, int *idx,
1140b57cec5SDimitry Andric int short_too) {
1150b57cec5SDimitry Andric char *current_argv, *has_equal;
1160b57cec5SDimitry Andric size_t current_argv_len;
1170b57cec5SDimitry Andric int i, match;
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric current_argv = const_cast<char *>(place);
1200b57cec5SDimitry Andric match = -1;
1210b57cec5SDimitry Andric
1220b57cec5SDimitry Andric optind++;
1230b57cec5SDimitry Andric
1240b57cec5SDimitry Andric if ((has_equal = strchr(current_argv, '=')) != NULL) {
1250b57cec5SDimitry Andric /* argument found (--option=arg) */
1260b57cec5SDimitry Andric current_argv_len = has_equal - current_argv;
1270b57cec5SDimitry Andric has_equal++;
1280b57cec5SDimitry Andric } else
1290b57cec5SDimitry Andric current_argv_len = strlen(current_argv);
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric for (i = 0; long_options[i].name; i++) {
1320b57cec5SDimitry Andric /* find matching long option */
1330b57cec5SDimitry Andric if (strncmp(current_argv, long_options[i].name, current_argv_len))
1340b57cec5SDimitry Andric continue;
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric if (strlen(long_options[i].name) == current_argv_len) {
1370b57cec5SDimitry Andric /* exact match */
1380b57cec5SDimitry Andric match = i;
1390b57cec5SDimitry Andric break;
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric /*
1420b57cec5SDimitry Andric * If this is a known short option, don't allow
1430b57cec5SDimitry Andric * a partial match of a single character.
1440b57cec5SDimitry Andric */
1450b57cec5SDimitry Andric if (short_too && current_argv_len == 1)
1460b57cec5SDimitry Andric continue;
1470b57cec5SDimitry Andric
1480b57cec5SDimitry Andric if (match == -1) /* partial match */
1490b57cec5SDimitry Andric match = i;
1500b57cec5SDimitry Andric else {
1510b57cec5SDimitry Andric /* ambiguous abbreviation */
1520b57cec5SDimitry Andric if (PRINT_ERROR)
1530b57cec5SDimitry Andric warnx(ambig, (int)current_argv_len, current_argv);
1540b57cec5SDimitry Andric optopt = 0;
1550b57cec5SDimitry Andric return (BADCH);
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric }
1580b57cec5SDimitry Andric if (match != -1) { /* option found */
1590b57cec5SDimitry Andric if (long_options[match].has_arg == no_argument && has_equal) {
1600b57cec5SDimitry Andric if (PRINT_ERROR)
1610b57cec5SDimitry Andric warnx(noarg, (int)current_argv_len, current_argv);
1620b57cec5SDimitry Andric /*
1630b57cec5SDimitry Andric * XXX: GNU sets optopt to val regardless of flag
1640b57cec5SDimitry Andric */
1650b57cec5SDimitry Andric if (long_options[match].flag == NULL)
1660b57cec5SDimitry Andric optopt = long_options[match].val;
1670b57cec5SDimitry Andric else
1680b57cec5SDimitry Andric optopt = 0;
1690b57cec5SDimitry Andric return (BADARG);
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric if (long_options[match].has_arg == required_argument ||
1720b57cec5SDimitry Andric long_options[match].has_arg == optional_argument) {
1730b57cec5SDimitry Andric if (has_equal)
1740b57cec5SDimitry Andric optarg = has_equal;
1750b57cec5SDimitry Andric else if (long_options[match].has_arg == required_argument) {
1760b57cec5SDimitry Andric /*
1770b57cec5SDimitry Andric * optional argument doesn't use next nargv
1780b57cec5SDimitry Andric */
1790b57cec5SDimitry Andric optarg = nargv[optind++];
1800b57cec5SDimitry Andric }
1810b57cec5SDimitry Andric }
1820b57cec5SDimitry Andric if ((long_options[match].has_arg == required_argument) &&
1830b57cec5SDimitry Andric (optarg == NULL)) {
1840b57cec5SDimitry Andric /*
1850b57cec5SDimitry Andric * Missing argument; leading ':' indicates no error
1860b57cec5SDimitry Andric * should be generated.
1870b57cec5SDimitry Andric */
1880b57cec5SDimitry Andric if (PRINT_ERROR)
1890b57cec5SDimitry Andric warnx(recargstring, current_argv);
1900b57cec5SDimitry Andric /*
1910b57cec5SDimitry Andric * XXX: GNU sets optopt to val regardless of flag
1920b57cec5SDimitry Andric */
1930b57cec5SDimitry Andric if (long_options[match].flag == NULL)
1940b57cec5SDimitry Andric optopt = long_options[match].val;
1950b57cec5SDimitry Andric else
1960b57cec5SDimitry Andric optopt = 0;
1970b57cec5SDimitry Andric --optind;
1980b57cec5SDimitry Andric return (BADARG);
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric } else { /* unknown option */
2010b57cec5SDimitry Andric if (short_too) {
2020b57cec5SDimitry Andric --optind;
2030b57cec5SDimitry Andric return (-1);
2040b57cec5SDimitry Andric }
2050b57cec5SDimitry Andric if (PRINT_ERROR)
2060b57cec5SDimitry Andric warnx(illoptstring, current_argv);
2070b57cec5SDimitry Andric optopt = 0;
2080b57cec5SDimitry Andric return (BADCH);
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric if (idx)
2110b57cec5SDimitry Andric *idx = match;
2120b57cec5SDimitry Andric if (long_options[match].flag) {
2130b57cec5SDimitry Andric *long_options[match].flag = long_options[match].val;
2140b57cec5SDimitry Andric return (0);
2150b57cec5SDimitry Andric } else
2160b57cec5SDimitry Andric return (long_options[match].val);
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric
2190b57cec5SDimitry Andric /*
2200b57cec5SDimitry Andric * getopt_internal --
2210b57cec5SDimitry Andric * Parse argc/argv argument vector. Called by user level routines.
2220b57cec5SDimitry Andric */
getopt_internal(int nargc,char * const * nargv,const char * options,const struct option * long_options,int * idx,int flags)2230b57cec5SDimitry Andric static int getopt_internal(int nargc, char *const *nargv, const char *options,
2240b57cec5SDimitry Andric const struct option *long_options, int *idx,
2250b57cec5SDimitry Andric int flags) {
2260b57cec5SDimitry Andric const char *oli; /* option letter list index */
2270b57cec5SDimitry Andric int optchar, short_too;
2280b57cec5SDimitry Andric static int posixly_correct = -1;
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric if (options == NULL)
2310b57cec5SDimitry Andric return (-1);
2320b57cec5SDimitry Andric
2330b57cec5SDimitry Andric /*
2340b57cec5SDimitry Andric * XXX Some GNU programs (like cvs) set optind to 0 instead of
2350b57cec5SDimitry Andric * XXX using optreset. Work around this braindamage.
2360b57cec5SDimitry Andric */
2370b57cec5SDimitry Andric if (optind == 0)
2380b57cec5SDimitry Andric optind = optreset = 1;
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andric /*
2410b57cec5SDimitry Andric * Disable GNU extensions if POSIXLY_CORRECT is set or options
2420b57cec5SDimitry Andric * string begins with a '+'.
2430b57cec5SDimitry Andric */
2440b57cec5SDimitry Andric if (posixly_correct == -1 || optreset)
2450b57cec5SDimitry Andric posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
2460b57cec5SDimitry Andric if (*options == '-')
2470b57cec5SDimitry Andric flags |= FLAG_ALLARGS;
2480b57cec5SDimitry Andric else if (posixly_correct || *options == '+')
2490b57cec5SDimitry Andric flags &= ~FLAG_PERMUTE;
2500b57cec5SDimitry Andric if (*options == '+' || *options == '-')
2510b57cec5SDimitry Andric options++;
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric optarg = NULL;
2540b57cec5SDimitry Andric if (optreset)
2550b57cec5SDimitry Andric nonopt_start = nonopt_end = -1;
2560b57cec5SDimitry Andric start:
2570b57cec5SDimitry Andric if (optreset || !*place) { /* update scanning pointer */
2580b57cec5SDimitry Andric optreset = 0;
2590b57cec5SDimitry Andric if (optind >= nargc) { /* end of argument vector */
2600b57cec5SDimitry Andric place = EMSG;
2610b57cec5SDimitry Andric if (nonopt_end != -1) {
2620b57cec5SDimitry Andric /* do permutation, if we have to */
2630b57cec5SDimitry Andric permute_args(nonopt_start, nonopt_end, optind, nargv);
2640b57cec5SDimitry Andric optind -= nonopt_end - nonopt_start;
2650b57cec5SDimitry Andric } else if (nonopt_start != -1) {
2660b57cec5SDimitry Andric /*
2670b57cec5SDimitry Andric * If we skipped non-options, set optind
2680b57cec5SDimitry Andric * to the first of them.
2690b57cec5SDimitry Andric */
2700b57cec5SDimitry Andric optind = nonopt_start;
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric nonopt_start = nonopt_end = -1;
2730b57cec5SDimitry Andric return (-1);
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric if (*(place = nargv[optind]) != '-' ||
2760b57cec5SDimitry Andric (place[1] == '\0' && strchr(options, '-') == NULL)) {
2770b57cec5SDimitry Andric place = EMSG; /* found non-option */
2780b57cec5SDimitry Andric if (flags & FLAG_ALLARGS) {
2790b57cec5SDimitry Andric /*
2800b57cec5SDimitry Andric * GNU extension:
2810b57cec5SDimitry Andric * return non-option as argument to option 1
2820b57cec5SDimitry Andric */
2830b57cec5SDimitry Andric optarg = nargv[optind++];
2840b57cec5SDimitry Andric return (INORDER);
2850b57cec5SDimitry Andric }
2860b57cec5SDimitry Andric if (!(flags & FLAG_PERMUTE)) {
2870b57cec5SDimitry Andric /*
2880b57cec5SDimitry Andric * If no permutation wanted, stop parsing
2890b57cec5SDimitry Andric * at first non-option.
2900b57cec5SDimitry Andric */
2910b57cec5SDimitry Andric return (-1);
2920b57cec5SDimitry Andric }
2930b57cec5SDimitry Andric /* do permutation */
2940b57cec5SDimitry Andric if (nonopt_start == -1)
2950b57cec5SDimitry Andric nonopt_start = optind;
2960b57cec5SDimitry Andric else if (nonopt_end != -1) {
2970b57cec5SDimitry Andric permute_args(nonopt_start, nonopt_end, optind, nargv);
2980b57cec5SDimitry Andric nonopt_start = optind - (nonopt_end - nonopt_start);
2990b57cec5SDimitry Andric nonopt_end = -1;
3000b57cec5SDimitry Andric }
3010b57cec5SDimitry Andric optind++;
3020b57cec5SDimitry Andric /* process next argument */
3030b57cec5SDimitry Andric goto start;
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric if (nonopt_start != -1 && nonopt_end == -1)
3060b57cec5SDimitry Andric nonopt_end = optind;
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andric /*
3090b57cec5SDimitry Andric * If we have "-" do nothing, if "--" we are done.
3100b57cec5SDimitry Andric */
3110b57cec5SDimitry Andric if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
3120b57cec5SDimitry Andric optind++;
3130b57cec5SDimitry Andric place = EMSG;
3140b57cec5SDimitry Andric /*
3150b57cec5SDimitry Andric * We found an option (--), so if we skipped
3160b57cec5SDimitry Andric * non-options, we have to permute.
3170b57cec5SDimitry Andric */
3180b57cec5SDimitry Andric if (nonopt_end != -1) {
3190b57cec5SDimitry Andric permute_args(nonopt_start, nonopt_end, optind, nargv);
3200b57cec5SDimitry Andric optind -= nonopt_end - nonopt_start;
3210b57cec5SDimitry Andric }
3220b57cec5SDimitry Andric nonopt_start = nonopt_end = -1;
3230b57cec5SDimitry Andric return (-1);
3240b57cec5SDimitry Andric }
3250b57cec5SDimitry Andric }
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric /*
3280b57cec5SDimitry Andric * Check long options if:
3290b57cec5SDimitry Andric * 1) we were passed some
3300b57cec5SDimitry Andric * 2) the arg is not just "-"
3310b57cec5SDimitry Andric * 3) either the arg starts with -- we are getopt_long_only()
3320b57cec5SDimitry Andric */
3330b57cec5SDimitry Andric if (long_options != NULL && place != nargv[optind] &&
3340b57cec5SDimitry Andric (*place == '-' || (flags & FLAG_LONGONLY))) {
3350b57cec5SDimitry Andric short_too = 0;
3360b57cec5SDimitry Andric if (*place == '-')
3370b57cec5SDimitry Andric place++; /* --foo long option */
3380b57cec5SDimitry Andric else if (*place != ':' && strchr(options, *place) != NULL)
3390b57cec5SDimitry Andric short_too = 1; /* could be short option too */
3400b57cec5SDimitry Andric
3410b57cec5SDimitry Andric optchar = parse_long_options(nargv, options, long_options, idx, short_too);
3420b57cec5SDimitry Andric if (optchar != -1) {
3430b57cec5SDimitry Andric place = EMSG;
3440b57cec5SDimitry Andric return (optchar);
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric
3480b57cec5SDimitry Andric if ((optchar = (int)*place++) == (int)':' ||
3490b57cec5SDimitry Andric (optchar == (int)'-' && *place != '\0') ||
3500b57cec5SDimitry Andric (oli = strchr(options, optchar)) == NULL) {
3510b57cec5SDimitry Andric /*
3520b57cec5SDimitry Andric * If the user specified "-" and '-' isn't listed in
3530b57cec5SDimitry Andric * options, return -1 (non-option) as per POSIX.
3540b57cec5SDimitry Andric * Otherwise, it is an unknown option character (or ':').
3550b57cec5SDimitry Andric */
3560b57cec5SDimitry Andric if (optchar == (int)'-' && *place == '\0')
3570b57cec5SDimitry Andric return (-1);
3580b57cec5SDimitry Andric if (!*place)
3590b57cec5SDimitry Andric ++optind;
3600b57cec5SDimitry Andric if (PRINT_ERROR)
3610b57cec5SDimitry Andric warnx(illoptchar, optchar);
3620b57cec5SDimitry Andric optopt = optchar;
3630b57cec5SDimitry Andric return (BADCH);
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
3660b57cec5SDimitry Andric /* -W long-option */
3670b57cec5SDimitry Andric if (*place) /* no space */
3680b57cec5SDimitry Andric /* NOTHING */;
3690b57cec5SDimitry Andric else if (++optind >= nargc) { /* no arg */
3700b57cec5SDimitry Andric place = EMSG;
3710b57cec5SDimitry Andric if (PRINT_ERROR)
3720b57cec5SDimitry Andric warnx(recargchar, optchar);
3730b57cec5SDimitry Andric optopt = optchar;
3740b57cec5SDimitry Andric return (BADARG);
3750b57cec5SDimitry Andric } else /* white space */
3760b57cec5SDimitry Andric place = nargv[optind];
3770b57cec5SDimitry Andric optchar = parse_long_options(nargv, options, long_options, idx, 0);
3780b57cec5SDimitry Andric place = EMSG;
3790b57cec5SDimitry Andric return (optchar);
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric if (*++oli != ':') { /* doesn't take argument */
3820b57cec5SDimitry Andric if (!*place)
3830b57cec5SDimitry Andric ++optind;
3840b57cec5SDimitry Andric } else { /* takes (optional) argument */
3850b57cec5SDimitry Andric optarg = NULL;
3860b57cec5SDimitry Andric if (*place) /* no white space */
3870b57cec5SDimitry Andric optarg = const_cast<char *>(place);
3880b57cec5SDimitry Andric else if (oli[1] != ':') { /* arg not optional */
3890b57cec5SDimitry Andric if (++optind >= nargc) { /* no arg */
3900b57cec5SDimitry Andric place = EMSG;
3910b57cec5SDimitry Andric if (PRINT_ERROR)
3920b57cec5SDimitry Andric warnx(recargchar, optchar);
3930b57cec5SDimitry Andric optopt = optchar;
3940b57cec5SDimitry Andric return (BADARG);
3950b57cec5SDimitry Andric } else
3960b57cec5SDimitry Andric optarg = nargv[optind];
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric place = EMSG;
3990b57cec5SDimitry Andric ++optind;
4000b57cec5SDimitry Andric }
4010b57cec5SDimitry Andric /* dump back option letter */
4020b57cec5SDimitry Andric return (optchar);
4030b57cec5SDimitry Andric }
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric /*
4060b57cec5SDimitry Andric * getopt --
4070b57cec5SDimitry Andric * Parse argc/argv argument vector.
4080b57cec5SDimitry Andric *
4090b57cec5SDimitry Andric * [eventually this will replace the BSD getopt]
4100b57cec5SDimitry Andric */
4110b57cec5SDimitry Andric #if defined(REPLACE_GETOPT)
getopt(int nargc,char * const * nargv,const char * options)4120b57cec5SDimitry Andric int getopt(int nargc, char *const *nargv, const char *options) {
4130b57cec5SDimitry Andric
4140b57cec5SDimitry Andric /*
4150b57cec5SDimitry Andric * We don't pass FLAG_PERMUTE to getopt_internal() since
4160b57cec5SDimitry Andric * the BSD getopt(3) (unlike GNU) has never done this.
4170b57cec5SDimitry Andric *
4180b57cec5SDimitry Andric * Furthermore, since many privileged programs call getopt()
4190b57cec5SDimitry Andric * before dropping privileges it makes sense to keep things
4200b57cec5SDimitry Andric * as simple (and bug-free) as possible.
4210b57cec5SDimitry Andric */
4220b57cec5SDimitry Andric return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
4230b57cec5SDimitry Andric }
4240b57cec5SDimitry Andric #endif
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric /*
4270b57cec5SDimitry Andric * getopt_long --
4280b57cec5SDimitry Andric * Parse argc/argv argument vector.
4290b57cec5SDimitry Andric */
4300b57cec5SDimitry Andric #if defined(REPLACE_GETOPT_LONG)
getopt_long(int nargc,char * const * nargv,const char * options,const struct option * long_options,int * idx)4310b57cec5SDimitry Andric int getopt_long(int nargc, char *const *nargv, const char *options,
4320b57cec5SDimitry Andric const struct option *long_options, int *idx) {
4330b57cec5SDimitry Andric return (
4340b57cec5SDimitry Andric getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE));
4350b57cec5SDimitry Andric }
4360b57cec5SDimitry Andric #endif
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andric /*
4390b57cec5SDimitry Andric * getopt_long_only --
4400b57cec5SDimitry Andric * Parse argc/argv argument vector.
4410b57cec5SDimitry Andric */
4420b57cec5SDimitry Andric #if defined(REPLACE_GETOPT_LONG_ONLY)
getopt_long_only(int nargc,char * const * nargv,const char * options,const struct option * long_options,int * idx)4430b57cec5SDimitry Andric int getopt_long_only(int nargc, char *const *nargv, const char *options,
4440b57cec5SDimitry Andric const struct option *long_options, int *idx) {
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric return (getopt_internal(nargc, nargv, options, long_options, idx,
4470b57cec5SDimitry Andric FLAG_PERMUTE | FLAG_LONGONLY));
4480b57cec5SDimitry Andric }
4490b57cec5SDimitry Andric #endif
4500b57cec5SDimitry Andric
4510b57cec5SDimitry Andric #endif
452