aboutsummaryrefslogtreecommitdiff
path: root/src/util/getopt.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/getopt.c')
-rw-r--r--src/util/getopt.c1018
1 files changed, 507 insertions, 511 deletions
diff --git a/src/util/getopt.c b/src/util/getopt.c
index 4a36678b2..317bc0748 100644
--- a/src/util/getopt.c
+++ b/src/util/getopt.c
@@ -198,19 +198,20 @@ static char *posixly_correct;
198/* Avoid depending on library functions or files 198/* Avoid depending on library functions or files
199 whose names are inconsistent. */ 199 whose names are inconsistent. */
200 200
201char *getenv (); 201char *
202getenv ();
202 203
203static char * 204static char *
204my_index (str, chr) 205my_index (str, chr)
205 const char *str; 206 const char *str;
206 int chr; 207 int chr;
207{ 208{
208 while (*str) 209 while (*str)
209 { 210 {
210 if (*str == chr) 211 if (*str == chr)
211 return (char *) str; 212 return (char *) str;
212 str++; 213 str++;
213 } 214 }
214 return 0; 215 return 0;
215} 216}
216 217
@@ -222,7 +223,8 @@ my_index (str, chr)
222#if !defined (__STDC__) || !__STDC__ 223#if !defined (__STDC__) || !__STDC__
223/* gcc with -traditional declares the built-in strlen to return int, 224/* gcc with -traditional declares the built-in strlen to return int,
224 and has done so at least since version 2.4.5. -- rms. */ 225 and has done so at least since version 2.4.5. -- rms. */
225extern int strlen (const char *); 226extern int
227strlen (const char *);
226#endif /* not __STDC__ */ 228#endif /* not __STDC__ */
227#endif /* __GNUC__ */ 229#endif /* __GNUC__ */
228 230
@@ -256,7 +258,7 @@ extern pid_t __libc_pid;
256 is valid for the getopt call we must make sure that the ARGV passed 258 is valid for the getopt call we must make sure that the ARGV passed
257 to getopt is that one passed to the process. */ 259 to getopt is that one passed to the process. */
258static void 260static void
259 __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv) 261 __attribute__ ((unused)) store_args_and_env (int argc, char *const *argv)
260{ 262{
261 /* XXX This is no good solution. We should rather copy the args so 263 /* XXX This is no good solution. We should rather copy the args so
262 * that we can compare them later. But we must not use malloc(3). */ 264 * that we can compare them later. But we must not use malloc(3). */
@@ -287,12 +289,13 @@ text_set_element (__libc_subinit, store_args_and_env);
287 the new indices of the non-options in ARGV after they are moved. */ 289 the new indices of the non-options in ARGV after they are moved. */
288 290
289#if defined (__STDC__) && __STDC__ 291#if defined (__STDC__) && __STDC__
290static void exchange (char **); 292static void
293exchange (char **);
291#endif 294#endif
292 295
293static void 296static void
294exchange (argv) 297exchange (argv)
295 char **argv; 298 char **argv;
296{ 299{
297 int bottom = first_nonopt; 300 int bottom = first_nonopt;
298 int middle = last_nonopt; 301 int middle = last_nonopt;
@@ -309,61 +312,61 @@ exchange (argv)
309 * string can work normally. Our top argument must be in the range 312 * string can work normally. Our top argument must be in the range
310 * of the string. */ 313 * of the string. */
311 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) 314 if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
312 { 315 {
313 /* We must extend the array. The user plays games with us and 316 /* We must extend the array. The user plays games with us and
314 * presents new arguments. */ 317 * presents new arguments. */
315 char *new_str = malloc (top + 1); 318 char *new_str = malloc (top + 1);
316 319
317 if (new_str == NULL) 320 if (new_str == NULL)
318 nonoption_flags_len = nonoption_flags_max_len = 0; 321 nonoption_flags_len = nonoption_flags_max_len = 0;
319 else 322 else
320 { 323 {
321 memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len); 324 memcpy (new_str, __getopt_nonoption_flags, nonoption_flags_max_len);
322 memset (&new_str[nonoption_flags_max_len], '\0', 325 memset (&new_str[nonoption_flags_max_len], '\0',
323 top + 1 - nonoption_flags_max_len); 326 top + 1 - nonoption_flags_max_len);
324 nonoption_flags_max_len = top + 1; 327 nonoption_flags_max_len = top + 1;
325 __getopt_nonoption_flags = new_str; 328 __getopt_nonoption_flags = new_str;
326 }
327 } 329 }
330 }
328#endif 331#endif
329 332
330 while (top > middle && middle > bottom) 333 while (top > middle && middle > bottom)
334 {
335 if (top - middle > middle - bottom)
331 { 336 {
332 if (top - middle > middle - bottom) 337 /* Bottom segment is the short one. */
333 { 338 int len = middle - bottom;
334 /* Bottom segment is the short one. */ 339 register int i;
335 int len = middle - bottom; 340
336 register int i; 341 /* Swap it with the top part of the top segment. */
337 342 for (i = 0; i < len; i++)
338 /* Swap it with the top part of the top segment. */ 343 {
339 for (i = 0; i < len; i++) 344 tem = argv[bottom + i];
340 { 345 argv[bottom + i] = argv[top - (middle - bottom) + i];
341 tem = argv[bottom + i]; 346 argv[top - (middle - bottom) + i] = tem;
342 argv[bottom + i] = argv[top - (middle - bottom) + i]; 347 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
343 argv[top - (middle - bottom) + i] = tem; 348 }
344 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); 349 /* Exclude the moved bottom segment from further swapping. */
345 } 350 top -= len;
346 /* Exclude the moved bottom segment from further swapping. */ 351 }
347 top -= len; 352 else
348 } 353 {
349 else 354 /* Top segment is the short one. */
350 { 355 int len = top - middle;
351 /* Top segment is the short one. */ 356 register int i;
352 int len = top - middle; 357
353 register int i; 358 /* Swap it with the bottom part of the bottom segment. */
354 359 for (i = 0; i < len; i++)
355 /* Swap it with the bottom part of the bottom segment. */ 360 {
356 for (i = 0; i < len; i++) 361 tem = argv[bottom + i];
357 { 362 argv[bottom + i] = argv[middle + i];
358 tem = argv[bottom + i]; 363 argv[middle + i] = tem;
359 argv[bottom + i] = argv[middle + i]; 364 SWAP_FLAGS (bottom + i, middle + i);
360 argv[middle + i] = tem; 365 }
361 SWAP_FLAGS (bottom + i, middle + i); 366 /* Exclude the moved top segment from further swapping. */
362 } 367 bottom += len;
363 /* Exclude the moved top segment from further swapping. */
364 bottom += len;
365 }
366 } 368 }
369 }
367 370
368 /* Update records for the slots the non-options now occupy. */ 371 /* Update records for the slots the non-options now occupy. */
369 372
@@ -374,13 +377,14 @@ exchange (argv)
374/* Initialize the internal data when the first call is made. */ 377/* Initialize the internal data when the first call is made. */
375 378
376#if defined (__STDC__) && __STDC__ 379#if defined (__STDC__) && __STDC__
377static const char *_getopt_initialize (int, char *const *, const char *); 380static const char *
381_getopt_initialize (int, char *const *, const char *);
378#endif 382#endif
379static const char * 383static const char *
380_getopt_initialize (argc, argv, optstring) 384_getopt_initialize (argc, argv, optstring)
381 int argc; 385 int argc;
382 char *const *argv; 386 char *const *argv;
383 const char *optstring; 387 const char *optstring;
384{ 388{
385 /* Start processing options with ARGV-element 1 (since ARGV-element 0 389 /* Start processing options with ARGV-element 1 (since ARGV-element 0
386 * is the program name); the sequence of previously skipped 390 * is the program name); the sequence of previously skipped
@@ -395,50 +399,48 @@ _getopt_initialize (argc, argv, optstring)
395 /* Determine how to handle the ordering of options and nonoptions. */ 399 /* Determine how to handle the ordering of options and nonoptions. */
396 400
397 if (optstring[0] == '-') 401 if (optstring[0] == '-')
398 { 402 {
399 ordering = RETURN_IN_ORDER; 403 ordering = RETURN_IN_ORDER;
400 ++optstring; 404 ++optstring;
401 } 405 }
402 else if (optstring[0] == '+') 406 else if (optstring[0] == '+')
403 { 407 {
404 ordering = REQUIRE_ORDER; 408 ordering = REQUIRE_ORDER;
405 ++optstring; 409 ++optstring;
406 } 410 }
407 else if (posixly_correct != NULL) 411 else if (posixly_correct != NULL)
408 ordering = REQUIRE_ORDER; 412 ordering = REQUIRE_ORDER;
409 else 413 else
410 ordering = PERMUTE; 414 ordering = PERMUTE;
411 415
412#ifdef _LIBC 416#ifdef _LIBC
413 if (posixly_correct == NULL && argc == original_argc 417 if (posixly_correct == NULL && argc == original_argc && argv == original_argv)
414 && argv == original_argv) 418 {
419 if (nonoption_flags_max_len == 0)
415 { 420 {
416 if (nonoption_flags_max_len == 0) 421 if (__getopt_nonoption_flags == NULL ||
417 { 422 __getopt_nonoption_flags[0] == '\0')
418 if (__getopt_nonoption_flags == NULL || 423 nonoption_flags_max_len = -1;
419 __getopt_nonoption_flags[0] == '\0') 424 else
420 nonoption_flags_max_len = -1; 425 {
421 else 426 const char *orig_str = __getopt_nonoption_flags;
422 { 427 int len = nonoption_flags_max_len = strlen (orig_str);
423 const char *orig_str = __getopt_nonoption_flags; 428
424 int len = nonoption_flags_max_len = strlen (orig_str); 429 if (nonoption_flags_max_len < argc)
425 430 nonoption_flags_max_len = argc;
426 if (nonoption_flags_max_len < argc) 431 __getopt_nonoption_flags = (char *) malloc (nonoption_flags_max_len);
427 nonoption_flags_max_len = argc; 432 if (__getopt_nonoption_flags == NULL)
428 __getopt_nonoption_flags = 433 nonoption_flags_max_len = -1;
429 (char *) malloc (nonoption_flags_max_len); 434 else
430 if (__getopt_nonoption_flags == NULL) 435 {
431 nonoption_flags_max_len = -1; 436 memcpy (__getopt_nonoption_flags, orig_str, len);
432 else 437 memset (&__getopt_nonoption_flags[len], '\0',
433 { 438 nonoption_flags_max_len - len);
434 memcpy (__getopt_nonoption_flags, orig_str, len); 439 }
435 memset (&__getopt_nonoption_flags[len], '\0', 440 }
436 nonoption_flags_max_len - len);
437 }
438 }
439 }
440 nonoption_flags_len = nonoption_flags_max_len;
441 } 441 }
442 nonoption_flags_len = nonoption_flags_max_len;
443 }
442 else 444 else
443 nonoption_flags_len = 0; 445 nonoption_flags_len = 0;
444#endif 446#endif
@@ -504,8 +506,8 @@ _getopt_initialize (argc, argv, optstring)
504 506
505static int 507static int
506GN_getopt_internal (int argc, char *const *argv, const char *optstring, 508GN_getopt_internal (int argc, char *const *argv, const char *optstring,
507 const struct GNoption *longopts, int *longind, 509 const struct GNoption *longopts, int *longind,
508 int long_only) 510 int long_only)
509{ 511{
510 static int __getopt_initialized = 0; 512 static int __getopt_initialized = 0;
511 static int GNopterr = 1; 513 static int GNopterr = 1;
@@ -513,12 +515,12 @@ GN_getopt_internal (int argc, char *const *argv, const char *optstring,
513 GNoptarg = NULL; 515 GNoptarg = NULL;
514 516
515 if (GNoptind == 0 || !__getopt_initialized) 517 if (GNoptind == 0 || !__getopt_initialized)
516 { 518 {
517 if (GNoptind == 0) 519 if (GNoptind == 0)
518 GNoptind = 1; /* Don't scan ARGV[0], the program name. */ 520 GNoptind = 1; /* Don't scan ARGV[0], the program name. */
519 optstring = _getopt_initialize (argc, argv, optstring); 521 optstring = _getopt_initialize (argc, argv, optstring);
520 __getopt_initialized = 1; 522 __getopt_initialized = 1;
521 } 523 }
522 524
523 /* Test whether ARGV[GNoptind] points to a non-option argument. 525 /* Test whether ARGV[GNoptind] points to a non-option argument.
524 * Either it does not have option syntax, or there is an environment flag 526 * Either it does not have option syntax, or there is an environment flag
@@ -533,81 +535,81 @@ GN_getopt_internal (int argc, char *const *argv, const char *optstring,
533#endif 535#endif
534 536
535 if (nextchar == NULL || *nextchar == '\0') 537 if (nextchar == NULL || *nextchar == '\0')
538 {
539 /* Advance to the next ARGV-element. */
540
541 /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been
542 * moved back by the user (who may also have changed the arguments). */
543 if (last_nonopt > GNoptind)
544 last_nonopt = GNoptind;
545 if (first_nonopt > GNoptind)
546 first_nonopt = GNoptind;
547
548 if (ordering == PERMUTE)
536 { 549 {
537 /* Advance to the next ARGV-element. */ 550 /* If we have just processed some options following some non-options,
538 551 * exchange them so that the options come first. */
539 /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been 552
540 * moved back by the user (who may also have changed the arguments). */ 553 if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
541 if (last_nonopt > GNoptind) 554 exchange ((char **) argv);
542 last_nonopt = GNoptind; 555 else if (last_nonopt != GNoptind)
543 if (first_nonopt > GNoptind) 556 first_nonopt = GNoptind;
544 first_nonopt = GNoptind; 557
545 558 /* Skip any additional non-options
546 if (ordering == PERMUTE) 559 * and extend the range of non-options previously skipped. */
547 { 560
548 /* If we have just processed some options following some non-options, 561 while (GNoptind < argc && NONOPTION_P)
549 * exchange them so that the options come first. */ 562 GNoptind++;
550 563 last_nonopt = GNoptind;
551 if (first_nonopt != last_nonopt && last_nonopt != GNoptind) 564 }
552 exchange ((char **) argv); 565
553 else if (last_nonopt != GNoptind) 566 /* The special ARGV-element `--' means premature end of options.
554 first_nonopt = GNoptind; 567 * Skip it like a null option,
555 568 * then exchange with previous non-options as if it were an option,
556 /* Skip any additional non-options 569 * then skip everything else like a non-option. */
557 * and extend the range of non-options previously skipped. */ 570 if (GNoptind != argc && !strcmp (argv[GNoptind], "--"))
558 571 {
559 while (GNoptind < argc && NONOPTION_P) 572 GNoptind++;
560 GNoptind++; 573
561 last_nonopt = GNoptind; 574 if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
562 } 575 exchange ((char **) argv);
563 576 else if (first_nonopt == last_nonopt)
564 /* The special ARGV-element `--' means premature end of options. 577 first_nonopt = GNoptind;
565 * Skip it like a null option, 578 last_nonopt = argc;
566 * then exchange with previous non-options as if it were an option, 579
567 * then skip everything else like a non-option. */ 580 GNoptind = argc;
568 if (GNoptind != argc && !strcmp (argv[GNoptind], "--"))
569 {
570 GNoptind++;
571
572 if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
573 exchange ((char **) argv);
574 else if (first_nonopt == last_nonopt)
575 first_nonopt = GNoptind;
576 last_nonopt = argc;
577
578 GNoptind = argc;
579 }
580
581 /* If we have done all the ARGV-elements, stop the scan
582 * and back over any non-options that we skipped and permuted. */
583
584 if (GNoptind == argc)
585 {
586 /* Set the next-arg-index to point at the non-options
587 * that we previously skipped, so the caller will digest them. */
588 if (first_nonopt != last_nonopt)
589 GNoptind = first_nonopt;
590 return -1;
591 }
592
593 /* If we have come to a non-option and did not permute it,
594 * either stop the scan or describe it to the caller and pass it by. */
595
596 if (NONOPTION_P)
597 {
598 if (ordering == REQUIRE_ORDER)
599 return -1;
600 GNoptarg = argv[GNoptind++];
601 return 1;
602 }
603
604 /* We have found another option-ARGV-element.
605 * Skip the initial punctuation. */
606
607 nextchar =
608 (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-'));
609 } 581 }
610 582
583 /* If we have done all the ARGV-elements, stop the scan
584 * and back over any non-options that we skipped and permuted. */
585
586 if (GNoptind == argc)
587 {
588 /* Set the next-arg-index to point at the non-options
589 * that we previously skipped, so the caller will digest them. */
590 if (first_nonopt != last_nonopt)
591 GNoptind = first_nonopt;
592 return -1;
593 }
594
595 /* If we have come to a non-option and did not permute it,
596 * either stop the scan or describe it to the caller and pass it by. */
597
598 if (NONOPTION_P)
599 {
600 if (ordering == REQUIRE_ORDER)
601 return -1;
602 GNoptarg = argv[GNoptind++];
603 return 1;
604 }
605
606 /* We have found another option-ARGV-element.
607 * Skip the initial punctuation. */
608
609 nextchar =
610 (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-'));
611 }
612
611 /* Decode the current option-ARGV-element. */ 613 /* Decode the current option-ARGV-element. */
612 614
613 /* Check whether the ARGV-element is a long option. 615 /* Check whether the ARGV-element is a long option.
@@ -626,138 +628,134 @@ GN_getopt_internal (int argc, char *const *argv, const char *optstring,
626 if (longopts != NULL && 628 if (longopts != NULL &&
627 (argv[GNoptind][1] == '-' || 629 (argv[GNoptind][1] == '-' ||
628 (long_only && 630 (long_only &&
629 (argv[GNoptind][2] || !my_index (optstring, argv[GNoptind][1]))))) 631 (argv[GNoptind][2] || !my_index (optstring, argv[GNoptind][1])))))
630 { 632 {
631 char *nameend; 633 char *nameend;
632 const struct GNoption *p; 634 const struct GNoption *p;
633 const struct GNoption *pfound = NULL; 635 const struct GNoption *pfound = NULL;
634 int exact = 0; 636 int exact = 0;
635 int ambig = 0; 637 int ambig = 0;
636 int indfound = -1; 638 int indfound = -1;
637 int option_index; 639 int option_index;
638 640
639 for (nameend = nextchar; *nameend && *nameend != '='; nameend++) 641 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
640 /* Do nothing. */ ; 642 /* Do nothing. */ ;
643
644 /* Test all long options for either exact match
645 * or abbreviated matches. */
646 for (p = longopts, option_index = 0; p->name; p++, option_index++)
647 if (!strncmp (p->name, nextchar, nameend - nextchar))
648 {
649 if ((unsigned int) (nameend - nextchar) ==
650 (unsigned int) strlen (p->name))
651 {
652 /* Exact match found. */
653 pfound = p;
654 indfound = option_index;
655 exact = 1;
656 break;
657 }
658 else if (pfound == NULL)
659 {
660 /* First nonexact match found. */
661 pfound = p;
662 indfound = option_index;
663 }
664 else
665 /* Second or later nonexact match found. */
666 ambig = 1;
667 }
641 668
642 /* Test all long options for either exact match 669 if (ambig && !exact)
643 * or abbreviated matches. */ 670 {
644 for (p = longopts, option_index = 0; p->name; p++, option_index++) 671 if (GNopterr)
645 if (!strncmp (p->name, nextchar, nameend - nextchar)) 672 fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0],
646 { 673 argv[GNoptind]);
647 if ((unsigned int) (nameend - nextchar) == 674 nextchar += strlen (nextchar);
648 (unsigned int) strlen (p->name)) 675 GNoptind++;
649 { 676 return '?';
650 /* Exact match found. */ 677 }
651 pfound = p;
652 indfound = option_index;
653 exact = 1;
654 break;
655 }
656 else if (pfound == NULL)
657 {
658 /* First nonexact match found. */
659 pfound = p;
660 indfound = option_index;
661 }
662 else
663 /* Second or later nonexact match found. */
664 ambig = 1;
665 }
666 678
667 if (ambig && !exact) 679 if (pfound != NULL)
668 { 680 {
669 if (GNopterr) 681 option_index = indfound;
670 fprintf (stderr, _("%s: option `%s' is ambiguous\n"), argv[0], 682 GNoptind++;
671 argv[GNoptind]); 683 if (*nameend)
672 nextchar += strlen (nextchar); 684 {
673 GNoptind++; 685 /* Don't test has_arg with >, because some C compilers don't
674 return '?'; 686 * allow it to be used on enums. */
675 } 687 if (pfound->has_arg)
688 GNoptarg = nameend + 1;
689 else
690 {
691 if (GNopterr)
692 {
693 if (argv[GNoptind - 1][1] == '-')
694 /* --option */
695 fprintf (stderr,
696 _("%s: option `--%s' does not allow an argument\n"),
697 argv[0], pfound->name);
698 else
699 /* +option or -option */
700 fprintf (stderr,
701 _("%s: option `%c%s' does not allow an argument\n"),
702 argv[0], argv[GNoptind - 1][0], pfound->name);
703 }
704 nextchar += strlen (nextchar);
705 return '?';
706 }
707 }
708 else if (pfound->has_arg == 1)
709 {
710 if (GNoptind < argc)
711 {
712 GNoptarg = argv[GNoptind++];
713 }
714 else
715 {
716 if (GNopterr)
717 {
718 fprintf (stderr, _("%s: option `%s' requires an argument\n"),
719 argv[0], argv[GNoptind - 1]);
720 }
721 nextchar += strlen (nextchar);
722 return (optstring[0] == ':') ? ':' : '?';
723 }
724 }
725 nextchar += strlen (nextchar);
726 if (longind != NULL)
727 *longind = option_index;
728 if (pfound->flag)
729 {
730 *(pfound->flag) = pfound->val;
731 return 0;
732 }
733 return pfound->val;
734 }
676 735
677 if (pfound != NULL) 736 /* Can't find it as a long option. If this is not getopt_long_only,
678 { 737 * or the option starts with '--' or is not a valid short
679 option_index = indfound; 738 * option, then it's an error.
680 GNoptind++; 739 * Otherwise interpret it as a short option. */
681 if (*nameend) 740 if (!long_only || argv[GNoptind][1] == '-' ||
682 { 741 my_index (optstring, *nextchar) == NULL)
683 /* Don't test has_arg with >, because some C compilers don't 742 {
684 * allow it to be used on enums. */ 743 if (GNopterr)
685 if (pfound->has_arg) 744 {
686 GNoptarg = nameend + 1; 745 if (argv[GNoptind][1] == '-')
687 else 746 /* --option */
688 { 747 fprintf (stderr, _("%s: unrecognized option `--%s'\n"), argv[0],
689 if (GNopterr) 748 nextchar);
690 { 749 else
691 if (argv[GNoptind - 1][1] == '-') 750 /* +option or -option */
692 /* --option */ 751 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), argv[0],
693 fprintf (stderr, 752 argv[GNoptind][0], nextchar);
694 _ 753 }
695 ("%s: option `--%s' does not allow an argument\n"), 754 nextchar = (char *) "";
696 argv[0], pfound->name); 755 GNoptind++;
697 else 756 return '?';
698 /* +option or -option */
699 fprintf (stderr,
700 _
701 ("%s: option `%c%s' does not allow an argument\n"),
702 argv[0], argv[GNoptind - 1][0],
703 pfound->name);
704 }
705 nextchar += strlen (nextchar);
706 return '?';
707 }
708 }
709 else if (pfound->has_arg == 1)
710 {
711 if (GNoptind < argc)
712 {
713 GNoptarg = argv[GNoptind++];
714 }
715 else
716 {
717 if (GNopterr)
718 {
719 fprintf (stderr,
720 _("%s: option `%s' requires an argument\n"),
721 argv[0], argv[GNoptind - 1]);
722 }
723 nextchar += strlen (nextchar);
724 return (optstring[0] == ':') ? ':' : '?';
725 }
726 }
727 nextchar += strlen (nextchar);
728 if (longind != NULL)
729 *longind = option_index;
730 if (pfound->flag)
731 {
732 *(pfound->flag) = pfound->val;
733 return 0;
734 }
735 return pfound->val;
736 }
737
738 /* Can't find it as a long option. If this is not getopt_long_only,
739 * or the option starts with '--' or is not a valid short
740 * option, then it's an error.
741 * Otherwise interpret it as a short option. */
742 if (!long_only || argv[GNoptind][1] == '-' ||
743 my_index (optstring, *nextchar) == NULL)
744 {
745 if (GNopterr)
746 {
747 if (argv[GNoptind][1] == '-')
748 /* --option */
749 fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
750 argv[0], nextchar);
751 else
752 /* +option or -option */
753 fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
754 argv[0], argv[GNoptind][0], nextchar);
755 }
756 nextchar = (char *) "";
757 GNoptind++;
758 return '?';
759 }
760 } 757 }
758 }
761 759
762 /* Look at and handle the next short option-character. */ 760 /* Look at and handle the next short option-character. */
763 761
@@ -770,193 +768,191 @@ GN_getopt_internal (int argc, char *const *argv, const char *optstring,
770 ++GNoptind; 768 ++GNoptind;
771 769
772 if (temp == NULL || c == ':') 770 if (temp == NULL || c == ':')
771 {
772 if (GNopterr)
773 { 773 {
774 if (GNopterr) 774 if (posixly_correct)
775 { 775 /* 1003.2 specifies the format of this message. */
776 if (posixly_correct) 776 fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
777 /* 1003.2 specifies the format of this message. */ 777 else
778 fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c); 778 fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
779 else
780 fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
781 }
782 return '?';
783 } 779 }
780 return '?';
781 }
784 /* Convenience. Treat POSIX -W foo same as long option --foo */ 782 /* Convenience. Treat POSIX -W foo same as long option --foo */
785 if (temp[0] == 'W' && temp[1] == ';') 783 if (temp[0] == 'W' && temp[1] == ';')
784 {
785 char *nameend;
786 const struct GNoption *p;
787 const struct GNoption *pfound = NULL;
788 int exact = 0;
789 int ambig = 0;
790 int indfound = 0;
791 int option_index;
792
793 /* This is an option that requires an argument. */
794 if (*nextchar != '\0')
786 { 795 {
787 char *nameend; 796 GNoptarg = nextchar;
788 const struct GNoption *p; 797 /* If we end this ARGV-element by taking the rest as an arg,
789 const struct GNoption *pfound = NULL; 798 * we must advance to the next element now. */
790 int exact = 0; 799 GNoptind++;
791 int ambig = 0; 800 }
792 int indfound = 0; 801 else if (GNoptind == argc)
793 int option_index; 802 {
794 803 if (GNopterr)
795 /* This is an option that requires an argument. */ 804 {
796 if (*nextchar != '\0') 805 /* 1003.2 specifies the format of this message. */
797 { 806 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
798 GNoptarg = nextchar; 807 argv[0], c);
799 /* If we end this ARGV-element by taking the rest as an arg, 808 }
800 * we must advance to the next element now. */ 809 if (optstring[0] == ':')
801 GNoptind++; 810 c = ':';
802 } 811 else
803 else if (GNoptind == argc) 812 c = '?';
804 { 813 return c;
805 if (GNopterr) 814 }
806 { 815 else
807 /* 1003.2 specifies the format of this message. */ 816 /* We already incremented `GNoptind' once;
808 fprintf (stderr, _("%s: option requires an argument -- %c\n"), 817 * increment it again when taking next ARGV-elt as argument. */
809 argv[0], c); 818 GNoptarg = argv[GNoptind++];
810 } 819
811 if (optstring[0] == ':') 820 /* GNoptarg is now the argument, see if it's in the
812 c = ':'; 821 * table of longopts. */
813 else 822
814 c = '?'; 823 for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
815 return c; 824 nameend++)
816 } 825 /* Do nothing. */ ;
817 else 826
818 /* We already incremented `GNoptind' once; 827 /* Test all long options for either exact match
819 * increment it again when taking next ARGV-elt as argument. */ 828 * or abbreviated matches. */
820 GNoptarg = argv[GNoptind++]; 829 if (longopts != NULL)
821 830 for (p = longopts, option_index = 0; p->name; p++, option_index++)
822 /* GNoptarg is now the argument, see if it's in the 831 if (!strncmp (p->name, nextchar, nameend - nextchar))
823 * table of longopts. */ 832 {
824 833 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
825 for (nextchar = nameend = GNoptarg; *nameend && *nameend != '='; 834 {
826 nameend++) 835 /* Exact match found. */
827 /* Do nothing. */ ; 836 pfound = p;
828 837 indfound = option_index;
829 /* Test all long options for either exact match 838 exact = 1;
830 * or abbreviated matches. */ 839 break;
831 if (longopts != NULL) 840 }
832 for (p = longopts, option_index = 0; p->name; p++, option_index++) 841 else if (pfound == NULL)
833 if (!strncmp (p->name, nextchar, nameend - nextchar)) 842 {
834 { 843 /* First nonexact match found. */
835 if ((unsigned int) (nameend - nextchar) == strlen (p->name)) 844 pfound = p;
836 { 845 indfound = option_index;
837 /* Exact match found. */ 846 }
838 pfound = p; 847 else
839 indfound = option_index; 848 /* Second or later nonexact match found. */
840 exact = 1; 849 ambig = 1;
841 break; 850 }
842 } 851 if (ambig && !exact)
843 else if (pfound == NULL) 852 {
844 { 853 if (GNopterr)
845 /* First nonexact match found. */ 854 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), argv[0],
846 pfound = p; 855 argv[GNoptind]);
847 indfound = option_index; 856 nextchar += strlen (nextchar);
848 } 857 GNoptind++;
849 else 858 return '?';
850 /* Second or later nonexact match found. */ 859 }
851 ambig = 1; 860 if (pfound != NULL)
852 } 861 {
853 if (ambig && !exact) 862 option_index = indfound;
854 { 863 if (*nameend)
855 if (GNopterr) 864 {
856 fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), 865 /* Don't test has_arg with >, because some C compilers don't
857 argv[0], argv[GNoptind]); 866 * allow it to be used on enums. */
858 nextchar += strlen (nextchar); 867 if (pfound->has_arg)
859 GNoptind++; 868 GNoptarg = nameend + 1;
860 return '?'; 869 else
861 } 870 {
862 if (pfound != NULL) 871 if (GNopterr)
863 { 872 fprintf (stderr, _("\
864 option_index = indfound;
865 if (*nameend)
866 {
867 /* Don't test has_arg with >, because some C compilers don't
868 * allow it to be used on enums. */
869 if (pfound->has_arg)
870 GNoptarg = nameend + 1;
871 else
872 {
873 if (GNopterr)
874 fprintf (stderr, _("\
875%s: option `-W %s' does not allow an argument\n"), argv[0], pfound->name); 873%s: option `-W %s' does not allow an argument\n"), argv[0], pfound->name);
876 874
877 nextchar += strlen (nextchar); 875 nextchar += strlen (nextchar);
878 return '?'; 876 return '?';
879 } 877 }
880 } 878 }
881 else if (pfound->has_arg == 1) 879 else if (pfound->has_arg == 1)
882 { 880 {
883 if (GNoptind < argc) 881 if (GNoptind < argc)
884 GNoptarg = argv[GNoptind++]; 882 GNoptarg = argv[GNoptind++];
885 else 883 else
886 { 884 {
887 if (GNopterr) 885 if (GNopterr)
888 fprintf (stderr, 886 fprintf (stderr, _("%s: option `%s' requires an argument\n"),
889 _("%s: option `%s' requires an argument\n"), 887 argv[0], argv[GNoptind - 1]);
890 argv[0], argv[GNoptind - 1]); 888 nextchar += strlen (nextchar);
891 nextchar += strlen (nextchar); 889 return optstring[0] == ':' ? ':' : '?';
892 return optstring[0] == ':' ? ':' : '?'; 890 }
893 } 891 }
894 } 892 nextchar += strlen (nextchar);
895 nextchar += strlen (nextchar); 893 if (longind != NULL)
896 if (longind != NULL) 894 *longind = option_index;
897 *longind = option_index; 895 if (pfound->flag)
898 if (pfound->flag) 896 {
899 { 897 *(pfound->flag) = pfound->val;
900 *(pfound->flag) = pfound->val; 898 return 0;
901 return 0; 899 }
902 } 900 return pfound->val;
903 return pfound->val;
904 }
905 nextchar = NULL;
906 return 'W'; /* Let the application handle it. */
907 } 901 }
902 nextchar = NULL;
903 return 'W'; /* Let the application handle it. */
904 }
908 if (temp[1] == ':') 905 if (temp[1] == ':')
906 {
907 if (temp[2] == ':')
909 { 908 {
910 if (temp[2] == ':') 909 /* This is an option that accepts an argument optionally. */
911 { 910 if (*nextchar != '\0')
912 /* This is an option that accepts an argument optionally. */ 911 {
913 if (*nextchar != '\0') 912 GNoptarg = nextchar;
914 { 913 GNoptind++;
915 GNoptarg = nextchar; 914 }
916 GNoptind++; 915 else
917 } 916 GNoptarg = NULL;
918 else 917 nextchar = NULL;
919 GNoptarg = NULL;
920 nextchar = NULL;
921 }
922 else
923 {
924 /* This is an option that requires an argument. */
925 if (*nextchar != '\0')
926 {
927 GNoptarg = nextchar;
928 /* If we end this ARGV-element by taking the rest as an arg,
929 * we must advance to the next element now. */
930 GNoptind++;
931 }
932 else if (GNoptind == argc)
933 {
934 if (GNopterr)
935 {
936 /* 1003.2 specifies the format of this message. */
937 fprintf (stderr,
938 _("%s: option requires an argument -- %c\n"),
939 argv[0], c);
940 }
941 if (optstring[0] == ':')
942 c = ':';
943 else
944 c = '?';
945 }
946 else
947 /* We already incremented `GNoptind' once;
948 * increment it again when taking next ARGV-elt as argument. */
949 GNoptarg = argv[GNoptind++];
950 nextchar = NULL;
951 }
952 } 918 }
919 else
920 {
921 /* This is an option that requires an argument. */
922 if (*nextchar != '\0')
923 {
924 GNoptarg = nextchar;
925 /* If we end this ARGV-element by taking the rest as an arg,
926 * we must advance to the next element now. */
927 GNoptind++;
928 }
929 else if (GNoptind == argc)
930 {
931 if (GNopterr)
932 {
933 /* 1003.2 specifies the format of this message. */
934 fprintf (stderr, _("%s: option requires an argument -- %c\n"),
935 argv[0], c);
936 }
937 if (optstring[0] == ':')
938 c = ':';
939 else
940 c = '?';
941 }
942 else
943 /* We already incremented `GNoptind' once;
944 * increment it again when taking next ARGV-elt as argument. */
945 GNoptarg = argv[GNoptind++];
946 nextchar = NULL;
947 }
948 }
953 return c; 949 return c;
954 } 950 }
955} 951}
956 952
957static int 953static int
958GNgetopt_long (int argc, char *const *argv, const char *options, 954GNgetopt_long (int argc, char *const *argv, const char *options,
959 const struct GNoption *long_options, int *opt_index) 955 const struct GNoption *long_options, int *opt_index)
960{ 956{
961 return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0); 957 return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
962} 958}
@@ -975,8 +971,8 @@ GNgetopt_long (int argc, char *const *argv, const char *options,
975 */ 971 */
976int 972int
977GNUNET_GETOPT_run (const char *binaryOptions, 973GNUNET_GETOPT_run (const char *binaryOptions,
978 const struct GNUNET_GETOPT_CommandLineOption *allOptions, 974 const struct GNUNET_GETOPT_CommandLineOption *allOptions,
979 unsigned int argc, char *const *argv) 975 unsigned int argc, char *const *argv)
980{ 976{
981 struct GNoption *long_options; 977 struct GNoption *long_options;
982 struct GNUNET_GETOPT_CommandLineProcessorContext clpc; 978 struct GNUNET_GETOPT_CommandLineProcessorContext clpc;
@@ -1001,15 +997,15 @@ GNUNET_GETOPT_run (const char *binaryOptions,
1001 shorts = GNUNET_malloc (count * 2 + 1); 997 shorts = GNUNET_malloc (count * 2 + 1);
1002 spos = 0; 998 spos = 0;
1003 for (i = 0; i < count; i++) 999 for (i = 0; i < count; i++)
1004 { 1000 {
1005 long_options[i].name = allOptions[i].name; 1001 long_options[i].name = allOptions[i].name;
1006 long_options[i].has_arg = allOptions[i].require_argument; 1002 long_options[i].has_arg = allOptions[i].require_argument;
1007 long_options[i].flag = NULL; 1003 long_options[i].flag = NULL;
1008 long_options[i].val = allOptions[i].shortName; 1004 long_options[i].val = allOptions[i].shortName;
1009 shorts[spos++] = allOptions[i].shortName; 1005 shorts[spos++] = allOptions[i].shortName;
1010 if (allOptions[i].require_argument != 0) 1006 if (allOptions[i].require_argument != 0)
1011 shorts[spos++] = ':'; 1007 shorts[spos++] = ':';
1012 } 1008 }
1013 long_options[count].name = NULL; 1009 long_options[count].name = NULL;
1014 long_options[count].has_arg = 0; 1010 long_options[count].has_arg = 0;
1015 long_options[count].flag = NULL; 1011 long_options[count].flag = NULL;
@@ -1018,31 +1014,31 @@ GNUNET_GETOPT_run (const char *binaryOptions,
1018 cont = GNUNET_OK; 1014 cont = GNUNET_OK;
1019 /* main getopt loop */ 1015 /* main getopt loop */
1020 while (cont == GNUNET_OK) 1016 while (cont == GNUNET_OK)
1017 {
1018 int option_index = 0;
1019
1020 c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
1021
1022 if (c == GNUNET_SYSERR)
1023 break; /* No more flags to process */
1024
1025 for (i = 0; i < count; i++)
1026 {
1027 clpc.currentArgument = GNoptind - 1;
1028 if ((char) c == allOptions[i].shortName)
1029 {
1030 cont =
1031 allOptions[i].processor (&clpc, allOptions[i].scls,
1032 allOptions[i].name, GNoptarg);
1033 break;
1034 }
1035 }
1036 if (i == count)
1021 { 1037 {
1022 int option_index = 0; 1038 fprintf (stderr, _("Use --help to get a list of options.\n"));
1023 1039 cont = GNUNET_SYSERR;
1024 c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
1025
1026 if (c == GNUNET_SYSERR)
1027 break; /* No more flags to process */
1028
1029 for (i = 0; i < count; i++)
1030 {
1031 clpc.currentArgument = GNoptind - 1;
1032 if ((char) c == allOptions[i].shortName)
1033 {
1034 cont =
1035 allOptions[i].processor (&clpc, allOptions[i].scls,
1036 allOptions[i].name, GNoptarg);
1037 break;
1038 }
1039 }
1040 if (i == count)
1041 {
1042 fprintf (stderr, _("Use --help to get a list of options.\n"));
1043 cont = GNUNET_SYSERR;
1044 }
1045 } 1040 }
1041 }
1046 1042
1047 GNUNET_free (shorts); 1043 GNUNET_free (shorts);
1048 GNUNET_free (long_options); 1044 GNUNET_free (long_options);