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.c1009
1 files changed, 505 insertions, 504 deletions
diff --git a/src/util/getopt.c b/src/util/getopt.c
index 3b144457a..8ec148e15 100644
--- a/src/util/getopt.c
+++ b/src/util/getopt.c
@@ -47,17 +47,17 @@
47#endif 47#endif
48#endif 48#endif
49 49
50#define LOG(kind, ...) GNUNET_log_from(kind, "util-getopt", __VA_ARGS__) 50#define LOG(kind, ...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
51 51
52#define LOG_STRERROR(kind, syscall) \ 52#define LOG_STRERROR(kind, syscall) \
53 GNUNET_log_from_strerror(kind, "util-getopt", syscall) 53 GNUNET_log_from_strerror (kind, "util-getopt", syscall)
54 54
55#ifndef _ 55#ifndef _
56/* This is for other GNU distributions with internationalized messages. 56/* This is for other GNU distributions with internationalized messages.
57 When compiling libc, the _ macro is predefined. */ 57 When compiling libc, the _ macro is predefined. */
58#ifdef HAVE_LIBINTL_H 58#ifdef HAVE_LIBINTL_H
59#include <libintl.h> 59#include <libintl.h>
60#define _(msgid) gettext(msgid) 60#define _(msgid) gettext (msgid)
61#else 61#else
62#define _(msgid) (msgid) 62#define _(msgid) (msgid)
63#endif 63#endif
@@ -84,7 +84,8 @@
84 one). For long options that have a zero `flag' field, `getopt' 84 one). For long options that have a zero `flag' field, `getopt'
85 returns the contents of the `val' field. */ 85 returns the contents of the `val' field. */
86 86
87struct GNoption { 87struct GNoption
88{
88 const char *name; 89 const char *name;
89 /* has_arg can't be an enum because some compilers complain about 90 /* has_arg can't be an enum because some compilers complain about
90 * type mismatches in all the code that assumes it is an int. */ 91 * type mismatches in all the code that assumes it is an int. */
@@ -188,17 +189,17 @@ static char *posixly_correct;
188 whose names are inconsistent. */ 189 whose names are inconsistent. */
189 190
190char * 191char *
191getenv(); 192getenv ();
192 193
193static char * 194static char *
194my_index(const char *str, int chr) 195my_index (const char *str, int chr)
195{ 196{
196 while (*str) 197 while (*str)
197 { 198 {
198 if (*str == chr) 199 if (*str == chr)
199 return (char *)str; 200 return (char *) str;
200 str++; 201 str++;
201 } 202 }
202 return 0; 203 return 0;
203} 204}
204 205
@@ -207,11 +208,11 @@ my_index(const char *str, int chr)
207#ifdef __GNUC__ 208#ifdef __GNUC__
208/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. 209/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
209 That was relevant to code that was here before. */ 210 That was relevant to code that was here before. */
210#if !defined(__STDC__) || !__STDC__ 211#if ! defined(__STDC__) || ! __STDC__
211/* gcc with -traditional declares the built-in strlen to return int, 212/* gcc with -traditional declares the built-in strlen to return int,
212 and has done so at least since version 2.4.5. -- rms. */ 213 and has done so at least since version 2.4.5. -- rms. */
213extern int 214extern int
214strlen(const char *); 215strlen (const char *);
215#endif /* not __STDC__ */ 216#endif /* not __STDC__ */
216#endif /* __GNUC__ */ 217#endif /* __GNUC__ */
217 218
@@ -239,11 +240,11 @@ static int last_nonopt;
239 240
240#if defined(__STDC__) && __STDC__ 241#if defined(__STDC__) && __STDC__
241static void 242static void
242exchange(char **); 243exchange (char **);
243#endif 244#endif
244 245
245static void 246static void
246exchange(char **argv) 247exchange (char **argv)
247{ 248{
248 int bottom = first_nonopt; 249 int bottom = first_nonopt;
249 int middle = last_nonopt; 250 int middle = last_nonopt;
@@ -256,42 +257,42 @@ exchange(char **argv)
256 * but it consists of two parts that need to be swapped next. */ 257 * but it consists of two parts that need to be swapped next. */
257 258
258 while (top > middle && middle > bottom) 259 while (top > middle && middle > bottom)
260 {
261 if (top - middle > middle - bottom)
259 { 262 {
260 if (top - middle > middle - bottom) 263 /* Bottom segment is the short one. */
261 { 264 int len = middle - bottom;
262 /* Bottom segment is the short one. */ 265 register int i;
263 int len = middle - bottom;
264 register int i;
265 266
266 /* Swap it with the top part of the top segment. */ 267 /* Swap it with the top part of the top segment. */
267 for (i = 0; i < len; i++) 268 for (i = 0; i < len; i++)
268 { 269 {
269 tem = argv[bottom + i]; 270 tem = argv[bottom + i];
270 argv[bottom + i] = argv[top - (middle - bottom) + i]; 271 argv[bottom + i] = argv[top - (middle - bottom) + i];
271 argv[top - (middle - bottom) + i] = tem; 272 argv[top - (middle - bottom) + i] = tem;
272 SWAP_FLAGS(bottom + i, top - (middle - bottom) + i); 273 SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
273 } 274 }
274 /* Exclude the moved bottom segment from further swapping. */ 275 /* Exclude the moved bottom segment from further swapping. */
275 top -= len; 276 top -= len;
276 } 277 }
277 else 278 else
278 { 279 {
279 /* Top segment is the short one. */ 280 /* Top segment is the short one. */
280 int len = top - middle; 281 int len = top - middle;
281 register int i; 282 register int i;
282 283
283 /* Swap it with the bottom part of the bottom segment. */ 284 /* Swap it with the bottom part of the bottom segment. */
284 for (i = 0; i < len; i++) 285 for (i = 0; i < len; i++)
285 { 286 {
286 tem = argv[bottom + i]; 287 tem = argv[bottom + i];
287 argv[bottom + i] = argv[middle + i]; 288 argv[bottom + i] = argv[middle + i];
288 argv[middle + i] = tem; 289 argv[middle + i] = tem;
289 SWAP_FLAGS(bottom + i, middle + i); 290 SWAP_FLAGS (bottom + i, middle + i);
290 } 291 }
291 /* Exclude the moved top segment from further swapping. */ 292 /* Exclude the moved top segment from further swapping. */
292 bottom += len; 293 bottom += len;
293 }
294 } 294 }
295 }
295 296
296 /* Update records for the slots the non-options now occupy. */ 297 /* Update records for the slots the non-options now occupy. */
297 298
@@ -303,10 +304,10 @@ exchange(char **argv)
303 304
304#if defined(__STDC__) && __STDC__ 305#if defined(__STDC__) && __STDC__
305static const char * 306static const char *
306_getopt_initialize(int, char *const *, const char *); 307_getopt_initialize (int, char *const *, const char *);
307#endif 308#endif
308static const char * 309static const char *
309_getopt_initialize(int argc, char *const *argv, const char *optstring) 310_getopt_initialize (int argc, char *const *argv, const char *optstring)
310{ 311{
311 /* Start processing options with ARGV-element 1 (since ARGV-element 0 312 /* Start processing options with ARGV-element 1 (since ARGV-element 0
312 * is the program name); the sequence of previously skipped 313 * is the program name); the sequence of previously skipped
@@ -316,20 +317,20 @@ _getopt_initialize(int argc, char *const *argv, const char *optstring)
316 317
317 nextchar = NULL; 318 nextchar = NULL;
318 319
319 posixly_correct = getenv("POSIXLY_CORRECT"); 320 posixly_correct = getenv ("POSIXLY_CORRECT");
320 321
321 /* Determine how to handle the ordering of options and nonoptions. */ 322 /* Determine how to handle the ordering of options and nonoptions. */
322 323
323 if (optstring[0] == '-') 324 if (optstring[0] == '-')
324 { 325 {
325 ordering = RETURN_IN_ORDER; 326 ordering = RETURN_IN_ORDER;
326 ++optstring; 327 ++optstring;
327 } 328 }
328 else if (optstring[0] == '+') 329 else if (optstring[0] == '+')
329 { 330 {
330 ordering = REQUIRE_ORDER; 331 ordering = REQUIRE_ORDER;
331 ++optstring; 332 ++optstring;
332 } 333 }
333 else if (posixly_correct != NULL) 334 else if (posixly_correct != NULL)
334 ordering = REQUIRE_ORDER; 335 ordering = REQUIRE_ORDER;
335 else 336 else
@@ -395,25 +396,25 @@ _getopt_initialize(int argc, char *const *argv, const char *optstring)
395 long-named options. */ 396 long-named options. */
396 397
397static int 398static int
398GN_getopt_internal(int argc, 399GN_getopt_internal (int argc,
399 char *const *argv, 400 char *const *argv,
400 const char *optstring, 401 const char *optstring,
401 const struct GNoption *longopts, 402 const struct GNoption *longopts,
402 int *longind, 403 int *longind,
403 int long_only) 404 int long_only)
404{ 405{
405 static int __getopt_initialized = 0; 406 static int __getopt_initialized = 0;
406 static int GNopterr = 1; 407 static int GNopterr = 1;
407 408
408 GNoptarg = NULL; 409 GNoptarg = NULL;
409 410
410 if (GNoptind == 0 || !__getopt_initialized) 411 if ((GNoptind == 0)|| ! __getopt_initialized)
411 { 412 {
412 if (GNoptind == 0) 413 if (GNoptind == 0)
413 GNoptind = 1; /* Don't scan ARGV[0], the program name. */ 414 GNoptind = 1; /* Don't scan ARGV[0], the program name. */
414 optstring = _getopt_initialize(argc, argv, optstring); 415 optstring = _getopt_initialize (argc, argv, optstring);
415 __getopt_initialized = 1; 416 __getopt_initialized = 1;
416 } 417 }
417 418
418 /* Test whether ARGV[GNoptind] points to a non-option argument. 419 /* Test whether ARGV[GNoptind] points to a non-option argument.
419 * Either it does not have option syntax, or there is an environment flag 420 * Either it does not have option syntax, or there is an environment flag
@@ -421,81 +422,81 @@ GN_getopt_internal(int argc,
421 * is only used when the used in the GNU libc. */ 422 * is only used when the used in the GNU libc. */
422#define NONOPTION_P (argv[GNoptind][0] != '-' || argv[GNoptind][1] == '\0') 423#define NONOPTION_P (argv[GNoptind][0] != '-' || argv[GNoptind][1] == '\0')
423 424
424 if (nextchar == NULL || *nextchar == '\0') 425 if ((nextchar == NULL)||(*nextchar == '\0'))
425 { 426 {
426 /* Advance to the next ARGV-element. */ 427 /* Advance to the next ARGV-element. */
427 428
428 /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been 429 /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been
429 * moved back by the user (who may also have changed the arguments). */ 430 * moved back by the user (who may also have changed the arguments). */
430 if (last_nonopt > GNoptind) 431 if (last_nonopt > GNoptind)
431 last_nonopt = GNoptind; 432 last_nonopt = GNoptind;
432 if (first_nonopt > GNoptind) 433 if (first_nonopt > GNoptind)
433 first_nonopt = GNoptind; 434 first_nonopt = GNoptind;
434 435
435 if (ordering == PERMUTE) 436 if (ordering == PERMUTE)
436 { 437 {
437 /* If we have just processed some options following some non-options, 438 /* If we have just processed some options following some non-options,
438 * exchange them so that the options come first. */ 439 * exchange them so that the options come first. */
439 440
440 if (first_nonopt != last_nonopt && last_nonopt != GNoptind) 441 if ((first_nonopt != last_nonopt) &&(last_nonopt != GNoptind) )
441 exchange((char **)argv); 442 exchange ((char **) argv);
442 else if (last_nonopt != GNoptind) 443 else if (last_nonopt != GNoptind)
443 first_nonopt = GNoptind; 444 first_nonopt = GNoptind;
444 445
445 /* Skip any additional non-options 446 /* Skip any additional non-options
446 * and extend the range of non-options previously skipped. */ 447 * and extend the range of non-options previously skipped. */
447 448
448 while (GNoptind < argc && NONOPTION_P) 449 while (GNoptind < argc && NONOPTION_P)
449 GNoptind++; 450 GNoptind++;
450 last_nonopt = GNoptind; 451 last_nonopt = GNoptind;
451 } 452 }
452 453
453 /* The special ARGV-element `--' means premature end of options. 454 /* The special ARGV-element `--' means premature end of options.
454 * Skip it like a null option, 455 * Skip it like a null option,
455 * then exchange with previous non-options as if it were an option, 456 * then exchange with previous non-options as if it were an option,
456 * then skip everything else like a non-option. */ 457 * then skip everything else like a non-option. */
457 if (GNoptind != argc && !strcmp(argv[GNoptind], "--")) 458 if ((GNoptind != argc) && ! strcmp (argv[GNoptind], "--"))
458 { 459 {
459 GNoptind++; 460 GNoptind++;
460 461
461 if (first_nonopt != last_nonopt && last_nonopt != GNoptind) 462 if ((first_nonopt != last_nonopt) &&(last_nonopt != GNoptind) )
462 exchange((char **)argv); 463 exchange ((char **) argv);
463 else if (first_nonopt == last_nonopt) 464 else if (first_nonopt == last_nonopt)
464 first_nonopt = GNoptind; 465 first_nonopt = GNoptind;
465 last_nonopt = argc; 466 last_nonopt = argc;
466 467
467 GNoptind = argc; 468 GNoptind = argc;
468 } 469 }
469 470
470 /* If we have done all the ARGV-elements, stop the scan 471 /* If we have done all the ARGV-elements, stop the scan
471 * and back over any non-options that we skipped and permuted. */ 472 * and back over any non-options that we skipped and permuted. */
472 473
473 if (GNoptind == argc) 474 if (GNoptind == argc)
474 { 475 {
475 /* Set the next-arg-index to point at the non-options 476 /* Set the next-arg-index to point at the non-options
476 * that we previously skipped, so the caller will digest them. */ 477 * that we previously skipped, so the caller will digest them. */
477 if (first_nonopt != last_nonopt) 478 if (first_nonopt != last_nonopt)
478 GNoptind = first_nonopt; 479 GNoptind = first_nonopt;
479 return -1; 480 return -1;
480 } 481 }
481 482
482 /* If we have come to a non-option and did not permute it, 483 /* If we have come to a non-option and did not permute it,
483 * either stop the scan or describe it to the caller and pass it by. */ 484 * either stop the scan or describe it to the caller and pass it by. */
484 485
485 if (NONOPTION_P) 486 if (NONOPTION_P)
486 { 487 {
487 if (ordering == REQUIRE_ORDER) 488 if (ordering == REQUIRE_ORDER)
488 return -1; 489 return -1;
489 GNoptarg = argv[GNoptind++]; 490 GNoptarg = argv[GNoptind++];
490 return 1; 491 return 1;
491 } 492 }
492 493
493 /* We have found another option-ARGV-element. 494 /* We have found another option-ARGV-element.
494 * Skip the initial punctuation. */ 495 * Skip the initial punctuation. */
495 496
496 nextchar = 497 nextchar =
497 (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-')); 498 (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-'));
498 } 499 }
499 500
500 /* Decode the current option-ARGV-element. */ 501 /* Decode the current option-ARGV-element. */
501 502
@@ -512,362 +513,362 @@ GN_getopt_internal(int argc,
512 * 513 *
513 * This distinction seems to be the most useful approach. */ 514 * This distinction seems to be the most useful approach. */
514 515
515 if (longopts != NULL && 516 if ((longopts != NULL)&&
516 (argv[GNoptind][1] == '-' || 517 ((argv[GNoptind][1] == '-')||
517 (long_only && 518 (long_only &&
518 (argv[GNoptind][2] || !my_index(optstring, argv[GNoptind][1]))))) 519 (argv[GNoptind][2] || ! my_index (optstring, argv[GNoptind][1])))))
519 { 520 {
520 char *nameend; 521 char *nameend;
521 const struct GNoption *p; 522 const struct GNoption *p;
522 const struct GNoption *pfound = NULL; 523 const struct GNoption *pfound = NULL;
523 int exact = 0; 524 int exact = 0;
524 int ambig = 0; 525 int ambig = 0;
525 int indfound = -1; 526 int indfound = -1;
526 int option_index; 527 int option_index;
528
529 for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
530 /* Do nothing. */;
531
532 /* Test all long options for either exact match
533 * or abbreviated matches. */
534 for (p = longopts, option_index = 0; p->name; p++, option_index++)
535 if (! strncmp (p->name, nextchar, nameend - nextchar))
536 {
537 if ((unsigned int) (nameend - nextchar) ==
538 (unsigned int) strlen (p->name))
539 {
540 /* Exact match found. */
541 pfound = p;
542 indfound = option_index;
543 exact = 1;
544 break;
545 }
546 else if (pfound == NULL)
547 {
548 /* First nonexact match found. */
549 pfound = p;
550 indfound = option_index;
551 }
552 else
553 /* Second or later nonexact match found. */
554 ambig = 1;
555 }
527 556
528 for (nameend = nextchar; *nameend && *nameend != '='; nameend++) 557 if (ambig && ! exact)
529 /* Do nothing. */; 558 {
559 if (GNopterr)
560 fprintf (stderr,
561 _ ("%s: option `%s' is ambiguous\n"),
562 argv[0],
563 argv[GNoptind]);
564 nextchar += strlen (nextchar);
565 GNoptind++;
566 return '?';
567 }
530 568
531 /* Test all long options for either exact match 569 if (pfound != NULL)
532 * or abbreviated matches. */ 570 {
533 for (p = longopts, option_index = 0; p->name; p++, option_index++) 571 option_index = indfound;
534 if (!strncmp(p->name, nextchar, nameend - nextchar)) 572 GNoptind++;
573 if (*nameend)
574 {
575 /* Don't test has_arg with >, because some C compilers don't
576 * allow it to be used on enums. */
577 if (pfound->has_arg)
578 GNoptarg = nameend + 1;
579 else
580 {
581 if (GNopterr)
535 { 582 {
536 if ((unsigned int)(nameend - nextchar) == 583 if (argv[GNoptind - 1][1] == '-')
537 (unsigned int)strlen(p->name)) 584 /* --option */
538 { 585 fprintf (stderr,
539 /* Exact match found. */ 586 _ ("%s: option `--%s' does not allow an argument\n"),
540 pfound = p; 587 argv[0],
541 indfound = option_index; 588 pfound->name);
542 exact = 1;
543 break;
544 }
545 else if (pfound == NULL)
546 {
547 /* First nonexact match found. */
548 pfound = p;
549 indfound = option_index;
550 }
551 else 589 else
552 /* Second or later nonexact match found. */ 590 /* +option or -option */
553 ambig = 1; 591 fprintf (stderr,
592 _ ("%s: option `%c%s' does not allow an argument\n"),
593 argv[0],
594 argv[GNoptind - 1][0],
595 pfound->name);
554 } 596 }
555 597 nextchar += strlen (nextchar);
556 if (ambig && !exact)
557 {
558 if (GNopterr)
559 fprintf(stderr,
560 _("%s: option `%s' is ambiguous\n"),
561 argv[0],
562 argv[GNoptind]);
563 nextchar += strlen(nextchar);
564 GNoptind++;
565 return '?'; 598 return '?';
566 } 599 }
567 600 }
568 if (pfound != NULL) 601 else if (pfound->has_arg == 1)
602 {
603 if (GNoptind < argc)
569 { 604 {
570 option_index = indfound; 605 GNoptarg = argv[GNoptind++];
571 GNoptind++;
572 if (*nameend)
573 {
574 /* Don't test has_arg with >, because some C compilers don't
575 * allow it to be used on enums. */
576 if (pfound->has_arg)
577 GNoptarg = nameend + 1;
578 else
579 {
580 if (GNopterr)
581 {
582 if (argv[GNoptind - 1][1] == '-')
583 /* --option */
584 fprintf(stderr,
585 _("%s: option `--%s' does not allow an argument\n"),
586 argv[0],
587 pfound->name);
588 else
589 /* +option or -option */
590 fprintf(stderr,
591 _("%s: option `%c%s' does not allow an argument\n"),
592 argv[0],
593 argv[GNoptind - 1][0],
594 pfound->name);
595 }
596 nextchar += strlen(nextchar);
597 return '?';
598 }
599 }
600 else if (pfound->has_arg == 1)
601 {
602 if (GNoptind < argc)
603 {
604 GNoptarg = argv[GNoptind++];
605 }
606 else
607 {
608 if (GNopterr)
609 {
610 fprintf(stderr,
611 _("%s: option `%s' requires an argument\n"),
612 argv[0],
613 argv[GNoptind - 1]);
614 }
615 nextchar += strlen(nextchar);
616 return (optstring[0] == ':') ? ':' : '?';
617 }
618 }
619 nextchar += strlen(nextchar);
620 if (longind != NULL)
621 *longind = option_index;
622 if (pfound->flag)
623 {
624 *(pfound->flag) = pfound->val;
625 return 0;
626 }
627 return pfound->val;
628 } 606 }
629 607 else
630 /* Can't find it as a long option. If this is not getopt_long_only,
631 * or the option starts with '--' or is not a valid short
632 * option, then it's an error.
633 * Otherwise interpret it as a short option. */
634 if (!long_only || argv[GNoptind][1] == '-' ||
635 my_index(optstring, *nextchar) == NULL)
636 { 608 {
637 if (GNopterr) 609 if (GNopterr)
638 { 610 {
639 if (argv[GNoptind][1] == '-') 611 fprintf (stderr,
640 /* --option */ 612 _ ("%s: option `%s' requires an argument\n"),
641 fprintf(stderr, 613 argv[0],
642 _("%s: unrecognized option `--%s'\n"), 614 argv[GNoptind - 1]);
643 argv[0], 615 }
644 nextchar); 616 nextchar += strlen (nextchar);
645 else 617 return (optstring[0] == ':') ? ':' : '?';
646 /* +option or -option */
647 fprintf(stderr,
648 _("%s: unrecognized option `%c%s'\n"),
649 argv[0],
650 argv[GNoptind][0],
651 nextchar);
652 }
653 nextchar = (char *)"";
654 GNoptind++;
655 return '?';
656 } 618 }
619 }
620 nextchar += strlen (nextchar);
621 if (longind != NULL)
622 *longind = option_index;
623 if (pfound->flag)
624 {
625 *(pfound->flag) = pfound->val;
626 return 0;
627 }
628 return pfound->val;
657 } 629 }
658 630
631 /* Can't find it as a long option. If this is not getopt_long_only,
632 * or the option starts with '--' or is not a valid short
633 * option, then it's an error.
634 * Otherwise interpret it as a short option. */
635 if (! long_only ||(argv[GNoptind][1] == '-') ||
636 (my_index (optstring, *nextchar) == NULL) )
637 {
638 if (GNopterr)
639 {
640 if (argv[GNoptind][1] == '-')
641 /* --option */
642 fprintf (stderr,
643 _ ("%s: unrecognized option `--%s'\n"),
644 argv[0],
645 nextchar);
646 else
647 /* +option or -option */
648 fprintf (stderr,
649 _ ("%s: unrecognized option `%c%s'\n"),
650 argv[0],
651 argv[GNoptind][0],
652 nextchar);
653 }
654 nextchar = (char *) "";
655 GNoptind++;
656 return '?';
657 }
658 }
659
659 /* Look at and handle the next short option-character. */ 660 /* Look at and handle the next short option-character. */
660 661
661 { 662 {
662 char c = *nextchar++; 663 char c = *nextchar++;
663 char *temp = my_index(optstring, c); 664 char *temp = my_index (optstring, c);
664 665
665 /* Increment `GNoptind' when we start to process its last character. */ 666 /* Increment `GNoptind' when we start to process its last character. */
666 if (*nextchar == '\0') 667 if (*nextchar == '\0')
667 ++GNoptind; 668 ++GNoptind;
668 669
669 if (temp == NULL || c == ':') 670 if ((temp == NULL)||(c == ':'))
671 {
672 if (GNopterr)
673 {
674 if (posixly_correct)
675 /* 1003.2 specifies the format of this message. */
676 fprintf (stderr, _ ("%s: illegal option -- %c\n"), argv[0], c);
677 else
678 fprintf (stderr, _ ("%s: invalid option -- %c\n"), argv[0], c);
679 }
680 return '?';
681 }
682 /* Convenience. Treat POSIX -W foo same as long option --foo */
683 if ((temp[0] == 'W')&&(temp[1] == ';'))
684 {
685 char *nameend;
686 const struct GNoption *p;
687 const struct GNoption *pfound = NULL;
688 int exact = 0;
689 int ambig = 0;
690 int indfound = 0;
691 int option_index;
692
693 /* This is an option that requires an argument. */
694 if (*nextchar != '\0')
695 {
696 GNoptarg = nextchar;
697 /* If we end this ARGV-element by taking the rest as an arg,
698 * we must advance to the next element now. */
699 GNoptind++;
700 }
701 else if (GNoptind == argc)
670 { 702 {
671 if (GNopterr) 703 if (GNopterr)
704 {
705 /* 1003.2 specifies the format of this message. */
706 fprintf (stderr,
707 _ ("%s: option requires an argument -- %c\n"),
708 argv[0],
709 c);
710 }
711 if (optstring[0] == ':')
712 c = ':';
713 else
714 c = '?';
715 return c;
716 }
717 else
718 /* We already incremented `GNoptind' once;
719 * increment it again when taking next ARGV-elt as argument. */
720 GNoptarg = argv[GNoptind++];
721
722 /* GNoptarg is now the argument, see if it's in the
723 * table of longopts. */
724
725 for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
726 nameend++)
727 /* Do nothing. */;
728
729 /* Test all long options for either exact match
730 * or abbreviated matches. */
731 if (longopts != NULL)
732 for (p = longopts, option_index = 0; p->name; p++, option_index++)
733 if (! strncmp (p->name, nextchar, nameend - nextchar))
672 { 734 {
673 if (posixly_correct) 735 if ((unsigned int) (nameend - nextchar) == strlen (p->name))
674 /* 1003.2 specifies the format of this message. */ 736 {
675 fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c); 737 /* Exact match found. */
738 pfound = p;
739 indfound = option_index;
740 exact = 1;
741 break;
742 }
743 else if (pfound == NULL)
744 {
745 /* First nonexact match found. */
746 pfound = p;
747 indfound = option_index;
748 }
676 else 749 else
677 fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c); 750 /* Second or later nonexact match found. */
751 ambig = 1;
678 } 752 }
753 if (ambig && ! exact)
754 {
755 if (GNopterr)
756 fprintf (stderr,
757 _ ("%s: option `-W %s' is ambiguous\n"),
758 argv[0],
759 argv[GNoptind]);
760 nextchar += strlen (nextchar);
761 GNoptind++;
679 return '?'; 762 return '?';
680 } 763 }
681 /* Convenience. Treat POSIX -W foo same as long option --foo */ 764 if (pfound != NULL)
682 if (temp[0] == 'W' && temp[1] == ';')
683 { 765 {
684 char *nameend; 766 option_index = indfound;
685 const struct GNoption *p; 767 if (*nameend)
686 const struct GNoption *pfound = NULL; 768 {
687 int exact = 0; 769 /* Don't test has_arg with >, because some C compilers don't
688 int ambig = 0; 770 * allow it to be used on enums. */
689 int indfound = 0; 771 if (pfound->has_arg)
690 int option_index; 772 GNoptarg = nameend + 1;
691 773 else
692 /* This is an option that requires an argument. */
693 if (*nextchar != '\0')
694 {
695 GNoptarg = nextchar;
696 /* If we end this ARGV-element by taking the rest as an arg,
697 * we must advance to the next element now. */
698 GNoptind++;
699 }
700 else if (GNoptind == argc)
701 { 774 {
702 if (GNopterr) 775 if (GNopterr)
703 { 776 fprintf (stderr,
704 /* 1003.2 specifies the format of this message. */ 777 _ ("%s: option `-W %s' does not allow an argument\n"),
705 fprintf(stderr, 778 argv[0],
706 _("%s: option requires an argument -- %c\n"), 779 pfound->name);
707 argv[0],
708 c);
709 }
710 if (optstring[0] == ':')
711 c = ':';
712 else
713 c = '?';
714 return c;
715 }
716 else
717 /* We already incremented `GNoptind' once;
718 * increment it again when taking next ARGV-elt as argument. */
719 GNoptarg = argv[GNoptind++];
720 780
721 /* GNoptarg is now the argument, see if it's in the 781 nextchar += strlen (nextchar);
722 * table of longopts. */
723
724 for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
725 nameend++)
726 /* Do nothing. */;
727
728 /* Test all long options for either exact match
729 * or abbreviated matches. */
730 if (longopts != NULL)
731 for (p = longopts, option_index = 0; p->name; p++, option_index++)
732 if (!strncmp(p->name, nextchar, nameend - nextchar))
733 {
734 if ((unsigned int)(nameend - nextchar) == strlen(p->name))
735 {
736 /* Exact match found. */
737 pfound = p;
738 indfound = option_index;
739 exact = 1;
740 break;
741 }
742 else if (pfound == NULL)
743 {
744 /* First nonexact match found. */
745 pfound = p;
746 indfound = option_index;
747 }
748 else
749 /* Second or later nonexact match found. */
750 ambig = 1;
751 }
752 if (ambig && !exact)
753 {
754 if (GNopterr)
755 fprintf(stderr,
756 _("%s: option `-W %s' is ambiguous\n"),
757 argv[0],
758 argv[GNoptind]);
759 nextchar += strlen(nextchar);
760 GNoptind++;
761 return '?'; 782 return '?';
762 } 783 }
763 if (pfound != NULL) 784 }
785 else if (pfound->has_arg == 1)
786 {
787 if (GNoptind < argc)
788 GNoptarg = argv[GNoptind++];
789 else
764 { 790 {
765 option_index = indfound; 791 if (GNopterr)
766 if (*nameend) 792 fprintf (stderr,
767 { 793 _ ("%s: option `%s' requires an argument\n"),
768 /* Don't test has_arg with >, because some C compilers don't 794 argv[0],
769 * allow it to be used on enums. */ 795 argv[GNoptind - 1]);
770 if (pfound->has_arg) 796 nextchar += strlen (nextchar);
771 GNoptarg = nameend + 1; 797 return optstring[0] == ':' ? ':' : '?';
772 else
773 {
774 if (GNopterr)
775 fprintf(stderr,
776 _("%s: option `-W %s' does not allow an argument\n"),
777 argv[0],
778 pfound->name);
779
780 nextchar += strlen(nextchar);
781 return '?';
782 }
783 }
784 else if (pfound->has_arg == 1)
785 {
786 if (GNoptind < argc)
787 GNoptarg = argv[GNoptind++];
788 else
789 {
790 if (GNopterr)
791 fprintf(stderr,
792 _("%s: option `%s' requires an argument\n"),
793 argv[0],
794 argv[GNoptind - 1]);
795 nextchar += strlen(nextchar);
796 return optstring[0] == ':' ? ':' : '?';
797 }
798 }
799 nextchar += strlen(nextchar);
800 if (longind != NULL)
801 *longind = option_index;
802 if (pfound->flag)
803 {
804 *(pfound->flag) = pfound->val;
805 return 0;
806 }
807 return pfound->val;
808 } 798 }
809 nextchar = NULL; 799 }
810 return 'W'; /* Let the application handle it. */ 800 nextchar += strlen (nextchar);
801 if (longind != NULL)
802 *longind = option_index;
803 if (pfound->flag)
804 {
805 *(pfound->flag) = pfound->val;
806 return 0;
807 }
808 return pfound->val;
811 } 809 }
810 nextchar = NULL;
811 return 'W'; /* Let the application handle it. */
812 }
812 if (temp[1] == ':') 813 if (temp[1] == ':')
814 {
815 if (temp[2] == ':')
813 { 816 {
814 if (temp[2] == ':') 817 /* This is an option that accepts an argument optionally. */
815 { 818 if (*nextchar != '\0')
816 /* This is an option that accepts an argument optionally. */ 819 {
817 if (*nextchar != '\0') 820 GNoptarg = nextchar;
818 { 821 GNoptind++;
819 GNoptarg = nextchar; 822 }
820 GNoptind++;
821 }
822 else
823 GNoptarg = NULL;
824 nextchar = NULL;
825 }
826 else 823 else
824 GNoptarg = NULL;
825 nextchar = NULL;
826 }
827 else
828 {
829 /* This is an option that requires an argument. */
830 if (*nextchar != '\0')
831 {
832 GNoptarg = nextchar;
833 /* If we end this ARGV-element by taking the rest as an arg,
834 * we must advance to the next element now. */
835 GNoptind++;
836 }
837 else if (GNoptind == argc)
838 {
839 if (GNopterr)
827 { 840 {
828 /* This is an option that requires an argument. */ 841 /* 1003.2 specifies the format of this message. */
829 if (*nextchar != '\0') 842 fprintf (stderr,
830 { 843 _ ("%s: option requires an argument -- %c\n"),
831 GNoptarg = nextchar; 844 argv[0],
832 /* If we end this ARGV-element by taking the rest as an arg, 845 c);
833 * we must advance to the next element now. */
834 GNoptind++;
835 }
836 else if (GNoptind == argc)
837 {
838 if (GNopterr)
839 {
840 /* 1003.2 specifies the format of this message. */
841 fprintf(stderr,
842 _("%s: option requires an argument -- %c\n"),
843 argv[0],
844 c);
845 }
846 if (optstring[0] == ':')
847 c = ':';
848 else
849 c = '?';
850 }
851 else
852 /* We already incremented `GNoptind' once;
853 * increment it again when taking next ARGV-elt as argument. */
854 GNoptarg = argv[GNoptind++];
855 nextchar = NULL;
856 } 846 }
847 if (optstring[0] == ':')
848 c = ':';
849 else
850 c = '?';
851 }
852 else
853 /* We already incremented `GNoptind' once;
854 * increment it again when taking next ARGV-elt as argument. */
855 GNoptarg = argv[GNoptind++];
856 nextchar = NULL;
857 } 857 }
858 }
858 return c; 859 return c;
859 } 860 }
860} 861}
861 862
862 863
863static int 864static int
864GNgetopt_long(int argc, 865GNgetopt_long (int argc,
865 char *const *argv, 866 char *const *argv,
866 const char *options, 867 const char *options,
867 const struct GNoption *long_options, 868 const struct GNoption *long_options,
868 int *opt_index) 869 int *opt_index)
869{ 870{
870 return GN_getopt_internal(argc, argv, options, long_options, opt_index, 0); 871 return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
871} 872}
872 873
873/* ******************** now the GNUnet specific modifications... ********************* */ 874/* ******************** now the GNUnet specific modifications... ********************* */
@@ -883,10 +884,10 @@ GNgetopt_long(int argc,
883 * argument, or #GNUNET_SYSERR on error 884 * argument, or #GNUNET_SYSERR on error
884 */ 885 */
885int 886int
886GNUNET_GETOPT_run(const char *binaryOptions, 887GNUNET_GETOPT_run (const char *binaryOptions,
887 const struct GNUNET_GETOPT_CommandLineOption *allOptions, 888 const struct GNUNET_GETOPT_CommandLineOption *allOptions,
888 unsigned int argc, 889 unsigned int argc,
889 char *const *argv) 890 char *const *argv)
890{ 891{
891 struct GNoption *long_options; 892 struct GNoption *long_options;
892 struct GNUNET_GETOPT_CommandLineProcessorContext clpc; 893 struct GNUNET_GETOPT_CommandLineProcessorContext clpc;
@@ -898,7 +899,7 @@ GNUNET_GETOPT_run(const char *binaryOptions,
898 unsigned int optmatch = 0; 899 unsigned int optmatch = 0;
899 const char *have_exclusive = NULL; 900 const char *have_exclusive = NULL;
900 901
901 GNUNET_assert(argc > 0); 902 GNUNET_assert (argc > 0);
902 GNoptind = 0; 903 GNoptind = 0;
903 clpc.binaryName = argv[0]; 904 clpc.binaryName = argv[0];
904 clpc.binaryOptions = binaryOptions; 905 clpc.binaryOptions = binaryOptions;
@@ -910,20 +911,20 @@ GNUNET_GETOPT_run(const char *binaryOptions,
910 911
911 /* transform our option representation into the format 912 /* transform our option representation into the format
912 used by the GNU getopt copylib */ 913 used by the GNU getopt copylib */
913 long_options = GNUNET_new_array(count + 1, struct GNoption); 914 long_options = GNUNET_new_array (count + 1, struct GNoption);
914 seen = GNUNET_new_array(count, uint8_t); 915 seen = GNUNET_new_array (count, uint8_t);
915 shorts = GNUNET_malloc(count * 2 + 1); 916 shorts = GNUNET_malloc (count * 2 + 1);
916 spos = 0; 917 spos = 0;
917 for (unsigned i = 0; i < count; i++) 918 for (unsigned i = 0; i < count; i++)
918 { 919 {
919 long_options[i].name = allOptions[i].name; 920 long_options[i].name = allOptions[i].name;
920 long_options[i].has_arg = allOptions[i].require_argument; 921 long_options[i].has_arg = allOptions[i].require_argument;
921 long_options[i].flag = NULL; 922 long_options[i].flag = NULL;
922 long_options[i].val = allOptions[i].shortName; 923 long_options[i].val = allOptions[i].shortName;
923 shorts[spos++] = allOptions[i].shortName; 924 shorts[spos++] = allOptions[i].shortName;
924 if (allOptions[i].require_argument != 0) 925 if (allOptions[i].require_argument != 0)
925 shorts[spos++] = ':'; 926 shorts[spos++] = ':';
926 } 927 }
927 long_options[count].name = NULL; 928 long_options[count].name = NULL;
928 long_options[count].has_arg = 0; 929 long_options[count].has_arg = 0;
929 long_options[count].flag = NULL; 930 long_options[count].flag = NULL;
@@ -933,74 +934,74 @@ GNUNET_GETOPT_run(const char *binaryOptions,
933 934
934 /* main getopt loop */ 935 /* main getopt loop */
935 while (1) 936 while (1)
936 { 937 {
937 int option_index = 0; 938 int option_index = 0;
938 unsigned int i; 939 unsigned int i;
939 int c; 940 int c;
940 941
941 c = GNgetopt_long(argc, argv, shorts, long_options, &option_index); 942 c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
942 if (c == GNUNET_SYSERR) 943 if (c == GNUNET_SYSERR)
943 break; /* No more flags to process */ 944 break; /* No more flags to process */
944 945
945 /* Check which of our program's options was given by the user */ 946 /* Check which of our program's options was given by the user */
946 for (i = 0; i < count; i++) 947 for (i = 0; i < count; i++)
947 { 948 {
948 clpc.currentArgument = GNoptind - 1; 949 clpc.currentArgument = GNoptind - 1;
949 if ((char)c == allOptions[i].shortName) 950 if ((char) c == allOptions[i].shortName)
950 { 951 {
951 optmatch++; 952 optmatch++;
952 if (allOptions[i].option_exclusive) 953 if (allOptions[i].option_exclusive)
953 have_exclusive = allOptions[i].name; 954 have_exclusive = allOptions[i].name;
954 if (GNUNET_OK == cont) 955 if (GNUNET_OK == cont)
955 {
956 /* parse the option using the option-specific processor */
957 cont = allOptions[i].processor(&clpc,
958 allOptions[i].scls,
959 allOptions[i].name,
960 GNoptarg);
961 }
962 seen[i] = 1;
963 break;
964 }
965 }
966 if (i == count)
967 { 956 {
968 fprintf(stderr, _("Use %s to get a list of options.\n"), "--help"); 957 /* parse the option using the option-specific processor */
969 cont = GNUNET_SYSERR; 958 cont = allOptions[i].processor (&clpc,
959 allOptions[i].scls,
960 allOptions[i].name,
961 GNoptarg);
970 } 962 }
963 seen[i] = 1;
964 break;
965 }
966 }
967 if (i == count)
968 {
969 fprintf (stderr, _ ("Use %s to get a list of options.\n"), "--help");
970 cont = GNUNET_SYSERR;
971 } 971 }
972 GNUNET_free(shorts); 972 }
973 GNUNET_free(long_options); 973 GNUNET_free (shorts);
974 GNUNET_free (long_options);
974 975
975 /* check that if any option that was marked as exclusive 976 /* check that if any option that was marked as exclusive
976 is the only option that was provided */ 977 is the only option that was provided */
977 if ((NULL != have_exclusive) && (optmatch > 1)) 978 if ((NULL != have_exclusive) && (optmatch > 1))
978 { 979 {
979 fprintf(stderr, 980 fprintf (stderr,
980 _("Option `%s' can't be used with other options.\n"), 981 _ ("Option `%s' can't be used with other options.\n"),
981 have_exclusive); 982 have_exclusive);
982 cont = GNUNET_SYSERR; 983 cont = GNUNET_SYSERR;
983 } 984 }
984 if (GNUNET_YES == cont) 985 if (GNUNET_YES == cont)
986 {
987 /* check that all mandatory options are present */
988 for (count = 0; NULL != allOptions[count].name; count++)
985 { 989 {
986 /* check that all mandatory options are present */ 990 if ((0 == seen[count]) && (allOptions[count].option_mandatory))
987 for (count = 0; NULL != allOptions[count].name; count++) 991 {
988 { 992 fprintf (stderr,
989 if ((0 == seen[count]) && (allOptions[count].option_mandatory)) 993 _ ("Missing mandatory option `%s'.\n"),
990 { 994 allOptions[count].name);
991 fprintf(stderr, 995 cont = GNUNET_SYSERR;
992 _("Missing mandatory option `%s'.\n"), 996 }
993 allOptions[count].name);
994 cont = GNUNET_SYSERR;
995 }
996 }
997 } 997 }
998 GNUNET_free(seen); 998 }
999 GNUNET_free (seen);
999 1000
1000 /* call cleaners, if available */ 1001 /* call cleaners, if available */
1001 for (unsigned int i = 0; NULL != allOptions[i].name; i++) 1002 for (unsigned int i = 0; NULL != allOptions[i].name; i++)
1002 if (NULL != allOptions[i].cleaner) 1003 if (NULL != allOptions[i].cleaner)
1003 allOptions[i].cleaner(allOptions[i].scls); 1004 allOptions[i].cleaner (allOptions[i].scls);
1004 1005
1005 if (GNUNET_OK != cont) 1006 if (GNUNET_OK != cont)
1006 return cont; 1007 return cont;