Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97
Free Software Foundation, Inc.
-NOTE: The canonical source of this file is maintained with the GNU C Library.
-Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+ NOTE: The canonical source of this file is maintained with the GNU C Library.
+ Bugs can be reported to bug-glibc@prep.ai.mit.edu.
-This program is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 3, or (at your option) any
-later version.
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 3, or (at your option) any
+ later version.
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
-This code was heavily modified for GNUnet.
-Copyright (C) 2006, 2017 Christian Grothoff
-*/
+ This code was heavily modified for GNUnet.
+ Copyright (C) 2006, 2017 Christian Grothoff
+ */
/**
* @file util/getopt.c
#endif
#endif
-#define LOG(kind, ...) GNUNET_log_from (kind, "util-getopt", __VA_ARGS__)
+#define LOG(kind, ...) GNUNET_log_from(kind, "util-getopt", __VA_ARGS__)
#define LOG_STRERROR(kind, syscall) \
- GNUNET_log_from_strerror (kind, "util-getopt", syscall)
+ GNUNET_log_from_strerror(kind, "util-getopt", syscall)
-#if defined(WIN32) && ! defined(__CYGWIN32__)
+#if defined(WIN32) && !defined(__CYGWIN32__)
/* It's not Unix, really. See? Capital letters. */
#include <windows.h>
-#define getpid() GetCurrentProcessId ()
+#define getpid() GetCurrentProcessId()
#endif
#ifndef _
When compiling libc, the _ macro is predefined. */
#ifdef HAVE_LIBINTL_H
#include <libintl.h>
-#define _(msgid) gettext (msgid)
+#define _(msgid) gettext(msgid)
#else
#define _(msgid) (msgid)
#endif
zero.
The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
+ no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
-struct GNoption
-{
+struct GNoption {
const char *name;
/* has_arg can't be an enum because some compilers complain about
* type mismatches in all the code that assumes it is an int. */
whose names are inconsistent. */
char *
-getenv ();
+getenv();
static char *
-my_index (const char *str, int chr)
+my_index(const char *str, int chr)
{
while (*str)
- {
- if (*str == chr)
- return (char *) str;
- str++;
- }
+ {
+ if (*str == chr)
+ return (char *)str;
+ str++;
+ }
return 0;
}
#ifdef __GNUC__
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
That was relevant to code that was here before. */
-#if ! defined(__STDC__) || ! __STDC__
+#if !defined(__STDC__) || !__STDC__
/* gcc with -traditional declares the built-in strlen to return int,
and has done so at least since version 2.4.5. -- rms. */
extern int
-strlen (const char *);
+strlen(const char *);
#endif /* not __STDC__ */
#endif /* __GNUC__ */
#if defined(__STDC__) && __STDC__
static void
-exchange (char **);
+exchange(char **);
#endif
static void
-exchange (char **argv)
+exchange(char **argv)
{
int bottom = first_nonopt;
int middle = last_nonopt;
* but it consists of two parts that need to be swapped next. */
while (top > middle && middle > bottom)
- {
- if (top - middle > middle - bottom)
{
- /* Bottom segment is the short one. */
- int len = middle - bottom;
- register int i;
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
- /* Swap it with the top part of the top segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[top - (middle - bottom) + i];
- argv[top - (middle - bottom) + i] = tem;
- SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
- }
- /* Exclude the moved bottom segment from further swapping. */
- top -= len;
- }
- else
- {
- /* Top segment is the short one. */
- int len = top - middle;
- register int i;
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS(bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
- /* Swap it with the bottom part of the bottom segment. */
- for (i = 0; i < len; i++)
- {
- tem = argv[bottom + i];
- argv[bottom + i] = argv[middle + i];
- argv[middle + i] = tem;
- SWAP_FLAGS (bottom + i, middle + i);
- }
- /* Exclude the moved top segment from further swapping. */
- bottom += len;
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS(bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
}
- }
/* Update records for the slots the non-options now occupy. */
#if defined(__STDC__) && __STDC__
static const char *
-_getopt_initialize (int, char *const *, const char *);
+_getopt_initialize(int, char *const *, const char *);
#endif
static const char *
-_getopt_initialize (int argc, char *const *argv, const char *optstring)
+_getopt_initialize(int argc, char *const *argv, const char *optstring)
{
/* Start processing options with ARGV-element 1 (since ARGV-element 0
* is the program name); the sequence of previously skipped
nextchar = NULL;
- posixly_correct = getenv ("POSIXLY_CORRECT");
+ posixly_correct = getenv("POSIXLY_CORRECT");
/* Determine how to handle the ordering of options and nonoptions. */
if (optstring[0] == '-')
- {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- }
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
else if (optstring[0] == '+')
- {
- ordering = REQUIRE_ORDER;
- ++optstring;
- }
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
else if (posixly_correct != NULL)
ordering = REQUIRE_ORDER;
else
long-named options. */
static int
-GN_getopt_internal (int argc,
- char *const *argv,
- const char *optstring,
- const struct GNoption *longopts,
- int *longind,
- int long_only)
+GN_getopt_internal(int argc,
+ char *const *argv,
+ const char *optstring,
+ const struct GNoption *longopts,
+ int *longind,
+ int long_only)
{
static int __getopt_initialized = 0;
static int GNopterr = 1;
GNoptarg = NULL;
- if (GNoptind == 0 || ! __getopt_initialized)
- {
- if (GNoptind == 0)
- GNoptind = 1; /* Don't scan ARGV[0], the program name. */
- optstring = _getopt_initialize (argc, argv, optstring);
- __getopt_initialized = 1;
- }
+ if (GNoptind == 0 || !__getopt_initialized)
+ {
+ if (GNoptind == 0)
+ GNoptind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize(argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
/* Test whether ARGV[GNoptind] points to a non-option argument.
* Either it does not have option syntax, or there is an environment flag
#define NONOPTION_P (argv[GNoptind][0] != '-' || argv[GNoptind][1] == '\0')
if (nextchar == NULL || *nextchar == '\0')
- {
- /* Advance to the next ARGV-element. */
-
- /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been
- * moved back by the user (who may also have changed the arguments). */
- if (last_nonopt > GNoptind)
- last_nonopt = GNoptind;
- if (first_nonopt > GNoptind)
- first_nonopt = GNoptind;
-
- if (ordering == PERMUTE)
{
- /* If we have just processed some options following some non-options,
- * exchange them so that the options come first. */
+ /* Advance to the next ARGV-element. */
- if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
- exchange ((char **) argv);
- else if (last_nonopt != GNoptind)
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if GNoptind has been
+ * moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > GNoptind)
+ last_nonopt = GNoptind;
+ if (first_nonopt > GNoptind)
first_nonopt = GNoptind;
- /* Skip any additional non-options
- * and extend the range of non-options previously skipped. */
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ * exchange them so that the options come first. */
- while (GNoptind < argc && NONOPTION_P)
- GNoptind++;
- last_nonopt = GNoptind;
- }
+ if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
+ exchange((char **)argv);
+ else if (last_nonopt != GNoptind)
+ first_nonopt = GNoptind;
- /* The special ARGV-element `--' means premature end of options.
- * Skip it like a null option,
- * then exchange with previous non-options as if it were an option,
- * then skip everything else like a non-option. */
- if (GNoptind != argc && ! strcmp (argv[GNoptind], "--"))
- {
- GNoptind++;
+ /* Skip any additional non-options
+ * and extend the range of non-options previously skipped. */
- if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
- exchange ((char **) argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = GNoptind;
- last_nonopt = argc;
+ while (GNoptind < argc && NONOPTION_P)
+ GNoptind++;
+ last_nonopt = GNoptind;
+ }
- GNoptind = argc;
- }
+ /* The special ARGV-element `--' means premature end of options.
+ * Skip it like a null option,
+ * then exchange with previous non-options as if it were an option,
+ * then skip everything else like a non-option. */
+ if (GNoptind != argc && !strcmp(argv[GNoptind], "--"))
+ {
+ GNoptind++;
- /* If we have done all the ARGV-elements, stop the scan
- * and back over any non-options that we skipped and permuted. */
+ if (first_nonopt != last_nonopt && last_nonopt != GNoptind)
+ exchange((char **)argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = GNoptind;
+ last_nonopt = argc;
- if (GNoptind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- * that we previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- GNoptind = first_nonopt;
- return -1;
- }
+ GNoptind = argc;
+ }
- /* If we have come to a non-option and did not permute it,
- * either stop the scan or describe it to the caller and pass it by. */
+ /* If we have done all the ARGV-elements, stop the scan
+ * and back over any non-options that we skipped and permuted. */
- if (NONOPTION_P)
- {
- if (ordering == REQUIRE_ORDER)
- return -1;
- GNoptarg = argv[GNoptind++];
- return 1;
- }
+ if (GNoptind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ * that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ GNoptind = first_nonopt;
+ return -1;
+ }
- /* We have found another option-ARGV-element.
- * Skip the initial punctuation. */
+ /* If we have come to a non-option and did not permute it,
+ * either stop the scan or describe it to the caller and pass it by. */
- nextchar =
- (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-'));
- }
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ GNoptarg = argv[GNoptind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ * Skip the initial punctuation. */
+
+ nextchar =
+ (argv[GNoptind] + 1 + (longopts != NULL && argv[GNoptind][1] == '-'));
+ }
/* Decode the current option-ARGV-element. */
if (longopts != NULL &&
(argv[GNoptind][1] == '-' ||
(long_only &&
- (argv[GNoptind][2] || ! my_index (optstring, argv[GNoptind][1])))))
- {
- char *nameend;
- const struct GNoption *p;
- const struct GNoption *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = -1;
- int option_index;
-
- for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
- /* Do nothing. */;
-
- /* Test all long options for either exact match
- * or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (! strncmp (p->name, nextchar, nameend - nextchar))
- {
- if ((unsigned int) (nameend - nextchar) ==
- (unsigned int) strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second or later nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && ! exact)
+ (argv[GNoptind][2] || !my_index(optstring, argv[GNoptind][1])))))
{
- if (GNopterr)
- fprintf (stderr,
- _ ("%s: option `%s' is ambiguous\n"),
- argv[0],
- argv[GNoptind]);
- nextchar += strlen (nextchar);
- GNoptind++;
- return '?';
- }
+ char *nameend;
+ const struct GNoption *p;
+ const struct GNoption *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
- if (pfound != NULL)
- {
- option_index = indfound;
- GNoptind++;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- * allow it to be used on enums. */
- if (pfound->has_arg)
- GNoptarg = nameend + 1;
- else
- {
- if (GNopterr)
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */;
+
+ /* Test all long options for either exact match
+ * or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp(p->name, nextchar, nameend - nextchar))
{
- if (argv[GNoptind - 1][1] == '-')
- /* --option */
- fprintf (stderr,
- _ ("%s: option `--%s' does not allow an argument\n"),
- argv[0],
- pfound->name);
+ if ((unsigned int)(nameend - nextchar) ==
+ (unsigned int)strlen(p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
else
- /* +option or -option */
- fprintf (stderr,
- _ ("%s: option `%c%s' does not allow an argument\n"),
- argv[0],
- argv[GNoptind - 1][0],
- pfound->name);
+ /* Second or later nonexact match found. */
+ ambig = 1;
}
- nextchar += strlen (nextchar);
+
+ if (ambig && !exact)
+ {
+ if (GNopterr)
+ fprintf(stderr,
+ _("%s: option `%s' is ambiguous\n"),
+ argv[0],
+ argv[GNoptind]);
+ nextchar += strlen(nextchar);
+ GNoptind++;
return '?';
}
- }
- else if (pfound->has_arg == 1)
- {
- if (GNoptind < argc)
+
+ if (pfound != NULL)
{
- GNoptarg = argv[GNoptind++];
+ option_index = indfound;
+ GNoptind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ * allow it to be used on enums. */
+ if (pfound->has_arg)
+ GNoptarg = nameend + 1;
+ else
+ {
+ if (GNopterr)
+ {
+ if (argv[GNoptind - 1][1] == '-')
+ /* --option */
+ fprintf(stderr,
+ _("%s: option `--%s' does not allow an argument\n"),
+ argv[0],
+ pfound->name);
+ else
+ /* +option or -option */
+ fprintf(stderr,
+ _("%s: option `%c%s' does not allow an argument\n"),
+ argv[0],
+ argv[GNoptind - 1][0],
+ pfound->name);
+ }
+ nextchar += strlen(nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (GNoptind < argc)
+ {
+ GNoptarg = argv[GNoptind++];
+ }
+ else
+ {
+ if (GNopterr)
+ {
+ fprintf(stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0],
+ argv[GNoptind - 1]);
+ }
+ nextchar += strlen(nextchar);
+ return (optstring[0] == ':') ? ':' : '?';
+ }
+ }
+ nextchar += strlen(nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
}
- else
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ * or the option starts with '--' or is not a valid short
+ * option, then it's an error.
+ * Otherwise interpret it as a short option. */
+ if (!long_only || argv[GNoptind][1] == '-' ||
+ my_index(optstring, *nextchar) == NULL)
{
if (GNopterr)
- {
- fprintf (stderr,
- _ ("%s: option `%s' requires an argument\n"),
- argv[0],
- argv[GNoptind - 1]);
- }
- nextchar += strlen (nextchar);
- return (optstring[0] == ':') ? ':' : '?';
+ {
+ if (argv[GNoptind][1] == '-')
+ /* --option */
+ fprintf(stderr,
+ _("%s: unrecognized option `--%s'\n"),
+ argv[0],
+ nextchar);
+ else
+ /* +option or -option */
+ fprintf(stderr,
+ _("%s: unrecognized option `%c%s'\n"),
+ argv[0],
+ argv[GNoptind][0],
+ nextchar);
+ }
+ nextchar = (char *)"";
+ GNoptind++;
+ return '?';
}
- }
- nextchar += strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
}
- /* Can't find it as a long option. If this is not getopt_long_only,
- * or the option starts with '--' or is not a valid short
- * option, then it's an error.
- * Otherwise interpret it as a short option. */
- if (! long_only || argv[GNoptind][1] == '-' ||
- my_index (optstring, *nextchar) == NULL)
- {
- if (GNopterr)
- {
- if (argv[GNoptind][1] == '-')
- /* --option */
- fprintf (stderr,
- _ ("%s: unrecognized option `--%s'\n"),
- argv[0],
- nextchar);
- else
- /* +option or -option */
- fprintf (stderr,
- _ ("%s: unrecognized option `%c%s'\n"),
- argv[0],
- argv[GNoptind][0],
- nextchar);
- }
- nextchar = (char *) "";
- GNoptind++;
- return '?';
- }
- }
-
/* Look at and handle the next short option-character. */
{
char c = *nextchar++;
- char *temp = my_index (optstring, c);
+ char *temp = my_index(optstring, c);
/* Increment `GNoptind' when we start to process its last character. */
if (*nextchar == '\0')
++GNoptind;
if (temp == NULL || c == ':')
- {
- if (GNopterr)
- {
- if (posixly_correct)
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, _ ("%s: illegal option -- %c\n"), argv[0], c);
- else
- fprintf (stderr, _ ("%s: invalid option -- %c\n"), argv[0], c);
- }
- return '?';
- }
- /* Convenience. Treat POSIX -W foo same as long option --foo */
- if (temp[0] == 'W' && temp[1] == ';')
- {
- char *nameend;
- const struct GNoption *p;
- const struct GNoption *pfound = NULL;
- int exact = 0;
- int ambig = 0;
- int indfound = 0;
- int option_index;
-
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- GNoptarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- * we must advance to the next element now. */
- GNoptind++;
- }
- else if (GNoptind == argc)
{
if (GNopterr)
- {
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr,
- _ ("%s: option requires an argument -- %c\n"),
- argv[0],
- c);
- }
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- return c;
- }
- else
- /* We already incremented `GNoptind' once;
- * increment it again when taking next ARGV-elt as argument. */
- GNoptarg = argv[GNoptind++];
-
- /* GNoptarg is now the argument, see if it's in the
- * table of longopts. */
-
- for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
- nameend++)
- /* Do nothing. */;
-
- /* Test all long options for either exact match
- * or abbreviated matches. */
- if (longopts != NULL)
- for (p = longopts, option_index = 0; p->name; p++, option_index++)
- if (! strncmp (p->name, nextchar, nameend - nextchar))
{
- if ((unsigned int) (nameend - nextchar) == strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf(stderr, _("%s: illegal option -- %c\n"), argv[0], c);
else
- /* Second or later nonexact match found. */
- ambig = 1;
+ fprintf(stderr, _("%s: invalid option -- %c\n"), argv[0], c);
}
- if (ambig && ! exact)
- {
- if (GNopterr)
- fprintf (stderr,
- _ ("%s: option `-W %s' is ambiguous\n"),
- argv[0],
- argv[GNoptind]);
- nextchar += strlen (nextchar);
- GNoptind++;
return '?';
}
- if (pfound != NULL)
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
{
- option_index = indfound;
- if (*nameend)
- {
- /* Don't test has_arg with >, because some C compilers don't
- * allow it to be used on enums. */
- if (pfound->has_arg)
- GNoptarg = nameend + 1;
- else
+ char *nameend;
+ const struct GNoption *p;
+ const struct GNoption *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ GNoptarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ * we must advance to the next element now. */
+ GNoptind++;
+ }
+ else if (GNoptind == argc)
{
if (GNopterr)
- fprintf (stderr,
- _ ("%s: option `-W %s' does not allow an argument\n"),
- argv[0],
- pfound->name);
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf(stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0],
+ c);
+ }
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `GNoptind' once;
+ * increment it again when taking next ARGV-elt as argument. */
+ GNoptarg = argv[GNoptind++];
- nextchar += strlen (nextchar);
+ /* GNoptarg is now the argument, see if it's in the
+ * table of longopts. */
+
+ for (nextchar = nameend = GNoptarg; *nameend && *nameend != '=';
+ nameend++)
+ /* Do nothing. */;
+
+ /* Test all long options for either exact match
+ * or abbreviated matches. */
+ if (longopts != NULL)
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp(p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int)(nameend - nextchar) == strlen(p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (GNopterr)
+ fprintf(stderr,
+ _("%s: option `-W %s' is ambiguous\n"),
+ argv[0],
+ argv[GNoptind]);
+ nextchar += strlen(nextchar);
+ GNoptind++;
return '?';
}
- }
- else if (pfound->has_arg == 1)
- {
- if (GNoptind < argc)
- GNoptarg = argv[GNoptind++];
- else
+ if (pfound != NULL)
{
- if (GNopterr)
- fprintf (stderr,
- _ ("%s: option `%s' requires an argument\n"),
- argv[0],
- argv[GNoptind - 1]);
- nextchar += strlen (nextchar);
- return optstring[0] == ':' ? ':' : '?';
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ * allow it to be used on enums. */
+ if (pfound->has_arg)
+ GNoptarg = nameend + 1;
+ else
+ {
+ if (GNopterr)
+ fprintf(stderr,
+ _("%s: option `-W %s' does not allow an argument\n"),
+ argv[0],
+ pfound->name);
+
+ nextchar += strlen(nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (GNoptind < argc)
+ GNoptarg = argv[GNoptind++];
+ else
+ {
+ if (GNopterr)
+ fprintf(stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0],
+ argv[GNoptind - 1]);
+ nextchar += strlen(nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen(nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
}
- }
- nextchar += strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
- nextchar = NULL;
- return 'W'; /* Let the application handle it. */
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != '\0')
- {
- GNoptarg = nextchar;
- GNoptind++;
- }
- else
- GNoptarg = NULL;
nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
}
- else
+ if (temp[1] == ':')
{
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- GNoptarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- * we must advance to the next element now. */
- GNoptind++;
- }
- else if (GNoptind == argc)
- {
- if (GNopterr)
+ if (temp[2] == ':')
{
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr,
- _ ("%s: option requires an argument -- %c\n"),
- argv[0],
- c);
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ GNoptarg = nextchar;
+ GNoptind++;
+ }
+ else
+ GNoptarg = NULL;
+ nextchar = NULL;
}
- if (optstring[0] == ':')
- c = ':';
- else
- c = '?';
- }
else
- /* We already incremented `GNoptind' once;
- * increment it again when taking next ARGV-elt as argument. */
- GNoptarg = argv[GNoptind++];
- nextchar = NULL;
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ GNoptarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ * we must advance to the next element now. */
+ GNoptind++;
+ }
+ else if (GNoptind == argc)
+ {
+ if (GNopterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf(stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0],
+ c);
+ }
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `GNoptind' once;
+ * increment it again when taking next ARGV-elt as argument. */
+ GNoptarg = argv[GNoptind++];
+ nextchar = NULL;
+ }
}
- }
return c;
}
}
static int
-GNgetopt_long (int argc,
- char *const *argv,
- const char *options,
- const struct GNoption *long_options,
- int *opt_index)
+GNgetopt_long(int argc,
+ char *const *argv,
+ const char *options,
+ const struct GNoption *long_options,
+ int *opt_index)
{
- return GN_getopt_internal (argc, argv, options, long_options, opt_index, 0);
+ return GN_getopt_internal(argc, argv, options, long_options, opt_index, 0);
}
/* ******************** now the GNUnet specific modifications... ********************* */
* argument, or #GNUNET_SYSERR on error
*/
int
-GNUNET_GETOPT_run (const char *binaryOptions,
- const struct GNUNET_GETOPT_CommandLineOption *allOptions,
- unsigned int argc,
- char *const *argv)
+GNUNET_GETOPT_run(const char *binaryOptions,
+ const struct GNUNET_GETOPT_CommandLineOption *allOptions,
+ unsigned int argc,
+ char *const *argv)
{
struct GNoption *long_options;
struct GNUNET_GETOPT_CommandLineProcessorContext clpc;
unsigned int optmatch = 0;
const char *have_exclusive = NULL;
- GNUNET_assert (argc > 0);
+ GNUNET_assert(argc > 0);
GNoptind = 0;
clpc.binaryName = argv[0];
clpc.binaryOptions = binaryOptions;
/* transform our option representation into the format
used by the GNU getopt copylib */
- long_options = GNUNET_new_array (count + 1, struct GNoption);
- seen = GNUNET_new_array (count, uint8_t);
- shorts = GNUNET_malloc (count * 2 + 1);
+ long_options = GNUNET_new_array(count + 1, struct GNoption);
+ seen = GNUNET_new_array(count, uint8_t);
+ shorts = GNUNET_malloc(count * 2 + 1);
spos = 0;
for (unsigned i = 0; i < count; i++)
- {
- long_options[i].name = allOptions[i].name;
- long_options[i].has_arg = allOptions[i].require_argument;
- long_options[i].flag = NULL;
- long_options[i].val = allOptions[i].shortName;
- shorts[spos++] = allOptions[i].shortName;
- if (allOptions[i].require_argument != 0)
- shorts[spos++] = ':';
- }
+ {
+ long_options[i].name = allOptions[i].name;
+ long_options[i].has_arg = allOptions[i].require_argument;
+ long_options[i].flag = NULL;
+ long_options[i].val = allOptions[i].shortName;
+ shorts[spos++] = allOptions[i].shortName;
+ if (allOptions[i].require_argument != 0)
+ shorts[spos++] = ':';
+ }
long_options[count].name = NULL;
long_options[count].has_arg = 0;
long_options[count].flag = NULL;
/* main getopt loop */
while (1)
- {
- int option_index = 0;
- unsigned int i;
- int c;
+ {
+ int option_index = 0;
+ unsigned int i;
+ int c;
- c = GNgetopt_long (argc, argv, shorts, long_options, &option_index);
- if (c == GNUNET_SYSERR)
- break; /* No more flags to process */
+ c = GNgetopt_long(argc, argv, shorts, long_options, &option_index);
+ if (c == GNUNET_SYSERR)
+ break; /* No more flags to process */
- /* Check which of our program's options was given by the user */
- for (i = 0; i < count; i++)
- {
- clpc.currentArgument = GNoptind - 1;
- if ((char) c == allOptions[i].shortName)
- {
- optmatch++;
- if (allOptions[i].option_exclusive)
- have_exclusive = allOptions[i].name;
- if (GNUNET_OK == cont)
+ /* Check which of our program's options was given by the user */
+ for (i = 0; i < count; i++)
{
- /* parse the option using the option-specific processor */
- cont = allOptions[i].processor (&clpc,
- allOptions[i].scls,
- allOptions[i].name,
- GNoptarg);
+ clpc.currentArgument = GNoptind - 1;
+ if ((char)c == allOptions[i].shortName)
+ {
+ optmatch++;
+ if (allOptions[i].option_exclusive)
+ have_exclusive = allOptions[i].name;
+ if (GNUNET_OK == cont)
+ {
+ /* parse the option using the option-specific processor */
+ cont = allOptions[i].processor(&clpc,
+ allOptions[i].scls,
+ allOptions[i].name,
+ GNoptarg);
+ }
+ seen[i] = 1;
+ break;
+ }
+ }
+ if (i == count)
+ {
+ fprintf(stderr, _("Use %s to get a list of options.\n"), "--help");
+ cont = GNUNET_SYSERR;
}
- seen[i] = 1;
- break;
- }
- }
- if (i == count)
- {
- fprintf (stderr, _ ("Use %s to get a list of options.\n"), "--help");
- cont = GNUNET_SYSERR;
}
- }
- GNUNET_free (shorts);
- GNUNET_free (long_options);
+ GNUNET_free(shorts);
+ GNUNET_free(long_options);
/* check that if any option that was marked as exclusive
is the only option that was provided */
if ((NULL != have_exclusive) && (optmatch > 1))
- {
- fprintf (stderr,
- _ ("Option `%s' can't be used with other options.\n"),
- have_exclusive);
- cont = GNUNET_SYSERR;
- }
+ {
+ fprintf(stderr,
+ _("Option `%s' can't be used with other options.\n"),
+ have_exclusive);
+ cont = GNUNET_SYSERR;
+ }
if (GNUNET_YES == cont)
- {
- /* check that all mandatory options are present */
- for (count = 0; NULL != allOptions[count].name; count++)
{
- if ((0 == seen[count]) && (allOptions[count].option_mandatory))
- {
- fprintf (stderr,
- _ ("Missing mandatory option `%s'.\n"),
- allOptions[count].name);
- cont = GNUNET_SYSERR;
- }
+ /* check that all mandatory options are present */
+ for (count = 0; NULL != allOptions[count].name; count++)
+ {
+ if ((0 == seen[count]) && (allOptions[count].option_mandatory))
+ {
+ fprintf(stderr,
+ _("Missing mandatory option `%s'.\n"),
+ allOptions[count].name);
+ cont = GNUNET_SYSERR;
+ }
+ }
}
- }
- GNUNET_free (seen);
+ GNUNET_free(seen);
/* call cleaners, if available */
for (unsigned int i = 0; NULL != allOptions[i].name; i++)
if (NULL != allOptions[i].cleaner)
- allOptions[i].cleaner (allOptions[i].scls);
+ allOptions[i].cleaner(allOptions[i].scls);
if (GNUNET_OK != cont)
return cont;