180814287SRaphael Isemann //===-- GetOptInc.cpp -----------------------------------------------------===//
2696bd635SAlexander Shaposhnikov //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6696bd635SAlexander Shaposhnikov //
7696bd635SAlexander Shaposhnikov //===----------------------------------------------------------------------===//
8696bd635SAlexander Shaposhnikov 
9a04668ffSPavel Labath #include "lldb/Host/common/GetOptInc.h"
10a04668ffSPavel Labath 
11b9c1b51eSKate Stone #if defined(REPLACE_GETOPT) || defined(REPLACE_GETOPT_LONG) ||                 \
12b9c1b51eSKate Stone     defined(REPLACE_GETOPT_LONG_ONLY)
13a04668ffSPavel Labath 
14a04668ffSPavel Labath // getopt.cpp
15*76e47d48SRaphael Isemann #include <cerrno>
16*76e47d48SRaphael Isemann #include <cstdlib>
17*76e47d48SRaphael Isemann #include <cstring>
18a04668ffSPavel Labath 
19a04668ffSPavel Labath #if defined(REPLACE_GETOPT)
20a04668ffSPavel Labath int opterr = 1;   /* if error message should be printed */
21a04668ffSPavel Labath int optind = 1;   /* index into parent argv vector */
22a04668ffSPavel Labath int optopt = '?'; /* character checked for validity */
23a04668ffSPavel Labath int optreset;     /* reset getopt */
24a04668ffSPavel Labath char *optarg;     /* argument associated with option */
25a04668ffSPavel Labath #endif
26a04668ffSPavel Labath 
27a04668ffSPavel Labath #define PRINT_ERROR ((opterr) && (*options != ':'))
28a04668ffSPavel Labath 
29a04668ffSPavel Labath #define FLAG_PERMUTE 0x01  /* permute non-options to the end of argv */
30a04668ffSPavel Labath #define FLAG_ALLARGS 0x02  /* treat non-options as args to option "-1" */
31a04668ffSPavel Labath #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
32a04668ffSPavel Labath 
33a04668ffSPavel Labath /* return values */
34a04668ffSPavel Labath #define BADCH (int)'?'
35a04668ffSPavel Labath #define BADARG ((*options == ':') ? (int)':' : (int)'?')
36a04668ffSPavel Labath #define INORDER (int)1
37a04668ffSPavel Labath 
38a04668ffSPavel Labath #define EMSG ""
39a04668ffSPavel Labath 
40a04668ffSPavel Labath static int getopt_internal(int, char *const *, const char *,
41a04668ffSPavel Labath                            const struct option *, int *, int);
42a04668ffSPavel Labath static int parse_long_options(char *const *, const char *,
43a04668ffSPavel Labath                               const struct option *, int *, int);
44a04668ffSPavel Labath static int gcd(int, int);
45a04668ffSPavel Labath static void permute_args(int, int, int, char *const *);
46a04668ffSPavel Labath 
47a04668ffSPavel Labath static const char *place = EMSG; /* option letter processing */
48a04668ffSPavel Labath 
49a04668ffSPavel Labath /* XXX: set optreset to 1 rather than these two */
50a04668ffSPavel Labath static int nonopt_start = -1; /* first non option argument (for permute) */
51a04668ffSPavel Labath static int nonopt_end = -1;   /* first option after non options (for permute) */
52a04668ffSPavel Labath 
53a04668ffSPavel Labath /*
54a04668ffSPavel Labath * Compute the greatest common divisor of a and b.
55a04668ffSPavel Labath */
gcd(int a,int b)56b9c1b51eSKate Stone static int gcd(int a, int b) {
57a04668ffSPavel Labath   int c;
58a04668ffSPavel Labath 
59a04668ffSPavel Labath   c = a % b;
60a04668ffSPavel Labath   while (c != 0) {
61a04668ffSPavel Labath     a = b;
62a04668ffSPavel Labath     b = c;
63a04668ffSPavel Labath     c = a % b;
64a04668ffSPavel Labath   }
65a04668ffSPavel Labath 
66a04668ffSPavel Labath   return (b);
67a04668ffSPavel Labath }
68a04668ffSPavel Labath 
pass()69a04668ffSPavel Labath static void pass() {}
70a04668ffSPavel Labath #define warnx(a, ...) pass();
71a04668ffSPavel Labath 
72a04668ffSPavel Labath /*
73a04668ffSPavel Labath * Exchange the block from nonopt_start to nonopt_end with the block
74a04668ffSPavel Labath * from nonopt_end to opt_end (keeping the same order of arguments
75a04668ffSPavel Labath * in each block).
76a04668ffSPavel Labath */
permute_args(int panonopt_start,int panonopt_end,int opt_end,char * const * nargv)77b9c1b51eSKate Stone static void permute_args(int panonopt_start, int panonopt_end, int opt_end,
78b9c1b51eSKate Stone                          char *const *nargv) {
79a04668ffSPavel Labath   int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
80a04668ffSPavel Labath   char *swap;
81a04668ffSPavel Labath 
82a04668ffSPavel Labath   /*
83a04668ffSPavel Labath   * compute lengths of blocks and number and size of cycles
84a04668ffSPavel Labath   */
85a04668ffSPavel Labath   nnonopts = panonopt_end - panonopt_start;
86a04668ffSPavel Labath   nopts = opt_end - panonopt_end;
87a04668ffSPavel Labath   ncycle = gcd(nnonopts, nopts);
88a04668ffSPavel Labath   cyclelen = (opt_end - panonopt_start) / ncycle;
89a04668ffSPavel Labath 
90a04668ffSPavel Labath   for (i = 0; i < ncycle; i++) {
91a04668ffSPavel Labath     cstart = panonopt_end + i;
92a04668ffSPavel Labath     pos = cstart;
93a04668ffSPavel Labath     for (j = 0; j < cyclelen; j++) {
94a04668ffSPavel Labath       if (pos >= panonopt_end)
95a04668ffSPavel Labath         pos -= nnonopts;
96a04668ffSPavel Labath       else
97a04668ffSPavel Labath         pos += nopts;
98a04668ffSPavel Labath       swap = nargv[pos];
99a04668ffSPavel Labath       /* LINTED const cast */
100b0717666SAlexandre Ganea       const_cast<char **>(nargv)[pos] = nargv[cstart];
101a04668ffSPavel Labath       /* LINTED const cast */
102b0717666SAlexandre Ganea       const_cast<char **>(nargv)[cstart] = swap;
103a04668ffSPavel Labath     }
104a04668ffSPavel Labath   }
105a04668ffSPavel Labath }
106a04668ffSPavel Labath 
107a04668ffSPavel Labath /*
108a04668ffSPavel Labath * parse_long_options --
109a04668ffSPavel Labath *  Parse long options in argc/argv argument vector.
110a04668ffSPavel Labath * Returns -1 if short_too is set and the option does not match long_options.
111a04668ffSPavel Labath */
parse_long_options(char * const * nargv,const char * options,const struct option * long_options,int * idx,int short_too)112b9c1b51eSKate Stone static int parse_long_options(char *const *nargv, const char *options,
113b9c1b51eSKate Stone                               const struct option *long_options, int *idx,
114b9c1b51eSKate Stone                               int short_too) {
115a04668ffSPavel Labath   char *current_argv, *has_equal;
116a04668ffSPavel Labath   size_t current_argv_len;
117a04668ffSPavel Labath   int i, match;
118a04668ffSPavel Labath 
119a04668ffSPavel Labath   current_argv = const_cast<char *>(place);
120a04668ffSPavel Labath   match = -1;
121a04668ffSPavel Labath 
122a04668ffSPavel Labath   optind++;
123a04668ffSPavel Labath 
124a04668ffSPavel Labath   if ((has_equal = strchr(current_argv, '=')) != NULL) {
125a04668ffSPavel Labath     /* argument found (--option=arg) */
126a04668ffSPavel Labath     current_argv_len = has_equal - current_argv;
127a04668ffSPavel Labath     has_equal++;
128b9c1b51eSKate Stone   } else
129a04668ffSPavel Labath     current_argv_len = strlen(current_argv);
130a04668ffSPavel Labath 
131a04668ffSPavel Labath   for (i = 0; long_options[i].name; i++) {
132a04668ffSPavel Labath     /* find matching long option */
133b9c1b51eSKate Stone     if (strncmp(current_argv, long_options[i].name, current_argv_len))
134a04668ffSPavel Labath       continue;
135a04668ffSPavel Labath 
136a04668ffSPavel Labath     if (strlen(long_options[i].name) == current_argv_len) {
137a04668ffSPavel Labath       /* exact match */
138a04668ffSPavel Labath       match = i;
139a04668ffSPavel Labath       break;
140a04668ffSPavel Labath     }
141a04668ffSPavel Labath     /*
142a04668ffSPavel Labath     * If this is a known short option, don't allow
143a04668ffSPavel Labath     * a partial match of a single character.
144a04668ffSPavel Labath     */
145a04668ffSPavel Labath     if (short_too && current_argv_len == 1)
146a04668ffSPavel Labath       continue;
147a04668ffSPavel Labath 
148a04668ffSPavel Labath     if (match == -1) /* partial match */
149a04668ffSPavel Labath       match = i;
150a04668ffSPavel Labath     else {
151a04668ffSPavel Labath       /* ambiguous abbreviation */
152a04668ffSPavel Labath       if (PRINT_ERROR)
153b9c1b51eSKate Stone         warnx(ambig, (int)current_argv_len, current_argv);
154a04668ffSPavel Labath       optopt = 0;
155a04668ffSPavel Labath       return (BADCH);
156a04668ffSPavel Labath     }
157a04668ffSPavel Labath   }
158a04668ffSPavel Labath   if (match != -1) { /* option found */
159b9c1b51eSKate Stone     if (long_options[match].has_arg == no_argument && has_equal) {
160a04668ffSPavel Labath       if (PRINT_ERROR)
161b9c1b51eSKate Stone         warnx(noarg, (int)current_argv_len, current_argv);
162a04668ffSPavel Labath       /*
163a04668ffSPavel Labath       * XXX: GNU sets optopt to val regardless of flag
164a04668ffSPavel Labath       */
165a04668ffSPavel Labath       if (long_options[match].flag == NULL)
166a04668ffSPavel Labath         optopt = long_options[match].val;
167a04668ffSPavel Labath       else
168a04668ffSPavel Labath         optopt = 0;
169a04668ffSPavel Labath       return (BADARG);
170a04668ffSPavel Labath     }
171a04668ffSPavel Labath     if (long_options[match].has_arg == required_argument ||
172a04668ffSPavel Labath         long_options[match].has_arg == optional_argument) {
173a04668ffSPavel Labath       if (has_equal)
174a04668ffSPavel Labath         optarg = has_equal;
175b9c1b51eSKate Stone       else if (long_options[match].has_arg == required_argument) {
176a04668ffSPavel Labath         /*
177a04668ffSPavel Labath         * optional argument doesn't use next nargv
178a04668ffSPavel Labath         */
179a04668ffSPavel Labath         optarg = nargv[optind++];
180a04668ffSPavel Labath       }
181a04668ffSPavel Labath     }
182b9c1b51eSKate Stone     if ((long_options[match].has_arg == required_argument) &&
183b9c1b51eSKate Stone         (optarg == NULL)) {
184a04668ffSPavel Labath       /*
185a04668ffSPavel Labath       * Missing argument; leading ':' indicates no error
186a04668ffSPavel Labath       * should be generated.
187a04668ffSPavel Labath       */
188a04668ffSPavel Labath       if (PRINT_ERROR)
189b9c1b51eSKate Stone         warnx(recargstring, current_argv);
190a04668ffSPavel Labath       /*
191a04668ffSPavel Labath       * XXX: GNU sets optopt to val regardless of flag
192a04668ffSPavel Labath       */
193a04668ffSPavel Labath       if (long_options[match].flag == NULL)
194a04668ffSPavel Labath         optopt = long_options[match].val;
195a04668ffSPavel Labath       else
196a04668ffSPavel Labath         optopt = 0;
197a04668ffSPavel Labath       --optind;
198a04668ffSPavel Labath       return (BADARG);
199a04668ffSPavel Labath     }
200b9c1b51eSKate Stone   } else { /* unknown option */
201a04668ffSPavel Labath     if (short_too) {
202a04668ffSPavel Labath       --optind;
203a04668ffSPavel Labath       return (-1);
204a04668ffSPavel Labath     }
205a04668ffSPavel Labath     if (PRINT_ERROR)
206a04668ffSPavel Labath       warnx(illoptstring, current_argv);
207a04668ffSPavel Labath     optopt = 0;
208a04668ffSPavel Labath     return (BADCH);
209a04668ffSPavel Labath   }
210a04668ffSPavel Labath   if (idx)
211a04668ffSPavel Labath     *idx = match;
212a04668ffSPavel Labath   if (long_options[match].flag) {
213a04668ffSPavel Labath     *long_options[match].flag = long_options[match].val;
214a04668ffSPavel Labath     return (0);
215b9c1b51eSKate Stone   } else
216a04668ffSPavel Labath     return (long_options[match].val);
217a04668ffSPavel Labath }
218a04668ffSPavel Labath 
219a04668ffSPavel Labath /*
220a04668ffSPavel Labath * getopt_internal --
221a04668ffSPavel Labath *  Parse argc/argv argument vector.  Called by user level routines.
222a04668ffSPavel Labath */
getopt_internal(int nargc,char * const * nargv,const char * options,const struct option * long_options,int * idx,int flags)223b9c1b51eSKate Stone static int getopt_internal(int nargc, char *const *nargv, const char *options,
224b9c1b51eSKate Stone                            const struct option *long_options, int *idx,
225b9c1b51eSKate Stone                            int flags) {
226a04668ffSPavel Labath   const char *oli; /* option letter list index */
227a04668ffSPavel Labath   int optchar, short_too;
228a04668ffSPavel Labath   static int posixly_correct = -1;
229a04668ffSPavel Labath 
230a04668ffSPavel Labath   if (options == NULL)
231a04668ffSPavel Labath     return (-1);
232a04668ffSPavel Labath 
233a04668ffSPavel Labath   /*
234a04668ffSPavel Labath   * XXX Some GNU programs (like cvs) set optind to 0 instead of
235a04668ffSPavel Labath   * XXX using optreset.  Work around this braindamage.
236a04668ffSPavel Labath   */
237a04668ffSPavel Labath   if (optind == 0)
238a04668ffSPavel Labath     optind = optreset = 1;
239a04668ffSPavel Labath 
240a04668ffSPavel Labath   /*
241a04668ffSPavel Labath   * Disable GNU extensions if POSIXLY_CORRECT is set or options
242a04668ffSPavel Labath   * string begins with a '+'.
243a04668ffSPavel Labath   */
244a04668ffSPavel Labath   if (posixly_correct == -1 || optreset)
245a04668ffSPavel Labath     posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
246a04668ffSPavel Labath   if (*options == '-')
247a04668ffSPavel Labath     flags |= FLAG_ALLARGS;
248a04668ffSPavel Labath   else if (posixly_correct || *options == '+')
249a04668ffSPavel Labath     flags &= ~FLAG_PERMUTE;
250a04668ffSPavel Labath   if (*options == '+' || *options == '-')
251a04668ffSPavel Labath     options++;
252a04668ffSPavel Labath 
253a04668ffSPavel Labath   optarg = NULL;
254a04668ffSPavel Labath   if (optreset)
255a04668ffSPavel Labath     nonopt_start = nonopt_end = -1;
256a04668ffSPavel Labath start:
257a04668ffSPavel Labath   if (optreset || !*place) { /* update scanning pointer */
258a04668ffSPavel Labath     optreset = 0;
259a04668ffSPavel Labath     if (optind >= nargc) { /* end of argument vector */
260a04668ffSPavel Labath       place = EMSG;
261a04668ffSPavel Labath       if (nonopt_end != -1) {
262a04668ffSPavel Labath         /* do permutation, if we have to */
263b9c1b51eSKate Stone         permute_args(nonopt_start, nonopt_end, optind, nargv);
264a04668ffSPavel Labath         optind -= nonopt_end - nonopt_start;
265b9c1b51eSKate Stone       } else if (nonopt_start != -1) {
266a04668ffSPavel Labath         /*
267a04668ffSPavel Labath         * If we skipped non-options, set optind
268a04668ffSPavel Labath         * to the first of them.
269a04668ffSPavel Labath         */
270a04668ffSPavel Labath         optind = nonopt_start;
271a04668ffSPavel Labath       }
272a04668ffSPavel Labath       nonopt_start = nonopt_end = -1;
273a04668ffSPavel Labath       return (-1);
274a04668ffSPavel Labath     }
275a04668ffSPavel Labath     if (*(place = nargv[optind]) != '-' ||
276a04668ffSPavel Labath         (place[1] == '\0' && strchr(options, '-') == NULL)) {
277a04668ffSPavel Labath       place = EMSG; /* found non-option */
278a04668ffSPavel Labath       if (flags & FLAG_ALLARGS) {
279a04668ffSPavel Labath         /*
280a04668ffSPavel Labath         * GNU extension:
281a04668ffSPavel Labath         * return non-option as argument to option 1
282a04668ffSPavel Labath         */
283a04668ffSPavel Labath         optarg = nargv[optind++];
284a04668ffSPavel Labath         return (INORDER);
285a04668ffSPavel Labath       }
286a04668ffSPavel Labath       if (!(flags & FLAG_PERMUTE)) {
287a04668ffSPavel Labath         /*
288a04668ffSPavel Labath         * If no permutation wanted, stop parsing
289a04668ffSPavel Labath         * at first non-option.
290a04668ffSPavel Labath         */
291a04668ffSPavel Labath         return (-1);
292a04668ffSPavel Labath       }
293a04668ffSPavel Labath       /* do permutation */
294a04668ffSPavel Labath       if (nonopt_start == -1)
295a04668ffSPavel Labath         nonopt_start = optind;
296a04668ffSPavel Labath       else if (nonopt_end != -1) {
297b9c1b51eSKate Stone         permute_args(nonopt_start, nonopt_end, optind, nargv);
298b9c1b51eSKate Stone         nonopt_start = optind - (nonopt_end - nonopt_start);
299a04668ffSPavel Labath         nonopt_end = -1;
300a04668ffSPavel Labath       }
301a04668ffSPavel Labath       optind++;
302a04668ffSPavel Labath       /* process next argument */
303a04668ffSPavel Labath       goto start;
304a04668ffSPavel Labath     }
305a04668ffSPavel Labath     if (nonopt_start != -1 && nonopt_end == -1)
306a04668ffSPavel Labath       nonopt_end = optind;
307a04668ffSPavel Labath 
308a04668ffSPavel Labath     /*
309a04668ffSPavel Labath     * If we have "-" do nothing, if "--" we are done.
310a04668ffSPavel Labath     */
311a04668ffSPavel Labath     if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
312a04668ffSPavel Labath       optind++;
313a04668ffSPavel Labath       place = EMSG;
314a04668ffSPavel Labath       /*
315a04668ffSPavel Labath       * We found an option (--), so if we skipped
316a04668ffSPavel Labath       * non-options, we have to permute.
317a04668ffSPavel Labath       */
318a04668ffSPavel Labath       if (nonopt_end != -1) {
319b9c1b51eSKate Stone         permute_args(nonopt_start, nonopt_end, optind, nargv);
320a04668ffSPavel Labath         optind -= nonopt_end - nonopt_start;
321a04668ffSPavel Labath       }
322a04668ffSPavel Labath       nonopt_start = nonopt_end = -1;
323a04668ffSPavel Labath       return (-1);
324a04668ffSPavel Labath     }
325a04668ffSPavel Labath   }
326a04668ffSPavel Labath 
327a04668ffSPavel Labath   /*
328a04668ffSPavel Labath   * Check long options if:
329a04668ffSPavel Labath   *  1) we were passed some
330a04668ffSPavel Labath   *  2) the arg is not just "-"
331a04668ffSPavel Labath   *  3) either the arg starts with -- we are getopt_long_only()
332a04668ffSPavel Labath   */
333a04668ffSPavel Labath   if (long_options != NULL && place != nargv[optind] &&
334a04668ffSPavel Labath       (*place == '-' || (flags & FLAG_LONGONLY))) {
335a04668ffSPavel Labath     short_too = 0;
336a04668ffSPavel Labath     if (*place == '-')
337a04668ffSPavel Labath       place++; /* --foo long option */
338a04668ffSPavel Labath     else if (*place != ':' && strchr(options, *place) != NULL)
339a04668ffSPavel Labath       short_too = 1; /* could be short option too */
340a04668ffSPavel Labath 
341b9c1b51eSKate Stone     optchar = parse_long_options(nargv, options, long_options, idx, short_too);
342a04668ffSPavel Labath     if (optchar != -1) {
343a04668ffSPavel Labath       place = EMSG;
344a04668ffSPavel Labath       return (optchar);
345a04668ffSPavel Labath     }
346a04668ffSPavel Labath   }
347a04668ffSPavel Labath 
348a04668ffSPavel Labath   if ((optchar = (int)*place++) == (int)':' ||
349a04668ffSPavel Labath       (optchar == (int)'-' && *place != '\0') ||
350a04668ffSPavel Labath       (oli = strchr(options, optchar)) == NULL) {
351a04668ffSPavel Labath     /*
352a04668ffSPavel Labath     * If the user specified "-" and  '-' isn't listed in
353a04668ffSPavel Labath     * options, return -1 (non-option) as per POSIX.
354a04668ffSPavel Labath     * Otherwise, it is an unknown option character (or ':').
355a04668ffSPavel Labath     */
356a04668ffSPavel Labath     if (optchar == (int)'-' && *place == '\0')
357a04668ffSPavel Labath       return (-1);
358a04668ffSPavel Labath     if (!*place)
359a04668ffSPavel Labath       ++optind;
360a04668ffSPavel Labath     if (PRINT_ERROR)
361a04668ffSPavel Labath       warnx(illoptchar, optchar);
362a04668ffSPavel Labath     optopt = optchar;
363a04668ffSPavel Labath     return (BADCH);
364a04668ffSPavel Labath   }
365a04668ffSPavel Labath   if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
366a04668ffSPavel Labath     /* -W long-option */
367a04668ffSPavel Labath     if (*place) /* no space */
368a04668ffSPavel Labath       /* NOTHING */;
369a04668ffSPavel Labath     else if (++optind >= nargc) { /* no arg */
370a04668ffSPavel Labath       place = EMSG;
371a04668ffSPavel Labath       if (PRINT_ERROR)
372a04668ffSPavel Labath         warnx(recargchar, optchar);
373a04668ffSPavel Labath       optopt = optchar;
374a04668ffSPavel Labath       return (BADARG);
375b9c1b51eSKate Stone     } else /* white space */
376a04668ffSPavel Labath       place = nargv[optind];
377b9c1b51eSKate Stone     optchar = parse_long_options(nargv, options, long_options, idx, 0);
378a04668ffSPavel Labath     place = EMSG;
379a04668ffSPavel Labath     return (optchar);
380a04668ffSPavel Labath   }
381a04668ffSPavel Labath   if (*++oli != ':') { /* doesn't take argument */
382a04668ffSPavel Labath     if (!*place)
383a04668ffSPavel Labath       ++optind;
384b9c1b51eSKate Stone   } else { /* takes (optional) argument */
385a04668ffSPavel Labath     optarg = NULL;
386a04668ffSPavel Labath     if (*place) /* no white space */
387a04668ffSPavel Labath       optarg = const_cast<char *>(place);
388a04668ffSPavel Labath     else if (oli[1] != ':') {  /* arg not optional */
389a04668ffSPavel Labath       if (++optind >= nargc) { /* no arg */
390a04668ffSPavel Labath         place = EMSG;
391a04668ffSPavel Labath         if (PRINT_ERROR)
392a04668ffSPavel Labath           warnx(recargchar, optchar);
393a04668ffSPavel Labath         optopt = optchar;
394a04668ffSPavel Labath         return (BADARG);
395b9c1b51eSKate Stone       } else
396a04668ffSPavel Labath         optarg = nargv[optind];
397a04668ffSPavel Labath     }
398a04668ffSPavel Labath     place = EMSG;
399a04668ffSPavel Labath     ++optind;
400a04668ffSPavel Labath   }
401a04668ffSPavel Labath   /* dump back option letter */
402a04668ffSPavel Labath   return (optchar);
403a04668ffSPavel Labath }
404a04668ffSPavel Labath 
405a04668ffSPavel Labath /*
406a04668ffSPavel Labath * getopt --
407a04668ffSPavel Labath *  Parse argc/argv argument vector.
408a04668ffSPavel Labath *
409a04668ffSPavel Labath * [eventually this will replace the BSD getopt]
410a04668ffSPavel Labath */
411a04668ffSPavel Labath #if defined(REPLACE_GETOPT)
getopt(int nargc,char * const * nargv,const char * options)412b9c1b51eSKate Stone int getopt(int nargc, char *const *nargv, const char *options) {
413a04668ffSPavel Labath 
414a04668ffSPavel Labath   /*
415a04668ffSPavel Labath   * We don't pass FLAG_PERMUTE to getopt_internal() since
416a04668ffSPavel Labath   * the BSD getopt(3) (unlike GNU) has never done this.
417a04668ffSPavel Labath   *
418a04668ffSPavel Labath   * Furthermore, since many privileged programs call getopt()
419a04668ffSPavel Labath   * before dropping privileges it makes sense to keep things
420a04668ffSPavel Labath   * as simple (and bug-free) as possible.
421a04668ffSPavel Labath   */
422a04668ffSPavel Labath   return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
423a04668ffSPavel Labath }
424a04668ffSPavel Labath #endif
425a04668ffSPavel Labath 
426a04668ffSPavel Labath /*
427a04668ffSPavel Labath * getopt_long --
428a04668ffSPavel Labath *  Parse argc/argv argument vector.
429a04668ffSPavel Labath */
430a04668ffSPavel Labath #if defined(REPLACE_GETOPT_LONG)
getopt_long(int nargc,char * const * nargv,const char * options,const struct option * long_options,int * idx)431b9c1b51eSKate Stone int getopt_long(int nargc, char *const *nargv, const char *options,
432b9c1b51eSKate Stone                 const struct option *long_options, int *idx) {
433b9c1b51eSKate Stone   return (
434b9c1b51eSKate Stone       getopt_internal(nargc, nargv, options, long_options, idx, FLAG_PERMUTE));
435a04668ffSPavel Labath }
436a04668ffSPavel Labath #endif
437a04668ffSPavel Labath 
438a04668ffSPavel Labath /*
439a04668ffSPavel Labath * getopt_long_only --
440a04668ffSPavel Labath *  Parse argc/argv argument vector.
441a04668ffSPavel Labath */
442a04668ffSPavel Labath #if defined(REPLACE_GETOPT_LONG_ONLY)
getopt_long_only(int nargc,char * const * nargv,const char * options,const struct option * long_options,int * idx)443b9c1b51eSKate Stone int getopt_long_only(int nargc, char *const *nargv, const char *options,
444b9c1b51eSKate Stone                      const struct option *long_options, int *idx) {
445a04668ffSPavel Labath 
446a04668ffSPavel Labath   return (getopt_internal(nargc, nargv, options, long_options, idx,
447a04668ffSPavel Labath                           FLAG_PERMUTE | FLAG_LONGONLY));
448a04668ffSPavel Labath }
449a04668ffSPavel Labath #endif
450a04668ffSPavel Labath 
451a04668ffSPavel Labath #endif
452