37 __getopt_initialize (const char *optstring);
\r
40 __getopt_internal (int argc, char *const *argv, const char* optstring, const struct option *longopts, int* longind, int long_only);
\r
43 __exchange (char **argv);
\r
46 getopt (int argc, char * const argv[], const char *optstring)
\r
48 return __getopt_internal(argc, argv, optstring,(const struct option *) 0,(int *) 0,0);
\r
52 __getopt_initialize (const char *optstring)
\r
54 /* Start processing options with ARGV-element 1 (since ARGV-element 0
\r
55 is the program name); the sequence of previously skipped
\r
56 non-option ARGV-elements is empty. */
\r
58 first_nonopt = last_nonopt = optind = 1;
\r
61 /* Determine how to handle the ordering of options and nonoptions. */
\r
63 if (optstring[0] == '-')
\r
65 ordering = RETURN_IN_ORDER;
\r
68 /* si la chaîne d'options commence par un + alors la fonction getopt() s'arrête
\r
69 * dès qu'un argument de la ligne de commande n'est pas une option
\r
71 else if (optstring[0] == '+')
\r
73 ordering = REQUIRE_ORDER;
\r
85 __getopt_internal (int argc, char *const *argv, const char* optstring, const struct option *longopts, int* longind, int long_only)
\r
90 optstring = __getopt_initialize (optstring);
\r
92 if (nextchar == NULL || *nextchar == '\0')
\r
94 /* Advance to the next ARGV-element. */
\r
96 if (ordering == PERMUTE)
\r
98 /* If we have just processed some options following some non-options,
\r
99 __exchange them so that the options come first. */
\r
101 if (first_nonopt != last_nonopt && last_nonopt != optind)
\r
102 __exchange ((char **) argv);
\r
103 else if (last_nonopt != optind)
\r
104 first_nonopt = optind;
\r
106 /* Skip any additional non-options
\r
107 and extend the range of non-options previously skipped. */
\r
109 while (optind < argc && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
\r
112 last_nonopt = optind;
\r
115 /* The special ARGV-element `--' means premature end of options.
\r
116 Skip it like a null option,
\r
117 then __exchange with previous non-options as if it were an option,
\r
118 then skip everything else like a non-option. */
\r
120 if (optind != argc && !strcmp (argv[optind], "--"))
\r
124 if (first_nonopt != last_nonopt && last_nonopt != optind)
\r
125 __exchange ((char **) argv);
\r
126 else if (first_nonopt == last_nonopt)
\r
127 first_nonopt = optind;
\r
129 last_nonopt = argc;
\r
134 /* If we have done all the ARGV-elements, stop the scan
\r
135 and back over any non-options that we skipped and permuted. */
\r
137 if (optind == argc)
\r
139 /* Set the next-arg-index to point at the non-options
\r
140 that we previously skipped, so the caller will digest them. */
\r
141 if (first_nonopt != last_nonopt)
\r
142 optind = first_nonopt;
\r
147 /* If we have come to a non-option and did not permute it,
\r
148 either stop the scan or describe it to the caller and pass it by. */
\r
150 if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
\r
152 if (ordering == REQUIRE_ORDER)
\r
154 optarg = argv[optind++];
\r
158 /* We have found another option-ARGV-element.
\r
159 Skip the initial punctuation. */
\r
161 nextchar = (argv[optind] + 1 + (longopts != NULL && argv[optind][1] == '-'));
\r
164 /* Decode the current option-ARGV-element. */
\r
166 /* Check whether the ARGV-element is a long option.
\r
168 If long_only and the ARGV-element has the form "-f", where f is
\r
169 a valid short option, don't consider it an abbreviated form of
\r
170 a long option that starts with f. Otherwise there would be no
\r
171 way to give the -f short option.
\r
173 On the other hand, if there's a long option "fubar" and
\r
174 the ARGV-element is "-fu", do consider that an abbreviation of
\r
175 the long option, just like "--fu", and not "-f" with arg "u".
\r
177 This distinction seems to be the most useful approach. */
\r
179 if (longopts != NULL && (argv[optind][1] == '-' || (long_only && (argv[optind][2] || !strchr (optstring, argv[optind][1])))))
\r
182 const struct option *p;
\r
183 const struct option *pfound = NULL;
\r
189 for (nameend = nextchar; *nameend !='\0' && *nameend != '='; nameend++)
\r
190 /* Do nothing. */ ;
\r
192 /* Test all long options for either exact match
\r
193 or abbreviated matches. */
\r
194 for (p = longopts, option_index = 0; p->name; p++, option_index++)
\r
196 if(!strncmp (p->name, nextchar, nameend - nextchar))
\r
199 if (nameend - nextchar == strlen (p->name))
\r
201 /* Exact match found. */
\r
203 indfound = option_index;
\r
207 else if (pfound == NULL)
\r
209 /* First nonexact match found. */
\r
213 indfound = option_index;
\r
220 /* Second or later nonexact match found. */
\r
226 if (ambig && !exact)
\r
229 fprintf (stderr, "error : %s: option `%s' is ambiguous\n",argv[0], argv[optind]);
\r
231 nextchar += strlen (nextchar);
\r
236 if (pfound != NULL)
\r
238 option_index = indfound;
\r
243 /* Don't test has_arg with >, because some C compilers don't
\r
244 allow it to be used on enums. */
\r
245 if (pfound->has_arg)
\r
246 optarg = nameend + 1;
\r
251 if (argv[optind - 1][1] == '-')
\r
253 fprintf (stderr,"error : %s: option `--%s' doesn't allow an argument\n",argv[0], pfound->name);
\r
255 /* +option or -option */
\r
256 fprintf (stderr,"error : %s: option `%c%s' doesn't allow an argument\n",argv[0], argv[optind - 1][0], pfound->name);
\r
259 nextchar += strlen (nextchar);
\r
263 else if (pfound->has_arg == 1)
\r
266 optarg = argv[optind++];
\r
270 fprintf (stderr, "error : %s: option `%s' requires an argument\n",argv[0], argv[optind - 1]);
\r
272 nextchar += strlen (nextchar);
\r
273 return optstring[0] == ':' ? ':' : '?';
\r
277 nextchar += strlen (nextchar);
\r
279 if (longind != NULL)
\r
280 *longind = option_index;
\r
284 *(pfound->flag) = pfound->val;
\r
288 return pfound->val;
\r
291 /* Can't find it as a long option. If this is not getopt_long_only,
\r
292 or the option starts with '--' or is not a valid short
\r
293 option, then it's an error.
\r
294 Otherwise interpret it as a short option. */
\r
295 if (!long_only || argv[optind][1] == '-'|| strchr (optstring, *nextchar) == NULL)
\r
299 if (argv[optind][1] == '-')
\r
301 fprintf (stderr, "error : %s: unrecognized option `--%s'\n",argv[0], nextchar);
\r
303 /* +option or -option */
\r
304 fprintf (stderr, "error : %s: unrecognized option `%c%s'\n",argv[0], argv[optind][0], nextchar);
\r
307 nextchar = (char *) "";
\r
313 /* Look at and handle the next short option-character. */
\r
316 char c = *nextchar++;
\r
317 char *temp = strchr (optstring, c);
\r
319 /* Increment `optind' when we start to process its last character. */
\r
320 if (*nextchar == '\0')
\r
323 if (temp == NULL || c == ':')
\r
326 fprintf (stderr, "error : %s: invalid option -- %c\n", argv[0], c);
\r
332 if (temp[1] == ':')
\r
334 if (temp[2] == ':')
\r
336 /* This is an option that accepts an argument optionally. */
\r
337 if (*nextchar != '\0')
\r
349 /* This is an option that requires an argument. */
\r
350 if (*nextchar != '\0')
\r
353 /* If we end this ARGV-element by taking the rest as an arg,
\r
354 we must advance to the next element now. */
\r
357 else if (optind == argc)
\r
361 /* 1003.2 specifies the format of this message. */
\r
362 fprintf (stderr, "error : %s: option requires an argument -- %c\n",argv[0], c);
\r
366 if (optstring[0] == ':')
\r
372 /* We already incremented `optind' once;
\r
373 increment it again when taking next ARGV-elt as argument. */
\r
374 optarg = argv[optind++];
\r
386 __exchange (char **argv)
\r
388 int bottom = first_nonopt;
\r
389 int middle = last_nonopt;
\r
393 /* Exchange the shorter segment with the far end of the longer segment.
\r
394 That puts the shorter segment into the right place.
\r
395 It leaves the longer segment in the right place overall,
\r
396 but it consists of two parts that need to be swapped next. */
\r
398 while (top > middle && middle > bottom)
\r
400 if (top - middle > middle - bottom)
\r
402 /* Bottom segment is the short one. */
\r
403 int len = middle - bottom;
\r
406 /* Swap it with the top part of the top segment. */
\r
407 for (i = 0; i < len; i++)
\r
409 tem = argv[bottom + i];
\r
410 argv[bottom + i] = argv[top - (middle - bottom) + i];
\r
411 argv[top - (middle - bottom) + i] = tem;
\r
413 /* Exclude the moved bottom segment from further swapping. */
\r
419 /* Top segment is the short one. */
\r
420 int len = top - middle;
\r
423 /* Swap it with the bottom part of the bottom segment. */
\r
424 for (i = 0; i < len; i++)
\r
426 tem = argv[bottom + i];
\r
427 argv[bottom + i] = argv[middle + i];
\r
428 argv[middle + i] = tem;
\r
430 /* Exclude the moved top segment from further swapping. */
\r
435 /* Update records for the slots the non-options now occupy. */
\r
437 first_nonopt += (optind - last_nonopt);
\r
438 last_nonopt = optind;
\r
442 getopt_long (int argc, char *const *argv, const char *options, const struct option *long_options, int *opt_index)
\r
444 return __getopt_internal (argc, argv, options, long_options, opt_index, 0);
\r
449 getopt_long_only(int argc, char *const *argv, const char *options, const struct option *long_options,int *opt_index)
\r
451 return __getopt_internal (argc, argv, options, long_options, opt_index, 1);
\r