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