From: git Date: Sat, 18 Apr 2026 15:30:02 +0000 (-0400) Subject: add getopt_long X-Git-Url: https://git.datadissipation.net/?a=commitdiff_plain;h=fd4273e5b7249057309c65c78ec1bd766bed03fe;p=single-header-libcext.git add getopt_long --- diff --git a/README.md b/README.md index 59cf6d6..46ea40c 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,24 @@ -A (WIP) collection of portable, strict C99, single-header implementations of common libc extensions. +A (WIP) collection of portable, (mostly) strict C99, single-header implementations of common libc extensions. ### How to Include the header in every file needed as usual: ``` -#include "" +#include ".h" ``` In the file chosen for the function implementation: ``` -#define _IMPLEMENTATION_ +#define _IMPLEMENTATION #include "" ``` -By default, the header won't have any includes, change that with: +By default, the header won't have any stdlib includes, change that with: ``` -#define _INCLUDE_LIBC_ +#define _INCLUDE_LIBC ``` Or disable function override with: @@ -26,3 +26,16 @@ Or disable function override with: ``` #define HAVE_ ``` + +## Specifics + +### getopt\_long + +`getopt_long.h` has additional macros related to argument +permuting, defining those enables it (GNU behaviour): + +``` +#define GETOPT_PERMUTE_ARGS +#define GETOPT_LONG_PERMUTE_ARGS +#define GETOPT_LONG_ONLY_PERMUTE_ARGS +``` diff --git a/asprintf.h b/asprintf.h index dc944df..a22a6fb 100644 --- a/asprintf.h +++ b/asprintf.h @@ -1,22 +1,56 @@ +/* + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * For more information, please refer to + */ + /* https://git.datadissipation.net */ #ifndef ASPRINTF_H_ #define ASPRINTF_H_ 1 - #ifdef ASPRINTF_INCLUDE_LIBC_ + #ifdef ASPRINTF_INCLUDE_LIBC #include #include #include #endif #ifndef HAVE_ASPRINTF - int vasprintf_(char **strp, const char *fmt, va_list ap); - int asprintf_(char **strp, const char *fmt, ...); + #define HAVE_ASPRINTF 1 + int i_vasprintf_(char **restrict strp, const char *restrict fmt, va_list ap); + int i_asprintf_(char **restrict strp, const char *restrict fmt, ...); /* * Credit for a big part of the macro madness: * Jens Gustedt * https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/ */ - #define vasprintf(s, f, a) vasprintf_(s, f, a) + + /* + * This isn't strict C99, because C99 requires at least one argument in "..." + * for macros. Still, I haven't encountered a compiler that won't preprocess + * this right (out of the popular ones, MSVC wasn't tested) + */ + #define vasprintf(s, f, a) i_vasprintf_(s, f, a) #define I_COND_COMMA_(...) , #define I_PICK_ARG_(_1, _2, ARG, ...) ARG #define I_HAS_COMMA_(...) I_PICK_ARG_(__VA_ARGS__, 1, 0) @@ -47,14 +81,14 @@ #define I_GET_ARG_(...) I_PICK_ARG_(__VA_ARGS__) #define asprintf(s, f, ...)\ - asprintf_(s, f I_PASTE_(I_ISEMPTY_(I_GET_ARG_(, , __VA_ARGS__))) __VA_ARGS__) + i_asprintf_(s, f I_PASTE_(I_ISEMPTY_(I_GET_ARG_(, , __VA_ARGS__))) __VA_ARGS__) #define I_EMPTY_1 #define I_EMPTY_0 I_COND_COMMA_() - #endif + #endif /* !HAVE_ASPRINTF */ - #ifdef ASPRINTF_IMPLEMENTATION_ + #ifdef ASPRINTF_IMPLEMENTATION int - vasprintf_(char **strp, const char *fmt, va_list ap) + i_vasprintf_(char **restrict strp, const char *restrict fmt, va_list ap) { int size, ret; va_list tp; @@ -81,16 +115,16 @@ } int - asprintf_(char **strp, const char *fmt, ...) + i_asprintf_(char **restrict strp, const char *restrict fmt, ...) { int ret; va_list ap; va_start(ap, fmt); - ret = vasprintf(strp, fmt, ap); + ret = i_vasprintf_(strp, fmt, ap); va_end(ap); return ret; } - #endif -#endif + #endif /* ASPRINTF_IMPLEMENTATION */ +#endif /* !ASPRINTF_H_ */ diff --git a/getopt_long.h b/getopt_long.h new file mode 100644 index 0000000..f26dd57 --- /dev/null +++ b/getopt_long.h @@ -0,0 +1,572 @@ +/* + * Copyright (c) 2002 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Sponsored in part by the Defense Advanced Research Projects + * Agency (DARPA) and Air Force Research Laboratory, Air Force + * Materiel Command, USAF, under agreement number F39502-99-1-0512. + */ + +/* + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Dieter Baron and Thomas Klausner. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* https://git.datadissipation.net */ +#ifndef GETOPT_LONG_H_ + #define GETOPT_LONG_H_ 1 + + #ifdef GETOPT_LONG_INCLUDE_LIBC + #include + #include + #include + #endif + + #ifndef HAVE_GETOPT_LONG + #define HAVE_GETOPT_LONG 1 + /* + * structs are in their own namespace, so this should be OK + * the worst it can do is make compiler messages worse + */ + #define option i_option_ + + struct i_option_ { + const char *name; + /* + * one of no_argument, required_argument, and optional_argument: + * whether option takes an argument + */ + int has_arg; + /* if not NULL, set *flag to val when option found */ + int *flag; + /* if flag not NULL, value to set *flag to; else return value */ + int val; + }; + + int i_getopt_(int argc, char *argv[], const char *optstring); + int i_getsubopt_(char *restrict optionp[], const char *restrict tokens[], + char *restrict valuep[]); + int i_getopt_long_(int argc, char *argv[], const char *optstring, + const struct option *longopts, int *longindex); + int i_getopt_long_only_(int argc, char *argv[], const char *optstring, + const struct option *longopts, int *longindex); + + #define no_argument 0 + #define required_argument 1 + #define optional_argument 2 + + #define getopt(c,v,o) i_getopt_(c,v,o) + #define getsubopt(o,t,v) i_getsubopt_(o,t,v) + #define getopt_long(c,v,o,l,i) i_getopt_long_(c,v,o,l,i) + #define getopt_long_only(c,v,o,l,i) i_getopt_long_only_(c,v,o,l,i) + + #endif /* !HAVE_GETOPT_LONG */ + + #ifdef GETOPT_LONG_IMPLEMENTATION + #define I_PRINT_ERROR_ ((i_opterr_) && (*options != ':')) + + #define I_FLAG_PERMUTE_ 0x01 /* permute non-options to the end of argv */ + #define I_FLAG_ALLARGS_ 0x02 /* treat non-options as args to option "-1" */ + #define I_FLAG_LONGONLY_ 0x04 /* operate as i_getopt_long_only */ + + /* return values */ + #define I_BADCH_ (int)'?' + #define I_BADARG_ ((*options == ':') ? (int)':' : (int)'?') + #define I_INORDER_ (int)1 + + #define I_EMSG_ "" + + static void i_warnx_(const char *, ...); + static int i_getopt_internal_(int, char **, const char *, + const struct option *, int *, int); + static int i_parse_long_options__(char * const *, const char *, + const struct option *, int *, int); + static int i_gcd_(int, int); + static void i_permute_args_(int, int, int, char * const *); + + + /* XXX: set i_optreeset_ to 1 rather than these two */ + static int i_nonopt_start_ = -1; /* first non option argument (for permute) */ + static int i_nonopt_end_ = -1; /* first option after non options (for permute) */ + static int i_opterr_ = 1; /* if error message should be printed */ + static int i_optind_ = 1; /* index into parent argv vector */ + static int i_optopt_ = '?'; /* character checked for validity */ + static int i_optreeset_; /* reset getopt */ + static char *i_optarg_; /* argument associated with option */ + static char *i_place_ = I_EMSG_; /* option letter processing */ + + /* Error messages */ + static const char i_recargchar_[] = "option requires an argument -- %c"; + static const char i_recargstring_[] = "option requires an argument -- %s"; + static const char i_ambig_[] = "i_ambig_uous option -- %.*s"; + static const char i_noarg_[] = "option doesn't take an argument -- %.*s"; + static const char i_illoptchar_[] = "unknown option -- %c"; + static const char i_illoptstring_[] = "unknown option -- %s"; + + /* + * Own warnx() for portability + */ + void + i_warnx_(const char *fmt, ...) + { + va_list args; + + #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) + #define I_GET_PROG_NAME_() getprogname() + #elif defined(__linux__) + #include + #define I_GET_PROG_NAME_() program_invocation_short_name + #else + #define I_GET_PROG_NAME_() "warnx" + #endif + + va_start(args, fmt); + fprintf(stderr, "%s: ", I_GET_PROG_NAME_()); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + va_end(args); + } + + /* + * Compute the greatest common divisor of a and b. + */ + static int + i_gcd_(int a, int b) + { + int c; + + c = a % b; + while (c != 0) { + a = b; + b = c; + c = a % b; + } + + return (b); + } + + /* + * Exchange the block from i_nonopt_start_ to i_nonopt_end_ with the block + * from i_nonopt_end_ to opt_end (keeping the same order of arguments + * in each block). + */ + static void + i_permute_args_(int pai_nonopt_start_, int pai_nonopt_end_, int opt_end, + char * const *nargv) + { + int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; + char *swap; + + /* + * compute lengths of blocks and number and size of cycles + */ + nnonopts = pai_nonopt_end_ - pai_nonopt_start_; + nopts = opt_end - pai_nonopt_end_; + ncycle = i_gcd_(nnonopts, nopts); + cyclelen = (opt_end - pai_nonopt_start_) / ncycle; + + for (i = 0; i < ncycle; i++) { + cstart = pai_nonopt_end_+i; + pos = cstart; + for (j = 0; j < cyclelen; j++) { + if (pos >= pai_nonopt_end_) + pos -= nnonopts; + else + pos += nopts; + swap = nargv[pos]; + /* LINTED const cast */ + ((char **) nargv)[pos] = nargv[cstart]; + /* LINTED const cast */ + ((char **)nargv)[cstart] = swap; + } + } + } + + /* + * i_parse_long_options__ -- + * Parse long options in argc/argv argument vector. + * Returns -1 if short_too is set and the option does not match long_options. + */ + static int + i_parse_long_options__(char * const *nargv, const char *options, + const struct option *long_options, int *idx, int short_too) + { + char *current_argv, *has_equal; + size_t current_argv_len; + int i, match; + + current_argv = i_place_; + match = -1; + + i_optind_++; + + if ((has_equal = strchr(current_argv, '=')) != NULL) { + /* argument found (--option=arg) */ + current_argv_len = has_equal - current_argv; + has_equal++; + } else { + current_argv_len = strlen(current_argv); + } + for (i = 0; long_options[i].name; i++) { + /* find matching long option */ + if (strncmp(current_argv, long_options[i].name, + current_argv_len)) + continue; + + if (strlen(long_options[i].name) == current_argv_len) { + /* exact match */ + match = i; + break; + } + /* + * If this is a known short option, don't allow + * a partial match of a single character. + */ + if (short_too && current_argv_len == 1) + continue; + + if (match == -1) { /* partial match */ + match = i; + } else { + /* i_ambig_uous abbreviation */ + if (I_PRINT_ERROR_) + i_warnx_(i_ambig_, (int)current_argv_len, + current_argv); + i_optopt_ = 0; + return (I_BADCH_); + } + } + if (match != -1) { /* option found */ + if (long_options[match].has_arg == no_argument + && has_equal) { + if (I_PRINT_ERROR_) + i_warnx_(i_noarg_, (int)current_argv_len, + current_argv); + /* + * XXX: GNU sets i_optopt_ to val regardless of flag + */ + if (long_options[match].flag == NULL) + i_optopt_ = long_options[match].val; + else + i_optopt_ = 0; + return (I_BADARG_); + } + if (long_options[match].has_arg == required_argument || + long_options[match].has_arg == optional_argument) { + if (has_equal) + i_optarg_ = has_equal; + else if (long_options[match].has_arg == + required_argument) { + /* + * optional argument doesn't use next nargv + */ + i_optarg_ = nargv[i_optind_++]; + } + } + if ((long_options[match].has_arg == required_argument) + && (i_optarg_ == NULL)) { + /* + * Missing argument; leading ':' indicates no error + * should be generated. + */ + if (I_PRINT_ERROR_) + i_warnx_(i_recargstring_, + current_argv); + /* + * XXX: GNU sets i_optopt_ to val regardless of flag + */ + if (long_options[match].flag == NULL) + i_optopt_ = long_options[match].val; + else + i_optopt_ = 0; + --i_optind_; + return (I_BADARG_); + } + } else { /* unknown option */ + if (short_too) { + --i_optind_; + return (-1); + } + if (I_PRINT_ERROR_) + i_warnx_(i_illoptstring_, current_argv); + i_optopt_ = 0; + return (I_BADCH_); + } + if (idx) + *idx = match; + if (long_options[match].flag) { + *long_options[match].flag = long_options[match].val; + return (0); + } else + return (long_options[match].val); + } + + /* + * i_getopt_internal_ -- + * Parse argc/argv argument vector. Called by user level routines. + */ + static int + i_getopt_internal_(int nargc, char **nargv, const char *options, + const struct option *long_options, int *idx, int flags) + { + char *oli; /* option letter list index */ + int optchar, short_too; + static int posix_me_harder = -1; + + if (options == NULL) + return (-1); + + /* + * XXX Some GNU programs (like cvs) set optind to 0 instead of + * XXX using optreeset. Work around this braindamage. + */ + if (i_optind_ == 0) + i_optind_ = i_optreeset_ = 1; + + /* + * Disable GNU extensions if POSIXLY_CORRECT is set or options + * string begins with a '+'. + */ + if (posix_me_harder == -1 || i_optreeset_) + posix_me_harder = (getenv("POSIXLY_CORRECT") != NULL); + if (*options == '-') + flags |= I_FLAG_ALLARGS_; + else if (posix_me_harder || *options == '+') + flags &= ~I_FLAG_PERMUTE_; + if (*options == '+' || *options == '-') + options++; + + i_optarg_ = NULL; + if (i_optreeset_) + i_nonopt_start_ = i_nonopt_end_ = -1; + start: + if (i_optreeset_ || !*i_place_) { /* update scanning pointer */ + i_optreeset_ = 0; + if (i_optind_ >= nargc) { /* end of argument vector */ + i_place_ = I_EMSG_; + if (i_nonopt_end_ != -1) { + /* do permutation, if we have to */ + i_permute_args_(i_nonopt_start_, i_nonopt_end_, + i_optind_, nargv); + i_optind_ -= i_nonopt_end_ - i_nonopt_start_; + } else if (i_nonopt_start_ != -1) { + /* + * If we skipped non-options, set i_optind_ + * to the first of them. + */ + i_optind_ = i_nonopt_start_; + } + i_nonopt_start_ = i_nonopt_end_ = -1; + return (-1); + } + if (*(i_place_ = nargv[i_optind_]) != '-' || + (i_place_[1] == '\0' && strchr(options, '-') == NULL)) { + i_place_ = I_EMSG_; /* found non-option */ + if (flags & I_FLAG_ALLARGS_) { + /* + * GNU extension: + * return non-option as argument to option 1 + */ + i_optarg_ = nargv[i_optind_++]; + return (I_INORDER_); + } + if (!(flags & I_FLAG_PERMUTE_)) { + /* + * If no permutation wanted, stop parsing + * at first non-option. + */ + return (-1); + } + /* do permutation */ + if (i_nonopt_start_ == -1) { + i_nonopt_start_ = i_optind_; + } else if (i_nonopt_end_ != -1) { + i_permute_args_(i_nonopt_start_, i_nonopt_end_, + i_optind_, nargv); + i_nonopt_start_ = i_optind_ - + (i_nonopt_end_ - i_nonopt_start_); + i_nonopt_end_ = -1; + } + i_optind_++; + /* process next argument */ + goto start; + } + if (i_nonopt_start_ != -1 && i_nonopt_end_ == -1) + i_nonopt_end_ = i_optind_; + + /* + * If we have "-" do nothing, if "--" we are done. + */ + if (i_place_[1] != '\0' && *++i_place_ == '-' && i_place_[1] == '\0') { + i_optind_++; + i_place_ = I_EMSG_; + /* + * We found an option (--), so if we skipped + * non-options, we have to permute. + */ + if (i_nonopt_end_ != -1) { + i_permute_args_(i_nonopt_start_, i_nonopt_end_, + i_optind_, nargv); + i_optind_ -= i_nonopt_end_ - i_nonopt_start_; + } + i_nonopt_start_ = i_nonopt_end_ = -1; + return (-1); + } + } + + /* + * Check long options if: + * 1) we were passed some + * 2) the arg is not just "-" + * 3) either the arg starts with -- we are i_getopt_long_only() + */ + if (long_options != NULL && i_place_ != nargv[i_optind_] && + (*i_place_ == '-' || (flags & I_FLAG_LONGONLY_))) { + short_too = 0; + if (*i_place_ == '-') + i_place_++; /* --foo long option */ + else if (*i_place_ != ':' + && strchr(options, *i_place_) != NULL) + short_too = 1; /* could be short option too */ + + optchar = i_parse_long_options__(nargv, options, long_options, + idx, short_too); + if (optchar != -1) { + i_place_ = I_EMSG_; + return (optchar); + } + } + + if ((optchar = (int)*i_place_++) == (int)':' || + (optchar == (int)'-' && *i_place_ != '\0') || + (oli = strchr(options, optchar)) == NULL) { + /* + * If the user specified "-" and '-' isn't listed in + * options, return -1 (non-option) as per POSIX. + * Otherwise, it is an unknown option character (or ':'). + */ + if (optchar == (int)'-' && *i_place_ == '\0') + return (-1); + if (!*i_place_) + ++i_optind_; + if (I_PRINT_ERROR_) + i_warnx_(i_illoptchar_, optchar); + i_optopt_ = optchar; + return (I_BADCH_); + } + if (long_options != NULL && optchar == 'W' && oli[1] == ';') { + /* -W long-option */ + if (*i_place_) { /* no space */ + /* NOTHING */; + } else if (++i_optind_ >= nargc) { /* no arg */ + i_place_ = I_EMSG_; + if (I_PRINT_ERROR_) + i_warnx_(i_recargchar_, optchar); + i_optopt_ = optchar; + return (I_BADARG_); + } else { /* white space */ + i_place_ = nargv[i_optind_]; + } + optchar = i_parse_long_options__(nargv, options, long_options, + idx, 0); + i_place_ = I_EMSG_; + return (optchar); + } + if (*++oli != ':') { /* doesn't take argument */ + if (!*i_place_) + ++i_optind_; + } else { /* takes (optional) argument */ + i_optarg_ = NULL; + if (*i_place_) /* no white space */ + i_optarg_ = i_place_; + else if (oli[1] != ':') { /* arg not optional */ + if (++i_optind_ >= nargc) { /* no arg */ + i_place_ = I_EMSG_; + if (I_PRINT_ERROR_) + i_warnx_(i_recargchar_, optchar); + i_optopt_ = optchar; + return (I_BADARG_); + } else { + i_optarg_ = nargv[i_optind_]; + } + } + i_place_ = I_EMSG_; + ++i_optind_; + } + /* dump back option letter */ + return (optchar); + } + + int + i_getopt_(int argc, char *argv[], const char *optstring) + { + #ifdef GETOPT_PERMUTE_ARGS + return (i_getopt_internal_(argc, argv, optstring, NULL, NULL, + I_FLAG_PERMUTE_)); + #else + return (i_getopt_internal_(argc, argv, optstring, NULL, NULL, 0)); + #endif + } + + int + i_getopt_long_(int argc, char *argv[], const char *optstring, + const struct option *longopts, int *longindex) + { + #ifdef GETOPT_LONG_PERMUTE_ARGS + return (i_getopt_internal_(argc, argv, optstring, longopts, longindex, + I_FLAG_PERMUTE_)); + #else + return (i_getopt_internal_(argc, argv, optstring, longopts, longindex, 0)); + #endif + + } + + int + i_getopt_long_only_(int argc, char *argv[], const char *optstring, + const struct option *longopts, int *longindex) + { + #ifdef GETOPT_LONG_ONLY_PERMUTE_ARGS + return (i_getopt_internal_(argc, argv, optstring, longopts, longindex, + I_FLAG_PERMUTE_ | I_FLAG_LONGONLY_)); + #else + return (i_getopt_internal_(argc, argv, optstring, longopts, longindex, + I_FLAG_LONGONLY_)); + #endif + } + #endif /* GETOPT_LONG_IMPLEMENTATION */ +#endif /* !GETOPT_LONG_H_ */