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