1 | /* Getopt for GNU. |
2 | NOTE: getopt is now part of the C library, so if you don't know what |
3 | "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu |
4 | before changing it! |
5 | |
6 | Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94 |
7 | Free Software Foundation, Inc. |
8 | |
9 | Changes by monty: |
10 | - Added include of string.h when necessary. |
11 | - Removed two warnings from gcc. |
12 | |
13 | This file is part of the GNU C Library. Its master source is NOT part of |
14 | the C library, however. The master source lives in /gd/gnu/lib. |
15 | |
16 | The GNU C Library is free software; you can redistribute it and/or |
17 | modify it under the terms of the GNU Library General Public License as |
18 | published by the Free Software Foundation; either version 2 of the |
19 | License, or (at your option) any later version. |
20 | |
21 | The GNU C Library is distributed in the hope that it will be useful, |
22 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
24 | Library General Public License for more details. |
25 | |
26 | You should have received a copy of the GNU Library General Public |
27 | License along with the GNU C Library; see the file COPYING.LIB. If |
28 | not, write to the Free Software Foundation, Inc., 675 Mass Ave, |
29 | Cambridge, MA 02139, USA. */ |
30 | |
31 | /* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. |
32 | Ditto for AIX 3.2 and <stdlib.h>. */ |
33 | #ifndef _NO_PROTO |
34 | #define _NO_PROTO |
35 | #endif |
36 | |
37 | #ifdef HAVE_CONFIG_H |
38 | #include <config.h> |
39 | #endif |
40 | |
41 | #if (!defined (__STDC__) || !__STDC__) && !defined(MSDOS) && !defined(OS2) |
42 | /* This is a separate conditional since some stdc systems |
43 | reject `defined (const)'. */ |
44 | #ifndef const |
45 | #define const |
46 | #endif |
47 | #endif |
48 | #include <stdlib.h> |
49 | #include <stdio.h> |
50 | #include <string.h> |
51 | /* Comment out all this code if we are using the GNU C Library, and are not |
52 | actually compiling the library itself. This code is part of the GNU C |
53 | Library, but also included in many other GNU distributions. Compiling |
54 | and linking in this code is a waste when using the GNU C library |
55 | (especially if it is a shared library). Rather than having every GNU |
56 | program understand `configure --with-gnu-libc' and omit the object files, |
57 | it is simpler to just do this in the source for each such file. */ |
58 | |
59 | #if defined (_LIBC) || !defined (__GNU_LIBRARY__) |
60 | |
61 | |
62 | /* This needs to come after some library #include |
63 | to get __GNU_LIBRARY__ defined. */ |
64 | #ifdef __GNU_LIBRARY__ |
65 | /* Don't include stdlib.h for non-GNU C libraries because some of them |
66 | contain conflicting prototypes for getopt. */ |
67 | #include <stdlib.h> |
68 | #endif /* GNU C library. */ |
69 | |
70 | /* This version of `getopt' appears to the caller like standard Unix `getopt' |
71 | but it behaves differently for the user, since it allows the user |
72 | to intersperse the options with the other arguments. |
73 | |
74 | As `getopt' works, it permutes the elements of ARGV so that, |
75 | when it is done, all the options precede everything else. Thus |
76 | all application programs are extended to handle flexible argument order. |
77 | |
78 | Setting the environment variable POSIXLY_CORRECT disables permutation. |
79 | Then the behavior is completely standard. |
80 | |
81 | GNU application programs can use a third alternative mode in which |
82 | they can distinguish the relative order of options and other arguments. */ |
83 | |
84 | #include "ma_getopt.h" |
85 | |
86 | /* For communication from `getopt' to the caller. |
87 | When `getopt' finds an option that takes an argument, |
88 | the argument value is returned here. |
89 | Also, when `ordering' is RETURN_IN_ORDER, |
90 | each non-option ARGV-element is returned here. */ |
91 | |
92 | char *optarg = NULL; |
93 | |
94 | /* Index in ARGV of the next element to be scanned. |
95 | This is used for communication to and from the caller |
96 | and for communication between successive calls to `getopt'. |
97 | |
98 | On entry to `getopt', zero means this is the first call; initialize. |
99 | |
100 | When `getopt' returns EOF, this is the index of the first of the |
101 | non-option elements that the caller should itself scan. |
102 | |
103 | Otherwise, `optind' communicates from one call to the next |
104 | how much of ARGV has been scanned so far. */ |
105 | |
106 | /* XXX 1003.2 says this must be 1 before any call. */ |
107 | int optind = 1; |
108 | |
109 | /* The next char to be scanned in the option-element |
110 | in which the last option character we returned was found. |
111 | This allows us to pick up the scan where we left off. |
112 | |
113 | If this is zero, or a null string, it means resume the scan |
114 | by advancing to the next ARGV-element. */ |
115 | |
116 | static char *nextchar; |
117 | |
118 | /* Callers store zero here to inhibit the error message |
119 | for unrecognized options. */ |
120 | |
121 | int opterr = 1; |
122 | |
123 | /* Set to an option character which was unrecognized. |
124 | This must be initialized on some systems to avoid linking in the |
125 | system's own getopt implementation. */ |
126 | |
127 | int optopt = '?'; |
128 | |
129 | /* Describe how to deal with options that follow non-option ARGV-elements. |
130 | |
131 | If the caller did not specify anything, |
132 | the default is REQUIRE_ORDER if the environment variable |
133 | POSIXLY_CORRECT is defined, PERMUTE otherwise. |
134 | |
135 | REQUIRE_ORDER means don't recognize them as options; |
136 | stop option processing when the first non-option is seen. |
137 | This is what Unix does. |
138 | This mode of operation is selected by either setting the environment |
139 | variable POSIXLY_CORRECT, or using `+' as the first character |
140 | of the list of option characters. |
141 | |
142 | PERMUTE is the default. We permute the contents of ARGV as we scan, |
143 | so that eventually all the non-options are at the end. This allows options |
144 | to be given in any order, even with programs that were not written to |
145 | expect this. |
146 | |
147 | RETURN_IN_ORDER is an option available to programs that were written |
148 | to expect options and other ARGV-elements in any order and that care about |
149 | the ordering of the two. We describe each non-option ARGV-element |
150 | as if it were the argument of an option with character code 1. |
151 | Using `-' as the first character of the list of option characters |
152 | selects this mode of operation. |
153 | |
154 | The special argument `--' forces an end of option-scanning regardless |
155 | of the value of `ordering'. In the case of RETURN_IN_ORDER, only |
156 | `--' can cause `getopt' to return EOF with `optind' != ARGC. */ |
157 | |
158 | static enum |
159 | { |
160 | REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER |
161 | } ordering; |
162 | |
163 | /* Value of POSIXLY_CORRECT environment variable. */ |
164 | static char *posixly_correct; |
165 | |
166 | #ifdef __GNU_LIBRARY__ |
167 | /* We want to avoid inclusion of string.h with non-GNU libraries |
168 | because there are many ways it can cause trouble. |
169 | On some systems, it contains special magic macros that don't work |
170 | in GCC. */ |
171 | #include <string.h> |
172 | #define my_index strchr |
173 | #else |
174 | |
175 | /* Avoid depending on library functions or files |
176 | whose names are inconsistent. */ |
177 | |
178 | static char * |
179 | my_index (const char *str, int chr) |
180 | { |
181 | while (*str) |
182 | { |
183 | if (*str == chr) |
184 | return (char *) str; |
185 | str++; |
186 | } |
187 | return 0; |
188 | } |
189 | |
190 | /* If using GCC, we can safely declare strlen this way. |
191 | If not using GCC, it is ok not to declare it. */ |
192 | #ifdef __GNUC__ |
193 | /* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. |
194 | That was relevant to code that was here before. */ |
195 | #if !defined (__STDC__) || !__STDC__ |
196 | /* gcc with -traditional declares the built-in strlen to return int, |
197 | and has done so at least since version 2.4.5. -- rms. */ |
198 | extern int strlen (const char *); |
199 | #endif /* not __STDC__ */ |
200 | #endif /* __GNUC__ */ |
201 | |
202 | #endif /* not __GNU_LIBRARY__ */ |
203 | |
204 | /* Handle permutation of arguments. */ |
205 | |
206 | /* Describe the part of ARGV that contains non-options that have |
207 | been skipped. `first_nonopt' is the index in ARGV of the first of them; |
208 | `last_nonopt' is the index after the last of them. */ |
209 | |
210 | static int first_nonopt; |
211 | static int last_nonopt; |
212 | |
213 | /* Exchange two adjacent subsequences of ARGV. |
214 | One subsequence is elements [first_nonopt,last_nonopt) |
215 | which contains all the non-options that have been skipped so far. |
216 | The other is elements [last_nonopt,optind), which contains all |
217 | the options processed since those non-options were skipped. |
218 | |
219 | `first_nonopt' and `last_nonopt' are relocated so that they describe |
220 | the new indices of the non-options in ARGV after they are moved. */ |
221 | |
222 | static void |
223 | exchange (char **argv) |
224 | { |
225 | int bottom = first_nonopt; |
226 | int middle = last_nonopt; |
227 | int top = optind; |
228 | char *tem; |
229 | |
230 | /* Exchange the shorter segment with the far end of the longer segment. |
231 | That puts the shorter segment into the right place. |
232 | It leaves the longer segment in the right place overall, |
233 | but it consists of two parts that need to be swapped next. */ |
234 | |
235 | while (top > middle && middle > bottom) |
236 | { |
237 | if (top - middle > middle - bottom) |
238 | { |
239 | /* Bottom segment is the short one. */ |
240 | int len = middle - bottom; |
241 | register int i; |
242 | |
243 | /* Swap it with the top part of the top segment. */ |
244 | for (i = 0; i < len; i++) |
245 | { |
246 | tem = argv[bottom + i]; |
247 | argv[bottom + i] = argv[top - (middle - bottom) + i]; |
248 | argv[top - (middle - bottom) + i] = tem; |
249 | } |
250 | /* Exclude the moved bottom segment from further swapping. */ |
251 | top -= len; |
252 | } |
253 | else |
254 | { |
255 | /* Top segment is the short one. */ |
256 | int len = top - middle; |
257 | register int i; |
258 | |
259 | /* Swap it with the bottom part of the bottom segment. */ |
260 | for (i = 0; i < len; i++) |
261 | { |
262 | tem = argv[bottom + i]; |
263 | argv[bottom + i] = argv[middle + i]; |
264 | argv[middle + i] = tem; |
265 | } |
266 | /* Exclude the moved top segment from further swapping. */ |
267 | bottom += len; |
268 | } |
269 | } |
270 | |
271 | /* Update records for the slots the non-options now occupy. */ |
272 | |
273 | first_nonopt += (optind - last_nonopt); |
274 | last_nonopt = optind; |
275 | } |
276 | |
277 | /* Initialize the internal data when the first call is made. */ |
278 | |
279 | static const char * |
280 | _getopt_initialize (const char *optstring) |
281 | { |
282 | /* Start processing options with ARGV-element 1 (since ARGV-element 0 |
283 | is the program name); the sequence of previously skipped |
284 | non-option ARGV-elements is empty. */ |
285 | |
286 | first_nonopt = last_nonopt = optind = 1; |
287 | |
288 | nextchar = NULL; |
289 | |
290 | posixly_correct = getenv ("POSIXLY_CORRECT" ); |
291 | |
292 | /* Determine how to handle the ordering of options and nonoptions. */ |
293 | |
294 | if (optstring[0] == '-') |
295 | { |
296 | ordering = RETURN_IN_ORDER; |
297 | ++optstring; |
298 | } |
299 | else if (optstring[0] == '+') |
300 | { |
301 | ordering = REQUIRE_ORDER; |
302 | ++optstring; |
303 | } |
304 | else if (posixly_correct != NULL) |
305 | ordering = REQUIRE_ORDER; |
306 | else |
307 | ordering = PERMUTE; |
308 | |
309 | return optstring; |
310 | } |
311 | |
312 | /* Scan elements of ARGV (whose length is ARGC) for option characters |
313 | given in OPTSTRING. |
314 | |
315 | If an element of ARGV starts with '-', and is not exactly "-" or "--", |
316 | then it is an option element. The characters of this element |
317 | (aside from the initial '-') are option characters. If `getopt' |
318 | is called repeatedly, it returns successively each of the option characters |
319 | from each of the option elements. |
320 | |
321 | If `getopt' finds another option character, it returns that character, |
322 | updating `optind' and `nextchar' so that the next call to `getopt' can |
323 | resume the scan with the following option character or ARGV-element. |
324 | |
325 | If there are no more option characters, `getopt' returns `EOF'. |
326 | Then `optind' is the index in ARGV of the first ARGV-element |
327 | that is not an option. (The ARGV-elements have been permuted |
328 | so that those that are not options now come last.) |
329 | |
330 | OPTSTRING is a string containing the legitimate option characters. |
331 | If an option character is seen that is not listed in OPTSTRING, |
332 | return '?' after printing an error message. If you set `opterr' to |
333 | zero, the error message is suppressed but we still return '?'. |
334 | |
335 | If a char in OPTSTRING is followed by a colon, that means it wants an arg, |
336 | so the following text in the same ARGV-element, or the text of the following |
337 | ARGV-element, is returned in `optarg'. Two colons mean an option that |
338 | wants an optional arg; if there is text in the current ARGV-element, |
339 | it is returned in `optarg', otherwise `optarg' is set to zero. |
340 | |
341 | If OPTSTRING starts with `-' or `+', it requests different methods of |
342 | handling the non-option ARGV-elements. |
343 | See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. |
344 | |
345 | Long-named options begin with `--' instead of `-'. |
346 | Their names may be abbreviated as long as the abbreviation is unique |
347 | or is an exact match for some defined option. If they have an |
348 | argument, it follows the option name in the same ARGV-element, separated |
349 | from the option name by a `=', or else the in next ARGV-element. |
350 | When `getopt' finds a long-named option, it returns 0 if that option's |
351 | `flag' field is nonzero, the value of the option's `val' field |
352 | if the `flag' field is zero. |
353 | |
354 | The elements of ARGV aren't really const, because we permute them. |
355 | But we pretend they're const in the prototype to be compatible |
356 | with other systems. |
357 | |
358 | LONGOPTS is a vector of `struct option' terminated by an |
359 | element containing a name which is zero. |
360 | |
361 | LONGIND returns the index in LONGOPT of the long-named option found. |
362 | It is only valid when a long-named option has been found by the most |
363 | recent call. |
364 | |
365 | If LONG_ONLY is nonzero, '-' as well as '--' can introduce |
366 | long-named options. */ |
367 | |
368 | int |
369 | _getopt_internal (int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longind, int long_only) |
370 | { |
371 | optarg = NULL; |
372 | |
373 | if (optind == 0) |
374 | optstring = _getopt_initialize (optstring); |
375 | |
376 | if (nextchar == NULL || *nextchar == '\0') |
377 | { |
378 | /* Advance to the next ARGV-element. */ |
379 | |
380 | if (ordering == PERMUTE) |
381 | { |
382 | /* If we have just processed some options following some non-options, |
383 | exchange them so that the options come first. */ |
384 | |
385 | if (first_nonopt != last_nonopt && last_nonopt != optind) |
386 | exchange ((char **) argv); |
387 | else if (last_nonopt != optind) |
388 | first_nonopt = optind; |
389 | |
390 | /* Skip any additional non-options |
391 | and extend the range of non-options previously skipped. */ |
392 | |
393 | while (optind < argc |
394 | && (argv[optind][0] != '-' || argv[optind][1] == '\0')) |
395 | optind++; |
396 | last_nonopt = optind; |
397 | } |
398 | |
399 | /* The special ARGV-element `--' means premature end of options. |
400 | Skip it like a null option, |
401 | then exchange with previous non-options as if it were an option, |
402 | then skip everything else like a non-option. */ |
403 | |
404 | if (optind != argc && !strcmp (argv[optind], "--" )) |
405 | { |
406 | optind++; |
407 | |
408 | if (first_nonopt != last_nonopt && last_nonopt != optind) |
409 | exchange ((char **) argv); |
410 | else if (first_nonopt == last_nonopt) |
411 | first_nonopt = optind; |
412 | last_nonopt = argc; |
413 | |
414 | optind = argc; |
415 | } |
416 | |
417 | /* If we have done all the ARGV-elements, stop the scan |
418 | and back over any non-options that we skipped and permuted. */ |
419 | |
420 | if (optind == argc) |
421 | { |
422 | /* Set the next-arg-index to point at the non-options |
423 | that we previously skipped, so the caller will digest them. */ |
424 | if (first_nonopt != last_nonopt) |
425 | optind = first_nonopt; |
426 | return EOF; |
427 | } |
428 | |
429 | /* If we have come to a non-option and did not permute it, |
430 | either stop the scan or describe it to the caller and pass it by. */ |
431 | |
432 | if ((argv[optind][0] != '-' || argv[optind][1] == '\0')) |
433 | { |
434 | if (ordering == REQUIRE_ORDER) |
435 | return EOF; |
436 | optarg = argv[optind++]; |
437 | return 1; |
438 | } |
439 | |
440 | /* We have found another option-ARGV-element. |
441 | Skip the initial punctuation. */ |
442 | |
443 | nextchar = (argv[optind] + 1 |
444 | + (longopts != NULL && argv[optind][1] == '-')); |
445 | } |
446 | |
447 | /* Decode the current option-ARGV-element. */ |
448 | |
449 | /* Check whether the ARGV-element is a long option. |
450 | |
451 | If long_only and the ARGV-element has the form "-f", where f is |
452 | a valid short option, don't consider it an abbreviated form of |
453 | a long option that starts with f. Otherwise there would be no |
454 | way to give the -f short option. |
455 | |
456 | On the other hand, if there's a long option "fubar" and |
457 | the ARGV-element is "-fu", do consider that an abbreviation of |
458 | the long option, just like "--fu", and not "-f" with arg "u". |
459 | |
460 | This distinction seems to be the most useful approach. */ |
461 | |
462 | if (longopts != NULL |
463 | && (argv[optind][1] == '-' |
464 | || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) |
465 | { |
466 | char *nameend; |
467 | const struct option *p; |
468 | const struct option *pfound = NULL; |
469 | int exact = 0; |
470 | int ambig = 0; |
471 | int indfound=0; /* Keep gcc happy */ |
472 | int option_index; |
473 | |
474 | for (nameend = nextchar; *nameend && *nameend != '='; nameend++) |
475 | /* Do nothing. */ ; |
476 | |
477 | /* Test all long options for either exact match |
478 | or abbreviated matches. */ |
479 | for (p = longopts, option_index = 0; p->name; p++, option_index++) |
480 | if (!strncmp (p->name, nextchar, nameend - nextchar)) |
481 | { |
482 | if ((size_t) (nameend - nextchar) == (size_t) strlen (p->name)) |
483 | { |
484 | /* Exact match found. */ |
485 | pfound = p; |
486 | indfound = option_index; |
487 | exact = 1; |
488 | break; |
489 | } |
490 | else if (pfound == NULL) |
491 | { |
492 | /* First nonexact match found. */ |
493 | pfound = p; |
494 | indfound = option_index; |
495 | } |
496 | else |
497 | /* Second or later nonexact match found. */ |
498 | ambig = 1; |
499 | } |
500 | |
501 | if (ambig && !exact) |
502 | { |
503 | if (opterr) |
504 | fprintf (stderr, "%s: option `%s' is ambiguous\n" , |
505 | argv[0], argv[optind]); |
506 | nextchar += strlen (nextchar); |
507 | optind++; |
508 | return '?'; |
509 | } |
510 | |
511 | if (pfound != NULL) |
512 | { |
513 | option_index = indfound; |
514 | optind++; |
515 | if (*nameend) |
516 | { |
517 | /* Don't test has_arg with >, because some C compilers don't |
518 | allow it to be used on enums. */ |
519 | if (pfound->has_arg) |
520 | optarg = nameend + 1; |
521 | else |
522 | { |
523 | if (opterr) |
524 | { |
525 | if (argv[optind - 1][1] == '-') |
526 | /* --option */ |
527 | fprintf (stderr, |
528 | "%s: option `--%s' doesn't allow an argument\n" , |
529 | argv[0], pfound->name); |
530 | else |
531 | /* +option or -option */ |
532 | fprintf (stderr, |
533 | "%s: option `%c%s' doesn't allow an argument\n" , |
534 | argv[0], argv[optind - 1][0], pfound->name); |
535 | } |
536 | nextchar += strlen (nextchar); |
537 | return '?'; |
538 | } |
539 | } |
540 | else if (pfound->has_arg == 1) |
541 | { |
542 | if (optind < argc) |
543 | optarg = argv[optind++]; |
544 | else |
545 | { |
546 | if (opterr) |
547 | fprintf (stderr, "%s: option `%s' requires an argument\n" , |
548 | argv[0], argv[optind - 1]); |
549 | nextchar += strlen (nextchar); |
550 | return optstring[0] == ':' ? ':' : '?'; |
551 | } |
552 | } |
553 | nextchar += strlen (nextchar); |
554 | if (longind != NULL) |
555 | *longind = option_index; |
556 | if (pfound->flag) |
557 | { |
558 | *(pfound->flag) = pfound->val; |
559 | return 0; |
560 | } |
561 | return pfound->val; |
562 | } |
563 | |
564 | /* Can't find it as a long option. If this is not getopt_long_only, |
565 | or the option starts with '--' or is not a valid short |
566 | option, then it's an error. |
567 | Otherwise interpret it as a short option. */ |
568 | if (!long_only || argv[optind][1] == '-' |
569 | || my_index (optstring, *nextchar) == NULL) |
570 | { |
571 | if (opterr) |
572 | { |
573 | if (argv[optind][1] == '-') |
574 | /* --option */ |
575 | fprintf (stderr, "%s: unrecognized option `--%s'\n" , |
576 | argv[0], nextchar); |
577 | else |
578 | /* +option or -option */ |
579 | fprintf (stderr, "%s: unrecognized option `%c%s'\n" , |
580 | argv[0], argv[optind][0], nextchar); |
581 | } |
582 | nextchar = (char *) "" ; |
583 | optind++; |
584 | return '?'; |
585 | } |
586 | } |
587 | |
588 | /* Look at and handle the next short option-character. */ |
589 | |
590 | { |
591 | char c = *nextchar++; |
592 | char *temp = my_index (optstring, c); |
593 | |
594 | /* Increment `optind' when we start to process its last character. */ |
595 | if (*nextchar == '\0') |
596 | ++optind; |
597 | |
598 | if (temp == NULL || c == ':') |
599 | { |
600 | if (opterr) |
601 | { |
602 | if (posixly_correct) |
603 | /* 1003.2 specifies the format of this message. */ |
604 | fprintf (stderr, "%s: illegal option -- %c\n" , argv[0], c); |
605 | else |
606 | fprintf (stderr, "%s: invalid option -- %c\n" , argv[0], c); |
607 | } |
608 | optopt = c; |
609 | return '?'; |
610 | } |
611 | if (temp[1] == ':') |
612 | { |
613 | if (temp[2] == ':') |
614 | { |
615 | /* This is an option that accepts an argument optionally. */ |
616 | if (*nextchar != '\0') |
617 | { |
618 | optarg = nextchar; |
619 | optind++; |
620 | } |
621 | else |
622 | optarg = NULL; |
623 | nextchar = NULL; |
624 | } |
625 | else |
626 | { |
627 | /* This is an option that requires an argument. */ |
628 | if (*nextchar != '\0') |
629 | { |
630 | optarg = nextchar; |
631 | /* If we end this ARGV-element by taking the rest as an arg, |
632 | we must advance to the next element now. */ |
633 | optind++; |
634 | } |
635 | else if (optind == argc) |
636 | { |
637 | if (opterr) |
638 | { |
639 | /* 1003.2 specifies the format of this message. */ |
640 | fprintf (stderr, "%s: option requires an argument -- %c\n" , |
641 | argv[0], c); |
642 | } |
643 | optopt = c; |
644 | if (optstring[0] == ':') |
645 | c = ':'; |
646 | else |
647 | c = '?'; |
648 | } |
649 | else |
650 | /* We already incremented `optind' once; |
651 | increment it again when taking next ARGV-elt as argument. */ |
652 | optarg = argv[optind++]; |
653 | nextchar = NULL; |
654 | } |
655 | } |
656 | return c; |
657 | } |
658 | } |
659 | |
660 | int |
661 | getopt (int argc, char *const *argv, const char *optstring) |
662 | { |
663 | return _getopt_internal (argc, argv, optstring, |
664 | (const struct option *) 0, |
665 | (int *) 0, |
666 | 0); |
667 | } |
668 | |
669 | #endif /* _LIBC or not __GNU_LIBRARY__. */ |
670 | |
671 | #ifdef TEST |
672 | |
673 | /* Compile with -DTEST to make an executable for use in testing |
674 | the above definition of `getopt'. */ |
675 | |
676 | int |
677 | main (argc, argv) |
678 | int argc; |
679 | char **argv; |
680 | { |
681 | int c; |
682 | int digit_optind = 0; |
683 | |
684 | while (1) |
685 | { |
686 | int this_option_optind = optind ? optind : 1; |
687 | |
688 | c = getopt (argc, argv, "abc:d:0123456789" ); |
689 | if (c == EOF) |
690 | break; |
691 | |
692 | switch (c) |
693 | { |
694 | case '0': |
695 | case '1': |
696 | case '2': |
697 | case '3': |
698 | case '4': |
699 | case '5': |
700 | case '6': |
701 | case '7': |
702 | case '8': |
703 | case '9': |
704 | if (digit_optind != 0 && digit_optind != this_option_optind) |
705 | printf ("digits occur in two different argv-elements.\n" ); |
706 | digit_optind = this_option_optind; |
707 | printf ("option %c\n" , c); |
708 | break; |
709 | |
710 | case 'a': |
711 | printf ("option a\n" ); |
712 | break; |
713 | |
714 | case 'b': |
715 | printf ("option b\n" ); |
716 | break; |
717 | |
718 | case 'c': |
719 | printf ("option c with value `%s'\n" , optarg); |
720 | break; |
721 | |
722 | case '?': |
723 | break; |
724 | |
725 | default: |
726 | printf ("?? getopt returned character code 0%o ??\n" , c); |
727 | } |
728 | } |
729 | |
730 | if (optind < argc) |
731 | { |
732 | printf ("non-option ARGV-elements: " ); |
733 | while (optind < argc) |
734 | printf ("%s " , argv[optind++]); |
735 | printf ("\n" ); |
736 | } |
737 | |
738 | exit (0); |
739 | } |
740 | |
741 | #endif /* TEST */ |
742 | |