/src/tmux/compat/getopt_long.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* This file is obtained from OpenSSH: |
2 | | * Repository: https://github.com/openssh/openssh-portable |
3 | | * Commit: b5b405fee7f3e79d44e2d2971a4b6b4cc53f112e |
4 | | * File: /openbsd-compat/getopt_long.c */ |
5 | | |
6 | | /* |
7 | | * Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com> |
8 | | * |
9 | | * Permission to use, copy, modify, and distribute this software for any |
10 | | * purpose with or without fee is hereby granted, provided that the above |
11 | | * copyright notice and this permission notice appear in all copies. |
12 | | * |
13 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
14 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
15 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
16 | | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
17 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
18 | | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
19 | | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
20 | | * |
21 | | * Sponsored in part by the Defense Advanced Research Projects |
22 | | * Agency (DARPA) and Air Force Research Laboratory, Air Force |
23 | | * Materiel Command, USAF, under agreement number F39502-99-1-0512. |
24 | | */ |
25 | | /*- |
26 | | * Copyright (c) 2000 The NetBSD Foundation, Inc. |
27 | | * All rights reserved. |
28 | | * |
29 | | * This code is derived from software contributed to The NetBSD Foundation |
30 | | * by Dieter Baron and Thomas Klausner. |
31 | | * |
32 | | * Redistribution and use in source and binary forms, with or without |
33 | | * modification, are permitted provided that the following conditions |
34 | | * are met: |
35 | | * 1. Redistributions of source code must retain the above copyright |
36 | | * notice, this list of conditions and the following disclaimer. |
37 | | * 2. Redistributions in binary form must reproduce the above copyright |
38 | | * notice, this list of conditions and the following disclaimer in the |
39 | | * documentation and/or other materials provided with the distribution. |
40 | | * |
41 | | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
42 | | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
43 | | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
44 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
45 | | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
46 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
47 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
48 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
49 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
50 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
51 | | * POSSIBILITY OF SUCH DAMAGE. |
52 | | */ |
53 | | |
54 | | /* OPENBSD ORIGINAL: lib/libc/stdlib/getopt_long.c */ |
55 | | #include "compat.h" |
56 | | |
57 | | /* The following macro constants are taken from getopt.h of OpenSSH: |
58 | | * Repository: https://github.com/openssh/openssh-portable |
59 | | * Commit: b5b405fee7f3e79d44e2d2971a4b6b4cc53f112e |
60 | | * File: /openbsd-compat/getopt.h |
61 | | * |
62 | | * ---- BEGIN - Copyright notice and license of getopt.h ---- |
63 | | * Copyright (c) 2000 The NetBSD Foundation, Inc. |
64 | | * All rights reserved. |
65 | | * |
66 | | * This code is derived from software contributed to The NetBSD Foundation |
67 | | * by Dieter Baron and Thomas Klausner. |
68 | | * |
69 | | * Redistribution and use in source and binary forms, with or without |
70 | | * modification, are permitted provided that the following conditions |
71 | | * are met: |
72 | | * 1. Redistributions of source code must retain the above copyright |
73 | | * notice, this list of conditions and the following disclaimer. |
74 | | * 2. Redistributions in binary form must reproduce the above copyright |
75 | | * notice, this list of conditions and the following disclaimer in the |
76 | | * documentation and/or other materials provided with the distribution. |
77 | | * |
78 | | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
79 | | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
80 | | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
81 | | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
82 | | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
83 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
84 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
85 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
86 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
87 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
88 | | * POSSIBILITY OF SUCH DAMAGE. |
89 | | * ---- END ---- |
90 | | */ |
91 | 0 | #define no_argument 0 |
92 | 0 | #define required_argument 1 |
93 | 0 | #define optional_argument 2 |
94 | | |
95 | | #if !defined(HAVE_GETOPT) || !defined(HAVE_GETOPT_OPTRESET) |
96 | | |
97 | | #if 0 |
98 | | #include <err.h> |
99 | | #include <getopt.h> |
100 | | #endif |
101 | | #include <errno.h> |
102 | | #include <stdlib.h> |
103 | | #include <string.h> |
104 | | #include <stdarg.h> |
105 | | |
106 | | struct option { |
107 | | /* name of long option */ |
108 | | const char *name; |
109 | | /* |
110 | | * one of no_argument, required_argument, and optional_argument: |
111 | | * whether option takes an argument |
112 | | */ |
113 | | int has_arg; |
114 | | /* if not NULL, set *flag to val when option found */ |
115 | | int *flag; |
116 | | /* if flag not NULL, value to set *flag to; else return value */ |
117 | | int val; |
118 | | }; |
119 | | |
120 | | int opterr = 1; /* if error message should be printed */ |
121 | | int optind = 1; /* index into parent argv vector */ |
122 | | int optopt = '?'; /* character checked for validity */ |
123 | | int optreset; /* reset getopt */ |
124 | | char *optarg; /* argument associated with option */ |
125 | | |
126 | 0 | #define PRINT_ERROR ((opterr) && (*options != ':')) |
127 | | |
128 | 0 | #define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */ |
129 | 0 | #define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */ |
130 | 0 | #define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */ |
131 | | |
132 | | /* return values */ |
133 | 0 | #define BADCH (int)'?' |
134 | 0 | #define BADARG ((*options == ':') ? (int)':' : (int)'?') |
135 | 0 | #define INORDER (int)1 |
136 | | |
137 | 0 | #define EMSG (char *)"" |
138 | | |
139 | | static int getopt_internal(int, char * const *, const char *, |
140 | | const struct option *, int *, int); |
141 | | static int parse_long_options(char * const *, const char *, |
142 | | const struct option *, int *, int); |
143 | | static int gcd(int, int); |
144 | | static void permute_args(int, int, int, char * const *); |
145 | | |
146 | | static char *place = EMSG; /* option letter processing */ |
147 | | |
148 | | /* XXX: set optreset to 1 rather than these two */ |
149 | | static int nonopt_start = -1; /* first non option argument (for permute) */ |
150 | | static int nonopt_end = -1; /* first option after non options (for permute) */ |
151 | | |
152 | | /* Error messages */ |
153 | | static const char recargchar[] = "option requires an argument -- %c"; |
154 | | static const char recargstring[] = "option requires an argument -- %s"; |
155 | | static const char ambig[] = "ambiguous option -- %.*s"; |
156 | | static const char noarg[] = "option doesn't take an argument -- %.*s"; |
157 | | static const char illoptchar[] = "unknown option -- %c"; |
158 | | static const char illoptstring[] = "unknown option -- %s"; |
159 | | |
160 | | /* |
161 | | * Compute the greatest common divisor of a and b. |
162 | | */ |
163 | | static int |
164 | | gcd(int a, int b) |
165 | 0 | { |
166 | 0 | int c; |
167 | |
|
168 | 0 | c = a % b; |
169 | 0 | while (c != 0) { |
170 | 0 | a = b; |
171 | 0 | b = c; |
172 | 0 | c = a % b; |
173 | 0 | } |
174 | |
|
175 | 0 | return (b); |
176 | 0 | } |
177 | | |
178 | | /* |
179 | | * Exchange the block from nonopt_start to nonopt_end with the block |
180 | | * from nonopt_end to opt_end (keeping the same order of arguments |
181 | | * in each block). |
182 | | */ |
183 | | static void |
184 | | permute_args(int panonopt_start, int panonopt_end, int opt_end, |
185 | | char * const *nargv) |
186 | 0 | { |
187 | 0 | int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos; |
188 | 0 | char *swap; |
189 | | |
190 | | /* |
191 | | * compute lengths of blocks and number and size of cycles |
192 | | */ |
193 | 0 | nnonopts = panonopt_end - panonopt_start; |
194 | 0 | nopts = opt_end - panonopt_end; |
195 | 0 | ncycle = gcd(nnonopts, nopts); |
196 | 0 | cyclelen = (opt_end - panonopt_start) / ncycle; |
197 | |
|
198 | 0 | for (i = 0; i < ncycle; i++) { |
199 | 0 | cstart = panonopt_end+i; |
200 | 0 | pos = cstart; |
201 | 0 | for (j = 0; j < cyclelen; j++) { |
202 | 0 | if (pos >= panonopt_end) |
203 | 0 | pos -= nnonopts; |
204 | 0 | else |
205 | 0 | pos += nopts; |
206 | 0 | swap = nargv[pos]; |
207 | | /* LINTED const cast */ |
208 | 0 | ((char **) nargv)[pos] = nargv[cstart]; |
209 | | /* LINTED const cast */ |
210 | 0 | ((char **)nargv)[cstart] = swap; |
211 | 0 | } |
212 | 0 | } |
213 | 0 | } |
214 | | |
215 | | /* |
216 | | * parse_long_options -- |
217 | | * Parse long options in argc/argv argument vector. |
218 | | * Returns -1 if short_too is set and the option does not match long_options. |
219 | | */ |
220 | | static int |
221 | | parse_long_options(char * const *nargv, const char *options, |
222 | | const struct option *long_options, int *idx, int short_too) |
223 | 0 | { |
224 | 0 | char *current_argv, *has_equal; |
225 | 0 | size_t current_argv_len; |
226 | 0 | int i, match; |
227 | |
|
228 | 0 | current_argv = place; |
229 | 0 | match = -1; |
230 | |
|
231 | 0 | optind++; |
232 | |
|
233 | 0 | if ((has_equal = strchr(current_argv, '=')) != NULL) { |
234 | | /* argument found (--option=arg) */ |
235 | 0 | current_argv_len = has_equal - current_argv; |
236 | 0 | has_equal++; |
237 | 0 | } else |
238 | 0 | current_argv_len = strlen(current_argv); |
239 | |
|
240 | 0 | for (i = 0; long_options[i].name; i++) { |
241 | | /* find matching long option */ |
242 | 0 | if (strncmp(current_argv, long_options[i].name, |
243 | 0 | current_argv_len)) |
244 | 0 | continue; |
245 | | |
246 | 0 | if (strlen(long_options[i].name) == current_argv_len) { |
247 | | /* exact match */ |
248 | 0 | match = i; |
249 | 0 | break; |
250 | 0 | } |
251 | | /* |
252 | | * If this is a known short option, don't allow |
253 | | * a partial match of a single character. |
254 | | */ |
255 | 0 | if (short_too && current_argv_len == 1) |
256 | 0 | continue; |
257 | | |
258 | 0 | if (match == -1) /* partial match */ |
259 | 0 | match = i; |
260 | 0 | else { |
261 | | /* ambiguous abbreviation */ |
262 | 0 | if (PRINT_ERROR) |
263 | 0 | warnx(ambig, (int)current_argv_len, |
264 | 0 | current_argv); |
265 | 0 | optopt = 0; |
266 | 0 | return (BADCH); |
267 | 0 | } |
268 | 0 | } |
269 | 0 | if (match != -1) { /* option found */ |
270 | 0 | if (long_options[match].has_arg == no_argument |
271 | 0 | && has_equal) { |
272 | 0 | if (PRINT_ERROR) |
273 | 0 | warnx(noarg, (int)current_argv_len, |
274 | 0 | current_argv); |
275 | | /* |
276 | | * XXX: GNU sets optopt to val regardless of flag |
277 | | */ |
278 | 0 | if (long_options[match].flag == NULL) |
279 | 0 | optopt = long_options[match].val; |
280 | 0 | else |
281 | 0 | optopt = 0; |
282 | 0 | return (BADARG); |
283 | 0 | } |
284 | 0 | if (long_options[match].has_arg == required_argument || |
285 | 0 | long_options[match].has_arg == optional_argument) { |
286 | 0 | if (has_equal) |
287 | 0 | optarg = has_equal; |
288 | 0 | else if (long_options[match].has_arg == |
289 | 0 | required_argument) { |
290 | | /* |
291 | | * optional argument doesn't use next nargv |
292 | | */ |
293 | 0 | optarg = nargv[optind++]; |
294 | 0 | } |
295 | 0 | } |
296 | 0 | if ((long_options[match].has_arg == required_argument) |
297 | 0 | && (optarg == NULL)) { |
298 | | /* |
299 | | * Missing argument; leading ':' indicates no error |
300 | | * should be generated. |
301 | | */ |
302 | 0 | if (PRINT_ERROR) |
303 | 0 | warnx(recargstring, |
304 | 0 | current_argv); |
305 | | /* |
306 | | * XXX: GNU sets optopt to val regardless of flag |
307 | | */ |
308 | 0 | if (long_options[match].flag == NULL) |
309 | 0 | optopt = long_options[match].val; |
310 | 0 | else |
311 | 0 | optopt = 0; |
312 | 0 | --optind; |
313 | 0 | return (BADARG); |
314 | 0 | } |
315 | 0 | } else { /* unknown option */ |
316 | 0 | if (short_too) { |
317 | 0 | --optind; |
318 | 0 | return (-1); |
319 | 0 | } |
320 | 0 | if (PRINT_ERROR) |
321 | 0 | warnx(illoptstring, current_argv); |
322 | 0 | optopt = 0; |
323 | 0 | return (BADCH); |
324 | 0 | } |
325 | 0 | if (idx) |
326 | 0 | *idx = match; |
327 | 0 | if (long_options[match].flag) { |
328 | 0 | *long_options[match].flag = long_options[match].val; |
329 | 0 | return (0); |
330 | 0 | } else |
331 | 0 | return (long_options[match].val); |
332 | 0 | } |
333 | | |
334 | | /* |
335 | | * getopt_internal -- |
336 | | * Parse argc/argv argument vector. Called by user level routines. |
337 | | */ |
338 | | static int |
339 | | getopt_internal(int nargc, char * const *nargv, const char *options, |
340 | | const struct option *long_options, int *idx, int flags) |
341 | 0 | { |
342 | 0 | char *oli; /* option letter list index */ |
343 | 0 | int optchar, short_too; |
344 | 0 | static int posixly_correct = -1; |
345 | |
|
346 | 0 | if (options == NULL) |
347 | 0 | return (-1); |
348 | | |
349 | | /* |
350 | | * XXX Some GNU programs (like cvs) set optind to 0 instead of |
351 | | * XXX using optreset. Work around this braindamage. |
352 | | */ |
353 | 0 | if (optind == 0) |
354 | 0 | optind = optreset = 1; |
355 | | |
356 | | /* |
357 | | * Disable GNU extensions if POSIXLY_CORRECT is set or options |
358 | | * string begins with a '+'. |
359 | | */ |
360 | 0 | if (posixly_correct == -1 || optreset) |
361 | 0 | posixly_correct = (getenv("POSIXLY_CORRECT") != NULL); |
362 | 0 | if (*options == '-') |
363 | 0 | flags |= FLAG_ALLARGS; |
364 | 0 | else if (posixly_correct || *options == '+') |
365 | 0 | flags &= ~FLAG_PERMUTE; |
366 | 0 | if (*options == '+' || *options == '-') |
367 | 0 | options++; |
368 | |
|
369 | 0 | optarg = NULL; |
370 | 0 | if (optreset) |
371 | 0 | nonopt_start = nonopt_end = -1; |
372 | 0 | start: |
373 | 0 | if (optreset || !*place) { /* update scanning pointer */ |
374 | 0 | optreset = 0; |
375 | 0 | if (optind >= nargc) { /* end of argument vector */ |
376 | 0 | place = EMSG; |
377 | 0 | if (nonopt_end != -1) { |
378 | | /* do permutation, if we have to */ |
379 | 0 | permute_args(nonopt_start, nonopt_end, |
380 | 0 | optind, nargv); |
381 | 0 | optind -= nonopt_end - nonopt_start; |
382 | 0 | } |
383 | 0 | else if (nonopt_start != -1) { |
384 | | /* |
385 | | * If we skipped non-options, set optind |
386 | | * to the first of them. |
387 | | */ |
388 | 0 | optind = nonopt_start; |
389 | 0 | } |
390 | 0 | nonopt_start = nonopt_end = -1; |
391 | 0 | return (-1); |
392 | 0 | } |
393 | 0 | if (*(place = nargv[optind]) != '-' || |
394 | 0 | (place[1] == '\0' && strchr(options, '-') == NULL)) { |
395 | 0 | place = EMSG; /* found non-option */ |
396 | 0 | if (flags & FLAG_ALLARGS) { |
397 | | /* |
398 | | * GNU extension: |
399 | | * return non-option as argument to option 1 |
400 | | */ |
401 | 0 | optarg = nargv[optind++]; |
402 | 0 | return (INORDER); |
403 | 0 | } |
404 | 0 | if (!(flags & FLAG_PERMUTE)) { |
405 | | /* |
406 | | * If no permutation wanted, stop parsing |
407 | | * at first non-option. |
408 | | */ |
409 | 0 | return (-1); |
410 | 0 | } |
411 | | /* do permutation */ |
412 | 0 | if (nonopt_start == -1) |
413 | 0 | nonopt_start = optind; |
414 | 0 | else if (nonopt_end != -1) { |
415 | 0 | permute_args(nonopt_start, nonopt_end, |
416 | 0 | optind, nargv); |
417 | 0 | nonopt_start = optind - |
418 | 0 | (nonopt_end - nonopt_start); |
419 | 0 | nonopt_end = -1; |
420 | 0 | } |
421 | 0 | optind++; |
422 | | /* process next argument */ |
423 | 0 | goto start; |
424 | 0 | } |
425 | 0 | if (nonopt_start != -1 && nonopt_end == -1) |
426 | 0 | nonopt_end = optind; |
427 | | |
428 | | /* |
429 | | * If we have "-" do nothing, if "--" we are done. |
430 | | */ |
431 | 0 | if (place[1] != '\0' && *++place == '-' && place[1] == '\0') { |
432 | 0 | optind++; |
433 | 0 | place = EMSG; |
434 | | /* |
435 | | * We found an option (--), so if we skipped |
436 | | * non-options, we have to permute. |
437 | | */ |
438 | 0 | if (nonopt_end != -1) { |
439 | 0 | permute_args(nonopt_start, nonopt_end, |
440 | 0 | optind, nargv); |
441 | 0 | optind -= nonopt_end - nonopt_start; |
442 | 0 | } |
443 | 0 | nonopt_start = nonopt_end = -1; |
444 | 0 | return (-1); |
445 | 0 | } |
446 | 0 | } |
447 | | |
448 | | /* |
449 | | * Check long options if: |
450 | | * 1) we were passed some |
451 | | * 2) the arg is not just "-" |
452 | | * 3) either the arg starts with -- we are getopt_long_only() |
453 | | */ |
454 | 0 | if (long_options != NULL && place != nargv[optind] && |
455 | 0 | (*place == '-' || (flags & FLAG_LONGONLY))) { |
456 | 0 | short_too = 0; |
457 | 0 | if (*place == '-') |
458 | 0 | place++; /* --foo long option */ |
459 | 0 | else if (*place != ':' && strchr(options, *place) != NULL) |
460 | 0 | short_too = 1; /* could be short option too */ |
461 | |
|
462 | 0 | optchar = parse_long_options(nargv, options, long_options, |
463 | 0 | idx, short_too); |
464 | 0 | if (optchar != -1) { |
465 | 0 | place = EMSG; |
466 | 0 | return (optchar); |
467 | 0 | } |
468 | 0 | } |
469 | | |
470 | 0 | if ((optchar = (int)*place++) == (int)':' || |
471 | 0 | (optchar == (int)'-' && *place != '\0') || |
472 | 0 | (oli = strchr(options, optchar)) == NULL) { |
473 | | /* |
474 | | * If the user specified "-" and '-' isn't listed in |
475 | | * options, return -1 (non-option) as per POSIX. |
476 | | * Otherwise, it is an unknown option character (or ':'). |
477 | | */ |
478 | 0 | if (optchar == (int)'-' && *place == '\0') |
479 | 0 | return (-1); |
480 | 0 | if (!*place) |
481 | 0 | ++optind; |
482 | 0 | if (PRINT_ERROR) |
483 | 0 | warnx(illoptchar, optchar); |
484 | 0 | optopt = optchar; |
485 | 0 | return (BADCH); |
486 | 0 | } |
487 | 0 | if (long_options != NULL && optchar == 'W' && oli[1] == ';') { |
488 | | /* -W long-option */ |
489 | 0 | if (*place) /* no space */ |
490 | 0 | /* NOTHING */; |
491 | 0 | else if (++optind >= nargc) { /* no arg */ |
492 | 0 | place = EMSG; |
493 | 0 | if (PRINT_ERROR) |
494 | 0 | warnx(recargchar, optchar); |
495 | 0 | optopt = optchar; |
496 | 0 | return (BADARG); |
497 | 0 | } else /* white space */ |
498 | 0 | place = nargv[optind]; |
499 | 0 | optchar = parse_long_options(nargv, options, long_options, |
500 | 0 | idx, 0); |
501 | 0 | place = EMSG; |
502 | 0 | return (optchar); |
503 | 0 | } |
504 | 0 | if (*++oli != ':') { /* doesn't take argument */ |
505 | 0 | if (!*place) |
506 | 0 | ++optind; |
507 | 0 | } else { /* takes (optional) argument */ |
508 | 0 | optarg = NULL; |
509 | 0 | if (*place) /* no white space */ |
510 | 0 | optarg = place; |
511 | 0 | else if (oli[1] != ':') { /* arg not optional */ |
512 | 0 | if (++optind >= nargc) { /* no arg */ |
513 | 0 | place = EMSG; |
514 | 0 | if (PRINT_ERROR) |
515 | 0 | warnx(recargchar, optchar); |
516 | 0 | optopt = optchar; |
517 | 0 | return (BADARG); |
518 | 0 | } else |
519 | 0 | optarg = nargv[optind]; |
520 | 0 | } |
521 | 0 | place = EMSG; |
522 | 0 | ++optind; |
523 | 0 | } |
524 | | /* dump back option letter */ |
525 | 0 | return (optchar); |
526 | 0 | } |
527 | | |
528 | | /* |
529 | | * getopt -- |
530 | | * Parse argc/argv argument vector. |
531 | | * |
532 | | * [eventually this will replace the BSD getopt] |
533 | | */ |
534 | | int |
535 | | getopt(int nargc, char * const *nargv, const char *options) |
536 | 0 | { |
537 | | |
538 | | /* |
539 | | * We don't pass FLAG_PERMUTE to getopt_internal() since |
540 | | * the BSD getopt(3) (unlike GNU) has never done this. |
541 | | * |
542 | | * Furthermore, since many privileged programs call getopt() |
543 | | * before dropping privileges it makes sense to keep things |
544 | | * as simple (and bug-free) as possible. |
545 | | */ |
546 | 0 | return (getopt_internal(nargc, nargv, options, NULL, NULL, 0)); |
547 | 0 | } |
548 | | |
549 | | #if 0 |
550 | | /* |
551 | | * getopt_long -- |
552 | | * Parse argc/argv argument vector. |
553 | | */ |
554 | | int |
555 | | getopt_long(int nargc, char * const *nargv, const char *options, |
556 | | const struct option *long_options, int *idx) |
557 | | { |
558 | | |
559 | | return (getopt_internal(nargc, nargv, options, long_options, idx, |
560 | | FLAG_PERMUTE)); |
561 | | } |
562 | | |
563 | | /* |
564 | | * getopt_long_only -- |
565 | | * Parse argc/argv argument vector. |
566 | | */ |
567 | | int |
568 | | getopt_long_only(int nargc, char * const *nargv, const char *options, |
569 | | const struct option *long_options, int *idx) |
570 | | { |
571 | | |
572 | | return (getopt_internal(nargc, nargv, options, long_options, idx, |
573 | | FLAG_PERMUTE|FLAG_LONGONLY)); |
574 | | } |
575 | | #endif |
576 | | |
577 | | #endif /* !defined(HAVE_GETOPT) || !defined(HAVE_OPTRESET) */ |