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