41f59de5e50651a3e76a7f247ee07a15eb172ca9
[libcext.git] / getopt_long.h
1 /*
2 * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 *
16 * Sponsored in part by the Defense Advanced Research Projects
17 * Agency (DARPA) and Air Force Research Laboratory, Air Force
18 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
19 */
20
21 /*
22 * Copyright (c) 1990, 1993
23 * The Regents of the University of California. All rights reserved.
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. Neither the name of the University nor the names of its contributors
34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 */
49
50 /*
51 * Copyright (c) 2000 The NetBSD Foundation, Inc.
52 * All rights reserved.
53 *
54 * This code is derived from software contributed to The NetBSD Foundation
55 * by Dieter Baron and Thomas Klausner.
56 *
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
59 * are met:
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 *
66 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
67 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
68 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
69 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
70 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
71 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
72 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
73 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
74 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
75 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
76 * POSSIBILITY OF SUCH DAMAGE.
77 */
78
79 /* https://git.datadissipation.net */
80 #ifndef GETOPT_LONG_H_
81 #define GETOPT_LONG_H_ 1
82
83 #ifdef GETOPT_LONG_INCLUDE_LIBC
84 #include <stdarg.h>
85 #include <stdio.h>
86 #include <stdlib.h>
87 #include <string.h>
88 #endif /* GETOPT_LONG_INCLUDE_LIBC */
89
90 #ifndef HAVE_GETOPT_LONG
91 #define HAVE_GETOPT_LONG 1
92
93 #define no_argument 0
94 #define required_argument 1
95 #define optional_argument 2
96
97 /*
98 * structs are in their own namespace, so this should be OK
99 * the worst it can do is make compiler messages worse
100 */
101 #define option i_option_
102
103 #define optarg i_optarg_
104 #define suboptarg i_suboptarg_
105 #define optind i_optind_
106 #define opterr i_opterr_
107 #define optopt i_optopt_
108 #define optreset i_optreset_
109
110 #define getopt i_getopt_
111 #define getsubopt i_getsubopt_
112 #define getopt_long i_getopt_long_
113 #define getopt_long_only i_getopt_long_only_
114
115 #ifndef GETOPT_LONG_IMPLEMENTATION
116 extern char *i_optarg_;
117 extern char *i_suboptarg_;
118 extern int i_optind_, i_opterr_, i_optopt_, i_optreset_;
119 #endif /* !GETOPT_LONG_IMPLEMENTATION */
120
121 struct i_option_ {
122 const char *name;
123 /*
124 * one of no_argument, required_argument, and optional_argument:
125 * whether option takes an argument
126 */
127 int has_arg;
128 /* if not NULL, set *flag to val when option found */
129 int *flag;
130 /* if flag not NULL, value to set *flag to; else return value */
131 int val;
132 };
133
134 int i_getopt_(int argc, char * const *argv, const char *optstring);
135 int i_getsubopt_(char **optionp, char * const *tokens, char **valuep);
136 int i_getopt_long_(int argc, char * const *argv, const char *optstring,
137 const struct option *longopts, int *longindex);
138 int i_getopt_long_only_(int argc, char * const *argv, const char *optstring,
139 const struct option *longopts, int *longindex);
140
141 #endif /* !HAVE_GETOPT_LONG */
142
143 #ifdef GETOPT_LONG_IMPLEMENTATION
144 #define I_PRINT_ERROR_ ((i_opterr_) && (*options != ':'))
145
146 #define I_FLAG_PERMUTE_ 0x01 /* permute non-options to the end of argv */
147 #define I_FLAG_ALLARGS_ 0x02 /* treat non-options as args to option "-1" */
148 #define I_FLAG_LONGONLY_ 0x04 /* operate as getopt_long_only */
149
150 /* return values */
151 #define I_BADCH_ (int)'?'
152 #define I_BADARG_ ((*options == ':') ? (int)':' : (int)'?')
153 #define I_INORDER_ (int)1
154
155 #define I_EMSG_ ""
156
157 int i_opterr_ = 1; /* if error message should be printed */
158 int i_optind_ = 1; /* index into parent argv vector */
159 int i_optopt_ = '?'; /* character checked for validity */
160 int i_optreset_; /* reset getopt */
161 char *i_optarg_; /* argument associated with option */
162 char *i_suboptarg_; /* argument associated with suboption */
163
164 /* XXX: set optreset to 1 rather than these two */
165 static int i_nonopt_start_ = -1; /* first non option argument (for permute) */
166 static int i_nonopt_end_ = -1; /* first option after non options (for permute) */
167 static char *i_place_ = I_EMSG_; /* option letter processing */
168
169 /* Error messages */
170 static const char i_recargchar_[] = "option requires an argument -- %c";
171 static const char i_recargstring_[] = "option requires an argument -- %s";
172 static const char i_ambig_[] = "i_ambig_uous option -- %.*s";
173 static const char i_noarg_[] = "option doesn't take an argument -- %.*s";
174 static const char i_illoptchar_[] = "unknown option -- %c";
175 static const char i_illoptstring_[] = "unknown option -- %s";
176
177 static void i_warnx_(const char *, ...);
178 static int i_getopt_internal_(int, char * const *, const char *,
179 const struct option *, int *, int);
180 static int i_parse_long_options__(char * const *, const char *,
181 const struct option *, int *, int);
182 static int i_gcd_(int, int);
183 static void i_permute_args_(int, int, int, char * const *);
184
185 /*
186 * Own warnx() for portability
187 */
188 void
189 i_warnx_(const char *fmt, ...)
190 {
191 va_list args;
192
193 /* Linux "program_invocation_short_name" is a GNU extension, so we don't use it */
194 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
195 #define I_GET_PROG_NAME_() getprogname()
196 #else
197 #define I_GET_PROG_NAME_() "warnx"
198 #endif
199
200 va_start(args, fmt);
201 fprintf(stderr, "%s: ", I_GET_PROG_NAME_());
202 vfprintf(stderr, fmt, args);
203 fputc('\n', stderr);
204 va_end(args);
205 }
206
207 /*
208 * Compute the greatest common divisor of a and b.
209 */
210 static int
211 i_gcd_(int a, int b)
212 {
213 int c;
214
215 c = a % b;
216 while (c != 0) {
217 a = b;
218 b = c;
219 c = a % b;
220 }
221
222 return (b);
223 }
224
225 /*
226 * Exchange the block from nonopt_start to nonopt_end with the block
227 * from nonopt_end to opt_end (keeping the same order of arguments
228 * in each block).
229 */
230 static void
231 i_permute_args_(int panonopt_start, int panonopt_end, int opt_end,
232 char * const *nargv)
233 {
234 int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
235 char *swap;
236
237 /*
238 * compute lengths of blocks and number and size of cycles
239 */
240 nnonopts = panonopt_end - panonopt_start;
241 nopts = opt_end - panonopt_end;
242 ncycle = i_gcd_(nnonopts, nopts);
243 cyclelen = (opt_end - panonopt_start) / ncycle;
244
245 for (i = 0; i < ncycle; i++) {
246 cstart = panonopt_end+i;
247 pos = cstart;
248 for (j = 0; j < cyclelen; j++) {
249 if (pos >= panonopt_end)
250 pos -= nnonopts;
251 else
252 pos += nopts;
253 swap = nargv[pos];
254 /* LINTED const cast */
255 ((char **) nargv)[pos] = nargv[cstart];
256 /* LINTED const cast */
257 ((char **)nargv)[cstart] = swap;
258 }
259 }
260 }
261
262 /*
263 * i_parse_long_options__ --
264 * Parse long options in argc/argv argument vector.
265 * Returns -1 if short_too is set and the option does not match long_options.
266 */
267 static int
268 i_parse_long_options__(char * const *nargv, const char *options,
269 const struct option *long_options, int *idx, int short_too)
270 {
271 char *current_argv, *has_equal;
272 size_t current_argv_len;
273 int i, match;
274
275 current_argv = i_place_;
276 match = -1;
277
278 i_optind_++;
279
280 if ((has_equal = strchr(current_argv, '=')) != NULL) {
281 /* argument found (--option=arg) */
282 current_argv_len = has_equal - current_argv;
283 has_equal++;
284 } else {
285 current_argv_len = strlen(current_argv);
286 }
287 for (i = 0; long_options[i].name; i++) {
288 /* find matching long option */
289 if (strncmp(current_argv, long_options[i].name,
290 current_argv_len))
291 continue;
292
293 if (strlen(long_options[i].name) == current_argv_len) {
294 /* exact match */
295 match = i;
296 break;
297 }
298 /*
299 * If this is a known short option, don't allow
300 * a partial match of a single character.
301 */
302 if (short_too && current_argv_len == 1)
303 continue;
304
305 if (match == -1) { /* partial match */
306 match = i;
307 } else {
308 /* ambiguous abbreviation */
309 if (I_PRINT_ERROR_)
310 i_warnx_(i_ambig_, (int)current_argv_len,
311 current_argv);
312 i_optopt_ = 0;
313 return (I_BADCH_);
314 }
315 }
316 if (match != -1) { /* option found */
317 if (long_options[match].has_arg == no_argument
318 && has_equal) {
319 if (I_PRINT_ERROR_)
320 i_warnx_(i_noarg_, (int)current_argv_len,
321 current_argv);
322 /*
323 * XXX: GNU sets optopt to val regardless of flag
324 */
325 if (long_options[match].flag == NULL)
326 i_optopt_ = long_options[match].val;
327 else
328 i_optopt_ = 0;
329 return (I_BADARG_);
330 }
331 if (long_options[match].has_arg == required_argument ||
332 long_options[match].has_arg == optional_argument) {
333 if (has_equal)
334 i_optarg_ = has_equal;
335 else if (long_options[match].has_arg ==
336 required_argument) {
337 /*
338 * optional argument doesn't use next nargv
339 */
340 i_optarg_ = nargv[i_optind_++];
341 }
342 }
343 if ((long_options[match].has_arg == required_argument)
344 && (i_optarg_ == NULL)) {
345 /*
346 * Missing argument; leading ':' indicates no error
347 * should be generated.
348 */
349 if (I_PRINT_ERROR_)
350 i_warnx_(i_recargstring_,
351 current_argv);
352 /*
353 * XXX: GNU sets optopt to val regardless of flag
354 */
355 if (long_options[match].flag == NULL)
356 i_optopt_ = long_options[match].val;
357 else
358 i_optopt_ = 0;
359 --i_optind_;
360 return (I_BADARG_);
361 }
362 } else { /* unknown option */
363 if (short_too) {
364 --i_optind_;
365 return (-1);
366 }
367 if (I_PRINT_ERROR_)
368 i_warnx_(i_illoptstring_, current_argv);
369 i_optopt_ = 0;
370 return (I_BADCH_);
371 }
372 if (idx)
373 *idx = match;
374 if (long_options[match].flag) {
375 *long_options[match].flag = long_options[match].val;
376 return (0);
377 } else
378 return (long_options[match].val);
379 }
380
381 /*
382 * i_getopt_internal_ --
383 * Parse argc/argv argument vector. Called by user level routines.
384 */
385 static int
386 i_getopt_internal_(int nargc, char *const *nargv, const char *options,
387 const struct option *long_options, int *idx, int flags)
388 {
389 char *oli; /* option letter list index */
390 int optchar, short_too;
391 static int posix_me_harder = -1;
392
393 if (options == NULL)
394 return (-1);
395
396 /*
397 * XXX Some GNU programs (like cvs) set optind to 0 instead of
398 * XXX using optreset. Work around this braindamage.
399 */
400 if (i_optind_ == 0)
401 i_optind_ = i_optreset_ = 1;
402
403 /*
404 * Disable GNU extensions if POSIXLY_CORRECT is set or options
405 * string begins with a '+'.
406 */
407 if (posix_me_harder == -1 || i_optreset_)
408 posix_me_harder = (getenv("POSIXLY_CORRECT") != NULL);
409 if (*options == '-')
410 flags |= I_FLAG_ALLARGS_;
411 else if (posix_me_harder || *options == '+')
412 flags &= ~I_FLAG_PERMUTE_;
413 if (*options == '+' || *options == '-')
414 options++;
415
416 i_optarg_ = NULL;
417 if (i_optreset_)
418 i_nonopt_start_ = i_nonopt_end_ = -1;
419 start:
420 if (i_optreset_ || !*i_place_) { /* update scanning pointer */
421 i_optreset_ = 0;
422 if (i_optind_ >= nargc) { /* end of argument vector */
423 i_place_ = I_EMSG_;
424 if (i_nonopt_end_ != -1) {
425 /* do permutation, if we have to */
426 i_permute_args_(i_nonopt_start_, i_nonopt_end_,
427 i_optind_, nargv);
428 i_optind_ -= i_nonopt_end_ - i_nonopt_start_;
429 } else if (i_nonopt_start_ != -1) {
430 /*
431 * If we skipped non-options, set optind
432 * to the first of them.
433 */
434 i_optind_ = i_nonopt_start_;
435 }
436 i_nonopt_start_ = i_nonopt_end_ = -1;
437 return (-1);
438 }
439 if (*(i_place_ = nargv[i_optind_]) != '-' ||
440 (i_place_[1] == '\0' && strchr(options, '-') == NULL)) {
441 i_place_ = I_EMSG_; /* found non-option */
442 if (flags & I_FLAG_ALLARGS_) {
443 /*
444 * GNU extension:
445 * return non-option as argument to option 1
446 */
447 i_optarg_ = nargv[i_optind_++];
448 return (I_INORDER_);
449 }
450 if (!(flags & I_FLAG_PERMUTE_)) {
451 /*
452 * If no permutation wanted, stop parsing
453 * at first non-option.
454 */
455 return (-1);
456 }
457 /* do permutation */
458 if (i_nonopt_start_ == -1) {
459 i_nonopt_start_ = i_optind_;
460 } else if (i_nonopt_end_ != -1) {
461 i_permute_args_(i_nonopt_start_, i_nonopt_end_,
462 i_optind_, nargv);
463 i_nonopt_start_ = i_optind_ -
464 (i_nonopt_end_ - i_nonopt_start_);
465 i_nonopt_end_ = -1;
466 }
467 i_optind_++;
468 /* process next argument */
469 goto start;
470 }
471 if (i_nonopt_start_ != -1 && i_nonopt_end_ == -1)
472 i_nonopt_end_ = i_optind_;
473
474 /*
475 * If we have "-" do nothing, if "--" we are done.
476 */
477 if (i_place_[1] != '\0' && *++i_place_ == '-' && i_place_[1] == '\0') {
478 i_optind_++;
479 i_place_ = I_EMSG_;
480 /*
481 * We found an option (--), so if we skipped
482 * non-options, we have to permute.
483 */
484 if (i_nonopt_end_ != -1) {
485 i_permute_args_(i_nonopt_start_, i_nonopt_end_,
486 i_optind_, nargv);
487 i_optind_ -= i_nonopt_end_ - i_nonopt_start_;
488 }
489 i_nonopt_start_ = i_nonopt_end_ = -1;
490 return (-1);
491 }
492 }
493
494 /*
495 * Check long options if:
496 * 1) we were passed some
497 * 2) the arg is not just "-"
498 * 3) either the arg starts with -- we are i_getopt_long_only()
499 */
500 if (long_options != NULL && i_place_ != nargv[i_optind_] &&
501 (*i_place_ == '-' || (flags & I_FLAG_LONGONLY_))) {
502 short_too = 0;
503 if (*i_place_ == '-')
504 i_place_++; /* --foo long option */
505 else if (*i_place_ != ':'
506 && strchr(options, *i_place_) != NULL)
507 short_too = 1; /* could be short option too */
508
509 optchar = i_parse_long_options__(nargv, options, long_options,
510 idx, short_too);
511 if (optchar != -1) {
512 i_place_ = I_EMSG_;
513 return (optchar);
514 }
515 }
516
517 if ((optchar = (int)*i_place_++) == (int)':' ||
518 (optchar == (int)'-' && *i_place_ != '\0') ||
519 (oli = strchr(options, optchar)) == NULL) {
520 /*
521 * If the user specified "-" and '-' isn't listed in
522 * options, return -1 (non-option) as per POSIX.
523 * Otherwise, it is an unknown option character (or ':').
524 */
525 if (optchar == (int)'-' && *i_place_ == '\0')
526 return (-1);
527 if (!*i_place_)
528 ++i_optind_;
529 if (I_PRINT_ERROR_)
530 i_warnx_(i_illoptchar_, optchar);
531 i_optopt_ = optchar;
532 return (I_BADCH_);
533 }
534 if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
535 /* -W long-option */
536 if (*i_place_) { /* no space */
537 /* NOTHING */;
538 } else if (++i_optind_ >= nargc) { /* no arg */
539 i_place_ = I_EMSG_;
540 if (I_PRINT_ERROR_)
541 i_warnx_(i_recargchar_, optchar);
542 i_optopt_ = optchar;
543 return (I_BADARG_);
544 } else { /* white space */
545 i_place_ = nargv[i_optind_];
546 }
547 optchar = i_parse_long_options__(nargv, options, long_options,
548 idx, 0);
549 i_place_ = I_EMSG_;
550 return (optchar);
551 }
552 if (*++oli != ':') { /* doesn't take argument */
553 if (!*i_place_)
554 ++i_optind_;
555 } else { /* takes (optional) argument */
556 i_optarg_ = NULL;
557 if (*i_place_) /* no white space */
558 i_optarg_ = i_place_;
559 else if (oli[1] != ':') { /* arg not optional */
560 if (++i_optind_ >= nargc) { /* no arg */
561 i_place_ = I_EMSG_;
562 if (I_PRINT_ERROR_)
563 i_warnx_(i_recargchar_, optchar);
564 i_optopt_ = optchar;
565 return (I_BADARG_);
566 } else {
567 i_optarg_ = nargv[i_optind_];
568 }
569 }
570 i_place_ = I_EMSG_;
571 ++i_optind_;
572 }
573 /* dump back option letter */
574 return (optchar);
575 }
576
577 int
578 i_getsubopt_(char **optionp, char * const *tokens, char **valuep)
579 {
580 int cnt;
581 char *p;
582
583 i_suboptarg_ = *valuep = NULL;
584
585 if (!optionp || !*optionp)
586 return(-1);
587
588 /* skip leading white-space, commas */
589 for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
590
591 if (!*p) {
592 *optionp = p;
593 return(-1);
594 }
595
596 /* save the start of the token, and skip the rest of the token. */
597 for (i_suboptarg_ = p;
598 *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';);
599
600 if (*p) {
601 /*
602 * If there's an equals sign, set the value pointer, and
603 * skip over the value part of the token. Terminate the
604 * token.
605 */
606 if (*p == '=') {
607 *p = '\0';
608 for (*valuep = ++p;
609 *p && *p != ',' && *p != ' ' && *p != '\t'; ++p);
610 if (*p)
611 *p++ = '\0';
612 } else {
613 *p++ = '\0';
614 }
615 /* Skip any whitespace or commas after this token. */
616 for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p);
617 }
618
619 /* set optionp for next round. */
620 *optionp = p;
621
622 for (cnt = 0; *tokens; ++tokens, ++cnt)
623 if (!strcmp(i_suboptarg_, *tokens))
624 return(cnt);
625 return(-1);
626 }
627
628 int
629 i_getopt_(int argc, char * const *argv, const char *optstring)
630 {
631 #ifdef GETOPT_PERMUTE_ARGS
632 return (i_getopt_internal_(argc, argv, optstring, NULL, NULL,
633 I_FLAG_PERMUTE_));
634 #else
635 return (i_getopt_internal_(argc, argv, optstring, NULL, NULL, 0));
636 #endif
637 }
638
639 int
640 i_getopt_long_(int argc, char * const *argv, const char *optstring,
641 const struct option *longopts, int *longindex)
642 {
643 #ifdef GETOPT_LONG_PERMUTE_ARGS
644 return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
645 I_FLAG_PERMUTE_));
646 #else
647 return (i_getopt_internal_(argc, argv, optstring, longopts, longindex, 0));
648 #endif
649
650 }
651
652 int
653 i_getopt_long_only_(int argc, char * const *argv, const char *optstring,
654 const struct option *longopts, int *longindex)
655 {
656 #ifdef GETOPT_LONG_ONLY_PERMUTE_ARGS
657 return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
658 I_FLAG_PERMUTE_ | I_FLAG_LONGONLY_));
659 #else
660 return (i_getopt_internal_(argc, argv, optstring, longopts, longindex,
661 I_FLAG_LONGONLY_));
662 #endif
663 }
664 #endif /* GETOPT_LONG_IMPLEMENTATION */
665 #endif /* !GETOPT_LONG_H_ */