VirtualBox

source: kBuild/vendor/grep/current/lib/getopt.c@ 3530

Last change on this file since 3530 was 3529, checked in by bird, 3 years ago

Imported grep 3.7 from grep-3.7.tar.gz (sha256: c22b0cf2d4f6bbe599c902387e8058990e1eee99aef333a203829e5fd3dbb342), applying minimal auto-props.

  • Property svn:eol-style set to native
File size: 23.6 KB
Line 
1/* Getopt for GNU.
2 Copyright (C) 1987-2021 Free Software Foundation, Inc.
3 This file is part of the GNU C Library and is also part of gnulib.
4 Patches to this file should be submitted to both projects.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
19
20
21#ifndef _LIBC
22# include <config.h>
23#endif
24
25#include "getopt.h"
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31
32#ifdef _LIBC
33/* When used as part of glibc, error printing must be done differently
34 for standards compliance. getopt is not a cancellation point, so
35 it must not call functions that are, and it is specified by an
36 older standard than stdio locking, so it must not refer to
37 functions in the "user namespace" related to stdio locking.
38 Finally, it must use glibc's internal message translation so that
39 the messages are looked up in the proper text domain. */
40# include <libintl.h>
41# define fprintf __fxprintf_nocancel
42# define flockfile(fp) _IO_flockfile (fp)
43# define funlockfile(fp) _IO_funlockfile (fp)
44#else
45# include "gettext.h"
46# define _(msgid) gettext (msgid)
47/* When used standalone, flockfile and funlockfile might not be
48 available. */
49# if (!defined _POSIX_THREAD_SAFE_FUNCTIONS \
50 || (defined _WIN32 && ! defined __CYGWIN__))
51# define flockfile(fp) /* nop */
52# define funlockfile(fp) /* nop */
53# endif
54/* When used standalone, do not attempt to use alloca. */
55# define __libc_use_alloca(size) 0
56# undef alloca
57# define alloca(size) (abort (), (void *)0)
58#endif
59
60/* This implementation of 'getopt' has three modes for handling
61 options interspersed with non-option arguments. It can stop
62 scanning for options at the first non-option argument encountered,
63 as POSIX specifies. It can continue scanning for options after the
64 first non-option argument, but permute 'argv' as it goes so that,
65 after 'getopt' is done, all the options precede all the non-option
66 arguments and 'optind' points to the first non-option argument.
67 Or, it can report non-option arguments as if they were arguments to
68 the option character '\x01'.
69
70 The default behavior of 'getopt_long' is to permute the argument list.
71 When this implementation is used standalone, the default behavior of
72 'getopt' is to stop at the first non-option argument, but when it is
73 used as part of GNU libc it also permutes the argument list. In both
74 cases, setting the environment variable POSIXLY_CORRECT to any value
75 disables permutation.
76
77 If the first character of the OPTSTRING argument to 'getopt' or
78 'getopt_long' is '+', both functions will stop at the first
79 non-option argument. If it is '-', both functions will report
80 non-option arguments as arguments to the option character '\x01'. */
81
82#include "getopt_int.h"
83
84/* For communication from 'getopt' to the caller.
85 When 'getopt' finds an option that takes an argument,
86 the argument value is returned here.
87 Also, when 'ordering' is RETURN_IN_ORDER,
88 each non-option ARGV-element is returned here. */
89
90char *optarg;
91
92/* Index in ARGV of the next element to be scanned.
93 This is used for communication to and from the caller
94 and for communication between successive calls to 'getopt'.
95
96 On entry to 'getopt', zero means this is the first call; initialize.
97
98 When 'getopt' returns -1, this is the index of the first of the
99 non-option elements that the caller should itself scan.
100
101 Otherwise, 'optind' communicates from one call to the next
102 how much of ARGV has been scanned so far. */
103
104/* 1003.2 says this must be 1 before any call. */
105int optind = 1;
106
107/* Callers store zero here to inhibit the error message
108 for unrecognized options. */
109
110int opterr = 1;
111
112/* Set to an option character which was unrecognized.
113 This must be initialized on some systems to avoid linking in the
114 system's own getopt implementation. */
115
116int optopt = '?';
117
118/* Keep a global copy of all internal members of getopt_data. */
119
120static struct _getopt_data getopt_data;
121
122
123/* Exchange two adjacent subsequences of ARGV.
124 One subsequence is elements [first_nonopt,last_nonopt)
125 which contains all the non-options that have been skipped so far.
126 The other is elements [last_nonopt,optind), which contains all
127 the options processed since those non-options were skipped.
128
129 'first_nonopt' and 'last_nonopt' are relocated so that they describe
130 the new indices of the non-options in ARGV after they are moved. */
131
132static void
133exchange (char **argv, struct _getopt_data *d)
134{
135 int bottom = d->__first_nonopt;
136 int middle = d->__last_nonopt;
137 int top = d->optind;
138 char *tem;
139
140 /* Exchange the shorter segment with the far end of the longer segment.
141 That puts the shorter segment into the right place.
142 It leaves the longer segment in the right place overall,
143 but it consists of two parts that need to be swapped next. */
144
145 while (top > middle && middle > bottom)
146 {
147 if (top - middle > middle - bottom)
148 {
149 /* Bottom segment is the short one. */
150 int len = middle - bottom;
151 int i;
152
153 /* Swap it with the top part of the top segment. */
154 for (i = 0; i < len; i++)
155 {
156 tem = argv[bottom + i];
157 argv[bottom + i] = argv[top - (middle - bottom) + i];
158 argv[top - (middle - bottom) + i] = tem;
159 }
160 /* Exclude the moved bottom segment from further swapping. */
161 top -= len;
162 }
163 else
164 {
165 /* Top segment is the short one. */
166 int len = top - middle;
167 int i;
168
169 /* Swap it with the bottom part of the bottom segment. */
170 for (i = 0; i < len; i++)
171 {
172 tem = argv[bottom + i];
173 argv[bottom + i] = argv[middle + i];
174 argv[middle + i] = tem;
175 }
176 /* Exclude the moved top segment from further swapping. */
177 bottom += len;
178 }
179 }
180
181 /* Update records for the slots the non-options now occupy. */
182
183 d->__first_nonopt += (d->optind - d->__last_nonopt);
184 d->__last_nonopt = d->optind;
185}
186
187/* Process the argument starting with d->__nextchar as a long option.
188 d->optind should *not* have been advanced over this argument.
189
190 If the value returned is -1, it was not actually a long option, the
191 state is unchanged, and the argument should be processed as a set
192 of short options (this can only happen when long_only is true).
193 Otherwise, the option (and its argument, if any) have been consumed
194 and the return value is the value to return from _getopt_internal_r. */
195static int
196process_long_option (int argc, char **argv, const char *optstring,
197 const struct option *longopts, int *longind,
198 int long_only, struct _getopt_data *d,
199 int print_errors, const char *prefix)
200{
201 char *nameend;
202 size_t namelen;
203 const struct option *p;
204 const struct option *pfound = NULL;
205 int n_options;
206 int option_index;
207
208 for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
209 /* Do nothing. */ ;
210 namelen = nameend - d->__nextchar;
211
212 /* First look for an exact match, counting the options as a side
213 effect. */
214 for (p = longopts, n_options = 0; p->name; p++, n_options++)
215 if (!strncmp (p->name, d->__nextchar, namelen)
216 && namelen == strlen (p->name))
217 {
218 /* Exact match found. */
219 pfound = p;
220 option_index = n_options;
221 break;
222 }
223
224 if (pfound == NULL)
225 {
226 /* Didn't find an exact match, so look for abbreviations. */
227 unsigned char *ambig_set = NULL;
228 int ambig_malloced = 0;
229 int ambig_fallback = 0;
230 int indfound = -1;
231
232 for (p = longopts, option_index = 0; p->name; p++, option_index++)
233 if (!strncmp (p->name, d->__nextchar, namelen))
234 {
235 if (pfound == NULL)
236 {
237 /* First nonexact match found. */
238 pfound = p;
239 indfound = option_index;
240 }
241 else if (long_only
242 || pfound->has_arg != p->has_arg
243 || pfound->flag != p->flag
244 || pfound->val != p->val)
245 {
246 /* Second or later nonexact match found. */
247 if (!ambig_fallback)
248 {
249 if (!print_errors)
250 /* Don't waste effort tracking the ambig set if
251 we're not going to print it anyway. */
252 ambig_fallback = 1;
253 else if (!ambig_set)
254 {
255 if (__libc_use_alloca (n_options))
256 ambig_set = alloca (n_options);
257 else if ((ambig_set = malloc (n_options)) == NULL)
258 /* Fall back to simpler error message. */
259 ambig_fallback = 1;
260 else
261 ambig_malloced = 1;
262
263 if (ambig_set)
264 {
265 memset (ambig_set, 0, n_options);
266 ambig_set[indfound] = 1;
267 }
268 }
269 if (ambig_set)
270 ambig_set[option_index] = 1;
271 }
272 }
273 }
274
275 if (ambig_set || ambig_fallback)
276 {
277 if (print_errors)
278 {
279 if (ambig_fallback)
280 fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"),
281 argv[0], prefix, d->__nextchar);
282 else
283 {
284 flockfile (stderr);
285 fprintf (stderr,
286 _("%s: option '%s%s' is ambiguous; possibilities:"),
287 argv[0], prefix, d->__nextchar);
288
289 for (option_index = 0; option_index < n_options; option_index++)
290 if (ambig_set[option_index])
291 fprintf (stderr, " '%s%s'",
292 prefix, longopts[option_index].name);
293
294 /* This must use 'fprintf' even though it's only
295 printing a single character, so that it goes through
296 __fxprintf_nocancel when compiled as part of glibc. */
297 fprintf (stderr, "\n");
298 funlockfile (stderr);
299 }
300 }
301 if (ambig_malloced)
302 free (ambig_set);
303 d->__nextchar += strlen (d->__nextchar);
304 d->optind++;
305 d->optopt = 0;
306 return '?';
307 }
308
309 option_index = indfound;
310 }
311
312 if (pfound == NULL)
313 {
314 /* Can't find it as a long option. If this is not getopt_long_only,
315 or the option starts with '--' or is not a valid short option,
316 then it's an error. */
317 if (!long_only || argv[d->optind][1] == '-'
318 || strchr (optstring, *d->__nextchar) == NULL)
319 {
320 if (print_errors)
321 fprintf (stderr, _("%s: unrecognized option '%s%s'\n"),
322 argv[0], prefix, d->__nextchar);
323
324 d->__nextchar = NULL;
325 d->optind++;
326 d->optopt = 0;
327 return '?';
328 }
329
330 /* Otherwise interpret it as a short option. */
331 return -1;
332 }
333
334 /* We have found a matching long option. Consume it. */
335 d->optind++;
336 d->__nextchar = NULL;
337 if (*nameend)
338 {
339 /* Don't test has_arg with >, because some C compilers don't
340 allow it to be used on enums. */
341 if (pfound->has_arg)
342 d->optarg = nameend + 1;
343 else
344 {
345 if (print_errors)
346 fprintf (stderr,
347 _("%s: option '%s%s' doesn't allow an argument\n"),
348 argv[0], prefix, pfound->name);
349
350 d->optopt = pfound->val;
351 return '?';
352 }
353 }
354 else if (pfound->has_arg == 1)
355 {
356 if (d->optind < argc)
357 d->optarg = argv[d->optind++];
358 else
359 {
360 if (print_errors)
361 fprintf (stderr,
362 _("%s: option '%s%s' requires an argument\n"),
363 argv[0], prefix, pfound->name);
364
365 d->optopt = pfound->val;
366 return optstring[0] == ':' ? ':' : '?';
367 }
368 }
369
370 if (longind != NULL)
371 *longind = option_index;
372 if (pfound->flag)
373 {
374 *(pfound->flag) = pfound->val;
375 return 0;
376 }
377 return pfound->val;
378}
379
380/* Initialize internal data upon the first call to getopt. */
381
382static const char *
383_getopt_initialize (int argc _GL_UNUSED,
384 char **argv _GL_UNUSED, const char *optstring,
385 struct _getopt_data *d, int posixly_correct)
386{
387 /* Start processing options with ARGV-element 1 (since ARGV-element 0
388 is the program name); the sequence of previously skipped
389 non-option ARGV-elements is empty. */
390 if (d->optind == 0)
391 d->optind = 1;
392
393 d->__first_nonopt = d->__last_nonopt = d->optind;
394 d->__nextchar = NULL;
395
396 /* Determine how to handle the ordering of options and nonoptions. */
397 if (optstring[0] == '-')
398 {
399 d->__ordering = RETURN_IN_ORDER;
400 ++optstring;
401 }
402 else if (optstring[0] == '+')
403 {
404 d->__ordering = REQUIRE_ORDER;
405 ++optstring;
406 }
407 else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
408 d->__ordering = REQUIRE_ORDER;
409 else
410 d->__ordering = PERMUTE;
411
412 d->__initialized = 1;
413 return optstring;
414}
415
416
417/* Scan elements of ARGV (whose length is ARGC) for option characters
418 given in OPTSTRING.
419
420 If an element of ARGV starts with '-', and is not exactly "-" or "--",
421 then it is an option element. The characters of this element
422 (aside from the initial '-') are option characters. If 'getopt'
423 is called repeatedly, it returns successively each of the option characters
424 from each of the option elements.
425
426 If 'getopt' finds another option character, it returns that character,
427 updating 'optind' and 'nextchar' so that the next call to 'getopt' can
428 resume the scan with the following option character or ARGV-element.
429
430 If there are no more option characters, 'getopt' returns -1.
431 Then 'optind' is the index in ARGV of the first ARGV-element
432 that is not an option. (The ARGV-elements have been permuted
433 so that those that are not options now come last.)
434
435 OPTSTRING is a string containing the legitimate option characters.
436 If an option character is seen that is not listed in OPTSTRING,
437 return '?' after printing an error message. If you set 'opterr' to
438 zero, the error message is suppressed but we still return '?'.
439
440 If a char in OPTSTRING is followed by a colon, that means it wants an arg,
441 so the following text in the same ARGV-element, or the text of the following
442 ARGV-element, is returned in 'optarg'. Two colons mean an option that
443 wants an optional arg; if there is text in the current ARGV-element,
444 it is returned in 'optarg', otherwise 'optarg' is set to zero.
445
446 If OPTSTRING starts with '-' or '+', it requests different methods of
447 handling the non-option ARGV-elements.
448 See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
449
450 Long-named options begin with '--' instead of '-'.
451 Their names may be abbreviated as long as the abbreviation is unique
452 or is an exact match for some defined option. If they have an
453 argument, it follows the option name in the same ARGV-element, separated
454 from the option name by a '=', or else the in next ARGV-element.
455 When 'getopt' finds a long-named option, it returns 0 if that option's
456 'flag' field is nonzero, the value of the option's 'val' field
457 if the 'flag' field is zero.
458
459 The elements of ARGV aren't really const, because we permute them.
460 But we pretend they're const in the prototype to be compatible
461 with other systems.
462
463 LONGOPTS is a vector of 'struct option' terminated by an
464 element containing a name which is zero.
465
466 LONGIND returns the index in LONGOPT of the long-named option found.
467 It is only valid when a long-named option has been found by the most
468 recent call.
469
470 If LONG_ONLY is nonzero, '-' as well as '--' can introduce
471 long-named options. */
472
473int
474_getopt_internal_r (int argc, char **argv, const char *optstring,
475 const struct option *longopts, int *longind,
476 int long_only, struct _getopt_data *d, int posixly_correct)
477{
478 int print_errors = d->opterr;
479
480 if (argc < 1)
481 return -1;
482
483 d->optarg = NULL;
484
485 if (d->optind == 0 || !d->__initialized)
486 optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
487 else if (optstring[0] == '-' || optstring[0] == '+')
488 optstring++;
489
490 if (optstring[0] == ':')
491 print_errors = 0;
492
493 /* Test whether ARGV[optind] points to a non-option argument. */
494#define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
495
496 if (d->__nextchar == NULL || *d->__nextchar == '\0')
497 {
498 /* Advance to the next ARGV-element. */
499
500 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
501 moved back by the user (who may also have changed the arguments). */
502 if (d->__last_nonopt > d->optind)
503 d->__last_nonopt = d->optind;
504 if (d->__first_nonopt > d->optind)
505 d->__first_nonopt = d->optind;
506
507 if (d->__ordering == PERMUTE)
508 {
509 /* If we have just processed some options following some non-options,
510 exchange them so that the options come first. */
511
512 if (d->__first_nonopt != d->__last_nonopt
513 && d->__last_nonopt != d->optind)
514 exchange (argv, d);
515 else if (d->__last_nonopt != d->optind)
516 d->__first_nonopt = d->optind;
517
518 /* Skip any additional non-options
519 and extend the range of non-options previously skipped. */
520
521 while (d->optind < argc && NONOPTION_P)
522 d->optind++;
523 d->__last_nonopt = d->optind;
524 }
525
526 /* The special ARGV-element '--' means premature end of options.
527 Skip it like a null option,
528 then exchange with previous non-options as if it were an option,
529 then skip everything else like a non-option. */
530
531 if (d->optind != argc && !strcmp (argv[d->optind], "--"))
532 {
533 d->optind++;
534
535 if (d->__first_nonopt != d->__last_nonopt
536 && d->__last_nonopt != d->optind)
537 exchange (argv, d);
538 else if (d->__first_nonopt == d->__last_nonopt)
539 d->__first_nonopt = d->optind;
540 d->__last_nonopt = argc;
541
542 d->optind = argc;
543 }
544
545 /* If we have done all the ARGV-elements, stop the scan
546 and back over any non-options that we skipped and permuted. */
547
548 if (d->optind == argc)
549 {
550 /* Set the next-arg-index to point at the non-options
551 that we previously skipped, so the caller will digest them. */
552 if (d->__first_nonopt != d->__last_nonopt)
553 d->optind = d->__first_nonopt;
554 return -1;
555 }
556
557 /* If we have come to a non-option and did not permute it,
558 either stop the scan or describe it to the caller and pass it by. */
559
560 if (NONOPTION_P)
561 {
562 if (d->__ordering == REQUIRE_ORDER)
563 return -1;
564 d->optarg = argv[d->optind++];
565 return 1;
566 }
567
568 /* We have found another option-ARGV-element.
569 Check whether it might be a long option. */
570 if (longopts)
571 {
572 if (argv[d->optind][1] == '-')
573 {
574 /* "--foo" is always a long option. The special option
575 "--" was handled above. */
576 d->__nextchar = argv[d->optind] + 2;
577 return process_long_option (argc, argv, optstring, longopts,
578 longind, long_only, d,
579 print_errors, "--");
580 }
581
582 /* If long_only and the ARGV-element has the form "-f",
583 where f is a valid short option, don't consider it an
584 abbreviated form of a long option that starts with f.
585 Otherwise there would be no way to give the -f short
586 option.
587
588 On the other hand, if there's a long option "fubar" and
589 the ARGV-element is "-fu", do consider that an
590 abbreviation of the long option, just like "--fu", and
591 not "-f" with arg "u".
592
593 This distinction seems to be the most useful approach. */
594 if (long_only && (argv[d->optind][2]
595 || !strchr (optstring, argv[d->optind][1])))
596 {
597 int code;
598 d->__nextchar = argv[d->optind] + 1;
599 code = process_long_option (argc, argv, optstring, longopts,
600 longind, long_only, d,
601 print_errors, "-");
602 if (code != -1)
603 return code;
604 }
605 }
606
607 /* It is not a long option. Skip the initial punctuation. */
608 d->__nextchar = argv[d->optind] + 1;
609 }
610
611 /* Look at and handle the next short option-character. */
612
613 {
614 char c = *d->__nextchar++;
615 const char *temp = strchr (optstring, c);
616
617 /* Increment 'optind' when we start to process its last character. */
618 if (*d->__nextchar == '\0')
619 ++d->optind;
620
621 if (temp == NULL || c == ':' || c == ';')
622 {
623 if (print_errors)
624 fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
625 d->optopt = c;
626 return '?';
627 }
628
629 /* Convenience. Treat POSIX -W foo same as long option --foo */
630 if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
631 {
632 /* This is an option that requires an argument. */
633 if (*d->__nextchar != '\0')
634 d->optarg = d->__nextchar;
635 else if (d->optind == argc)
636 {
637 if (print_errors)
638 fprintf (stderr,
639 _("%s: option requires an argument -- '%c'\n"),
640 argv[0], c);
641
642 d->optopt = c;
643 if (optstring[0] == ':')
644 c = ':';
645 else
646 c = '?';
647 return c;
648 }
649 else
650 d->optarg = argv[d->optind];
651
652 d->__nextchar = d->optarg;
653 d->optarg = NULL;
654 return process_long_option (argc, argv, optstring, longopts, longind,
655 0 /* long_only */, d, print_errors, "-W ");
656 }
657 if (temp[1] == ':')
658 {
659 if (temp[2] == ':')
660 {
661 /* This is an option that accepts an argument optionally. */
662 if (*d->__nextchar != '\0')
663 {
664 d->optarg = d->__nextchar;
665 d->optind++;
666 }
667 else
668 d->optarg = NULL;
669 d->__nextchar = NULL;
670 }
671 else
672 {
673 /* This is an option that requires an argument. */
674 if (*d->__nextchar != '\0')
675 {
676 d->optarg = d->__nextchar;
677 /* If we end this ARGV-element by taking the rest as an arg,
678 we must advance to the next element now. */
679 d->optind++;
680 }
681 else if (d->optind == argc)
682 {
683 if (print_errors)
684 fprintf (stderr,
685 _("%s: option requires an argument -- '%c'\n"),
686 argv[0], c);
687
688 d->optopt = c;
689 if (optstring[0] == ':')
690 c = ':';
691 else
692 c = '?';
693 }
694 else
695 /* We already incremented 'optind' once;
696 increment it again when taking next ARGV-elt as argument. */
697 d->optarg = argv[d->optind++];
698 d->__nextchar = NULL;
699 }
700 }
701 return c;
702 }
703}
704
705int
706_getopt_internal (int argc, char **argv, const char *optstring,
707 const struct option *longopts, int *longind, int long_only,
708 int posixly_correct)
709{
710 int result;
711
712 getopt_data.optind = optind;
713 getopt_data.opterr = opterr;
714
715 result = _getopt_internal_r (argc, argv, optstring, longopts,
716 longind, long_only, &getopt_data,
717 posixly_correct);
718
719 optind = getopt_data.optind;
720 optarg = getopt_data.optarg;
721 optopt = getopt_data.optopt;
722
723 return result;
724}
725
726/* glibc gets a LSB-compliant getopt and a POSIX-complaint __posix_getopt.
727 Standalone applications just get a POSIX-compliant getopt.
728 POSIX and LSB both require these functions to take 'char *const *argv'
729 even though this is incorrect (because of the permutation). */
730#define GETOPT_ENTRY(NAME, POSIXLY_CORRECT) \
731 int \
732 NAME (int argc, char *const *argv, const char *optstring) \
733 { \
734 return _getopt_internal (argc, (char **)argv, optstring, \
735 0, 0, 0, POSIXLY_CORRECT); \
736 }
737
738#ifdef _LIBC
739GETOPT_ENTRY(getopt, 0)
740GETOPT_ENTRY(__posix_getopt, 1)
741#else
742GETOPT_ENTRY(getopt, 1)
743#endif
744
745
746
747#ifdef TEST
748
749/* Compile with -DTEST to make an executable for use in testing
750 the above definition of 'getopt'. */
751
752int
753main (int argc, char **argv)
754{
755 int c;
756 int digit_optind = 0;
757
758 while (1)
759 {
760 int this_option_optind = optind ? optind : 1;
761
762 c = getopt (argc, argv, "abc:d:0123456789");
763 if (c == -1)
764 break;
765
766 switch (c)
767 {
768 case '0':
769 case '1':
770 case '2':
771 case '3':
772 case '4':
773 case '5':
774 case '6':
775 case '7':
776 case '8':
777 case '9':
778 if (digit_optind != 0 && digit_optind != this_option_optind)
779 printf ("digits occur in two different argv-elements.\n");
780 digit_optind = this_option_optind;
781 printf ("option %c\n", c);
782 break;
783
784 case 'a':
785 printf ("option a\n");
786 break;
787
788 case 'b':
789 printf ("option b\n");
790 break;
791
792 case 'c':
793 printf ("option c with value '%s'\n", optarg);
794 break;
795
796 case '?':
797 break;
798
799 default:
800 printf ("?? getopt returned character code 0%o ??\n", c);
801 }
802 }
803
804 if (optind < argc)
805 {
806 printf ("non-option ARGV-elements: ");
807 while (optind < argc)
808 printf ("%s ", argv[optind++]);
809 printf ("\n");
810 }
811
812 exit (0);
813}
814
815#endif /* TEST */
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette