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