2008-02-29 Gregory Pietsch <gpietsch@comcast.net>
* libc/stdlib/getopt.c (getopt_internal): Rewrite to accept data area so as to support reentrant calls. Change all callers to fill in data area with global values and restore any changes to the global values after call. (__getopt_r, __getopt_long_r, __getopt_long_only_r): New routines to support reentrancy that add a data area argument. * libc/include/getopt.h: Add new _r routines and provide macros so they can be called with using double-underscores.
This commit is contained in:
parent
86a4b0c733
commit
76ff710cfa
|
@ -1,3 +1,14 @@
|
|||
2008-02-29 Gregory Pietsch <gpietsch@comcast.net>
|
||||
|
||||
* libc/stdlib/getopt.c (getopt_internal): Rewrite to accept
|
||||
data area so as to support reentrant calls. Change all callers
|
||||
to fill in data area with global values and restore any changes
|
||||
to the global values after call.
|
||||
(__getopt_r, __getopt_long_r, __getopt_long_only_r): New routines
|
||||
to support reentrancy that add a data area argument.
|
||||
* libc/include/getopt.h: Add new _r routines and provide macros
|
||||
so they can be called with using double-underscores.
|
||||
|
||||
2008-02-21 Eric Blake <ebb9@byu.net>
|
||||
|
||||
Fix strtod("-0x", NULL).
|
||||
|
|
|
@ -82,6 +82,7 @@ Gregory Pietsch's current e-mail address:
|
|||
gpietsch@comcast.net
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef GETOPT_H
|
||||
#define GETOPT_H
|
||||
|
||||
|
@ -90,30 +91,46 @@ gpietsch@comcast.net
|
|||
/* include files needed by this include file */
|
||||
|
||||
/* macros defined by this include file */
|
||||
#define NO_ARG 0
|
||||
#define REQUIRED_ARG 1
|
||||
#define OPTIONAL_ARG 2
|
||||
|
||||
/* types defined by this include file */
|
||||
|
||||
struct option
|
||||
{
|
||||
char *name; /* the name of the long option */
|
||||
int has_arg; /* one of the above macros */
|
||||
int *flag; /* determines if getopt_long() returns a
|
||||
* value for a long option; if it is
|
||||
* non-NULL, 0 is returned as a function
|
||||
* value and the value of val is stored in
|
||||
* the area pointed to by flag. Otherwise,
|
||||
* val is returned. */
|
||||
int val; /* determines the value to return if flag is
|
||||
* NULL. */
|
||||
};
|
||||
#define NO_ARG 0
|
||||
#define REQUIRED_ARG 1
|
||||
#define OPTIONAL_ARG 2
|
||||
/* The GETOPT_DATA_INITIALIZER macro is used to initialize a statically-
|
||||
allocated variable of type struct getopt_data. */
|
||||
#define GETOPT_DATA_INITIALIZER {0,0,0,0,0}
|
||||
/* These #defines are to keep the namespace clear... */
|
||||
#define getopt_r __getopt_r
|
||||
#define getopt_long_r __getopt_long_r
|
||||
#define getopt_long_only_r __getopt_long_only_r
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* types defined by this include file */
|
||||
struct option
|
||||
{
|
||||
char *name; /* the name of the long option */
|
||||
int has_arg; /* one of the above macros */
|
||||
int *flag; /* determines if getopt_long() returns a
|
||||
* value for a long option; if it is
|
||||
* non-NULL, 0 is returned as a function
|
||||
* value and the value of val is stored in
|
||||
* the area pointed to by flag. Otherwise,
|
||||
* val is returned. */
|
||||
int val; /* determines the value to return if flag is
|
||||
* NULL. */
|
||||
|
||||
};
|
||||
|
||||
/* The getopt_data structure is for reentrancy. Its members are similar to
|
||||
the externally-defined variables. */
|
||||
typedef struct getopt_data
|
||||
{
|
||||
char *optarg;
|
||||
int optind, opterr, optopt, optwhere;
|
||||
} getopt_data;
|
||||
|
||||
/* externally-defined variables */
|
||||
extern char *optarg;
|
||||
|
@ -122,14 +139,35 @@ extern "C"
|
|||
extern int optopt;
|
||||
|
||||
/* function prototypes */
|
||||
int _EXFUN (getopt, (int __argc, char *const __argv[], const char *__optstring));
|
||||
int _EXFUN (getopt_long, (int __argc, char *const __argv[], const char *__shortopts, const struct option *__longopts, int *__longind));
|
||||
int _EXFUN (getopt_long_only, (int __argc, char *const __argv[], const char *__shortopts, const struct option *__longopts, int *__longind));
|
||||
int _EXFUN (getopt,
|
||||
(int __argc, char *const __argv[], const char *__optstring));
|
||||
|
||||
int _EXFUN (getopt_long,
|
||||
(int __argc, char *const __argv[], const char *__shortopts,
|
||||
const struct option * __longopts, int *__longind));
|
||||
|
||||
int _EXFUN (getopt_long_only,
|
||||
(int __argc, char *const __argv[], const char *__shortopts,
|
||||
const struct option * __longopts, int *__longind));
|
||||
|
||||
int _EXFUN (__getopt_r,
|
||||
(int __argc, char *const __argv[], const char *__optstring,
|
||||
struct getopt_data * __data));
|
||||
|
||||
int _EXFUN (__getopt_long_r,
|
||||
(int __argc, char *const __argv[], const char *__shortopts,
|
||||
const struct option * __longopts, int *__longind,
|
||||
struct getopt_data * __data));
|
||||
|
||||
int _EXFUN (__getopt_long_only_r,
|
||||
(int __argc, char *const __argv[], const char *__shortopts,
|
||||
const struct option * __longopts, int *__longind,
|
||||
struct getopt_data * __data));
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* GETOPT_H */
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ Gregory Pietsch's current e-mail address:
|
|||
gpietsch@comcast.net
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/* include files */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -100,16 +101,19 @@ typedef enum GETOPT_ORDERING_T
|
|||
} GETOPT_ORDERING_T;
|
||||
|
||||
/* globally-defined variables */
|
||||
char *optarg = NULL;
|
||||
char *optarg = 0;
|
||||
int optind = 0;
|
||||
int opterr = 1;
|
||||
int optopt = '?';
|
||||
|
||||
/* static variables */
|
||||
static int optwhere = 0;
|
||||
|
||||
/* functions */
|
||||
|
||||
/* reverse_argv_elements: reverses num elements starting at argv */
|
||||
static void
|
||||
reverse_argv_elements (char ** argv, int num)
|
||||
reverse_argv_elements (char **argv, int num)
|
||||
{
|
||||
int i;
|
||||
char *tmp;
|
||||
|
@ -126,276 +130,346 @@ reverse_argv_elements (char ** argv, int num)
|
|||
static void
|
||||
permute (char *const argv[], int len1, int len2)
|
||||
{
|
||||
reverse_argv_elements ((char **)argv, len1);
|
||||
reverse_argv_elements ((char **)argv, len1 + len2);
|
||||
reverse_argv_elements ((char **)argv, len2);
|
||||
reverse_argv_elements ((char **) argv, len1);
|
||||
reverse_argv_elements ((char **) argv, len1 + len2);
|
||||
reverse_argv_elements ((char **) argv, len2);
|
||||
}
|
||||
|
||||
/* is_option: is this argv-element an option or the end of the option list? */
|
||||
static int
|
||||
is_option (char *argv_element, int only)
|
||||
{
|
||||
return ((argv_element == NULL)
|
||||
|| (argv_element[0] == '-') || (only && argv_element[0] == '+'));
|
||||
return ((argv_element == 0)
|
||||
|| (argv_element[0] == '-') || (only && argv_element[0] == '+'));
|
||||
}
|
||||
|
||||
/* read_globals: read the values from the globals into a getopt_data
|
||||
structure */
|
||||
static void
|
||||
read_globals (struct getopt_data *data)
|
||||
{
|
||||
data->optarg = optarg;
|
||||
data->optind = optind;
|
||||
data->opterr = opterr;
|
||||
data->optopt = optopt;
|
||||
data->optwhere = optwhere;
|
||||
}
|
||||
|
||||
/* write_globals: write the values into the globals from a getopt_data
|
||||
structure */
|
||||
static void
|
||||
write_globals (struct getopt_data *data)
|
||||
{
|
||||
optarg = data->optarg;
|
||||
optind = data->optind;
|
||||
opterr = data->opterr;
|
||||
optopt = data->optopt;
|
||||
optwhere = data->optwhere;
|
||||
}
|
||||
|
||||
/* getopt_internal: the function that does all the dirty work */
|
||||
static int
|
||||
getopt_internal (int argc, char *const argv[], const char *shortopts,
|
||||
const struct option *longopts, int *longind, int only)
|
||||
const struct option *longopts, int *longind, int only,
|
||||
struct getopt_data *data)
|
||||
{
|
||||
GETOPT_ORDERING_T ordering = PERMUTE;
|
||||
static size_t optwhere = 0;
|
||||
size_t permute_from = 0;
|
||||
int num_nonopts = 0;
|
||||
int optindex = 0;
|
||||
size_t match_chars = 0;
|
||||
char *possible_arg = NULL;
|
||||
char *possible_arg = 0;
|
||||
int longopt_match = -1;
|
||||
int has_arg = -1;
|
||||
char *cp = NULL;
|
||||
char *cp = 0;
|
||||
int arg_next = 0;
|
||||
|
||||
/* first, deal with silly parameters and easy stuff */
|
||||
if (argc == 0 || argv == NULL || (shortopts == NULL && longopts == NULL))
|
||||
if (argc == 0 || argv == 0 || (shortopts == 0 && longopts == 0)
|
||||
|| data->optind >= argc || argv[data->optind] == 0)
|
||||
return EOF;
|
||||
if (optind >= argc || argv[optind] == NULL)
|
||||
return EOF;
|
||||
if (strcmp (argv[optind], "--") == 0)
|
||||
if (strcmp (argv[data->optind], "--") == 0)
|
||||
{
|
||||
optind++;
|
||||
data->optind++;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* if this is our first time through */
|
||||
if (optind == 0)
|
||||
optind = optwhere = 1;
|
||||
if (data->optind == 0)
|
||||
data->optind = data->optwhere = 1;
|
||||
|
||||
/* define ordering */
|
||||
if (shortopts != NULL && (*shortopts == '-' || *shortopts == '+'))
|
||||
if (shortopts != 0 && (*shortopts == '-' || *shortopts == '+'))
|
||||
{
|
||||
ordering = (*shortopts == '-') ? RETURN_IN_ORDER : REQUIRE_ORDER;
|
||||
shortopts++;
|
||||
}
|
||||
else
|
||||
ordering = (getenv ("POSIXLY_CORRECT") != NULL) ? REQUIRE_ORDER : PERMUTE;
|
||||
ordering = (getenv ("POSIXLY_CORRECT") != 0) ? REQUIRE_ORDER : PERMUTE;
|
||||
|
||||
/*
|
||||
* based on ordering, find our next option, if we're at the beginning of
|
||||
* one
|
||||
*/
|
||||
if (optwhere == 1)
|
||||
if (data->optwhere == 1)
|
||||
{
|
||||
switch (ordering)
|
||||
{
|
||||
case PERMUTE:
|
||||
permute_from = optind;
|
||||
num_nonopts = 0;
|
||||
while (!is_option (argv[optind], only))
|
||||
{
|
||||
optind++;
|
||||
num_nonopts++;
|
||||
}
|
||||
if (argv[optind] == NULL)
|
||||
{
|
||||
/* no more options */
|
||||
optind = permute_from;
|
||||
return EOF;
|
||||
}
|
||||
else if (strcmp (argv[optind], "--") == 0)
|
||||
{
|
||||
/* no more options, but have to get `--' out of the way */
|
||||
permute (argv + permute_from, num_nonopts, 1);
|
||||
optind = permute_from + 1;
|
||||
return EOF;
|
||||
}
|
||||
break;
|
||||
case RETURN_IN_ORDER:
|
||||
if (!is_option (argv[optind], only))
|
||||
{
|
||||
optarg = argv[optind++];
|
||||
return (optopt = 1);
|
||||
}
|
||||
break;
|
||||
case REQUIRE_ORDER:
|
||||
if (!is_option (argv[optind], only))
|
||||
return EOF;
|
||||
break;
|
||||
}
|
||||
{
|
||||
default: /* shouldn't happen */
|
||||
case PERMUTE:
|
||||
permute_from = data->optind;
|
||||
num_nonopts = 0;
|
||||
while (!is_option (argv[data->optind], only))
|
||||
{
|
||||
data->optind++;
|
||||
num_nonopts++;
|
||||
}
|
||||
if (argv[data->optind] == 0)
|
||||
{
|
||||
/* no more options */
|
||||
data->optind = permute_from;
|
||||
return EOF;
|
||||
}
|
||||
else if (strcmp (argv[data->optind], "--") == 0)
|
||||
{
|
||||
/* no more options, but have to get `--' out of the way */
|
||||
permute (argv + permute_from, num_nonopts, 1);
|
||||
data->optind = permute_from + 1;
|
||||
return EOF;
|
||||
}
|
||||
break;
|
||||
case RETURN_IN_ORDER:
|
||||
if (!is_option (argv[data->optind], only))
|
||||
{
|
||||
data->optarg = argv[data->optind++];
|
||||
return (data->optopt = 1);
|
||||
}
|
||||
break;
|
||||
case REQUIRE_ORDER:
|
||||
if (!is_option (argv[data->optind], only))
|
||||
return EOF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* we've got an option, so parse it */
|
||||
|
||||
/* first, is it a long option? */
|
||||
if (longopts != NULL
|
||||
&& (memcmp (argv[optind], "--", 2) == 0
|
||||
|| (only && argv[optind][0] == '+')) && optwhere == 1)
|
||||
if (longopts != 0
|
||||
&& (memcmp (argv[data->optind], "--", 2) == 0
|
||||
|| (only && argv[data->optind][0] == '+')) && data->optwhere == 1)
|
||||
{
|
||||
/* handle long options */
|
||||
if (memcmp (argv[optind], "--", 2) == 0)
|
||||
optwhere = 2;
|
||||
if (memcmp (argv[data->optind], "--", 2) == 0)
|
||||
data->optwhere = 2;
|
||||
longopt_match = -1;
|
||||
possible_arg = strchr (argv[optind] + optwhere, '=');
|
||||
if (possible_arg == NULL)
|
||||
{
|
||||
/* no =, so next argv might be arg */
|
||||
match_chars = strlen (argv[optind]);
|
||||
possible_arg = argv[optind] + match_chars;
|
||||
match_chars = match_chars - optwhere;
|
||||
}
|
||||
possible_arg = strchr (argv[data->optind] + data->optwhere, '=');
|
||||
if (possible_arg == 0)
|
||||
{
|
||||
/* no =, so next argv might be arg */
|
||||
match_chars = strlen (argv[data->optind]);
|
||||
possible_arg = argv[data->optind] + match_chars;
|
||||
match_chars = match_chars - data->optwhere;
|
||||
}
|
||||
else
|
||||
match_chars = (possible_arg - argv[optind]) - optwhere;
|
||||
for (optindex = 0; longopts[optindex].name != NULL; optindex++)
|
||||
{
|
||||
if (memcmp (argv[optind] + optwhere,
|
||||
longopts[optindex].name, match_chars) == 0)
|
||||
{
|
||||
/* do we have an exact match? */
|
||||
if (match_chars == (int) (strlen (longopts[optindex].name)))
|
||||
{
|
||||
longopt_match = optindex;
|
||||
break;
|
||||
}
|
||||
/* do any characters match? */
|
||||
else
|
||||
{
|
||||
if (longopt_match < 0)
|
||||
longopt_match = optindex;
|
||||
else
|
||||
{
|
||||
/* we have ambiguous options */
|
||||
if (opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous "
|
||||
"(could be `--%s' or `--%s')\n",
|
||||
argv[0],
|
||||
argv[optind],
|
||||
longopts[longopt_match].name,
|
||||
longopts[optindex].name);
|
||||
return (optopt = '?');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match_chars = (possible_arg - argv[data->optind]) - data->optwhere;
|
||||
for (optindex = 0; longopts[optindex].name != 0; ++optindex)
|
||||
{
|
||||
if (memcmp
|
||||
(argv[data->optind] + data->optwhere, longopts[optindex].name,
|
||||
match_chars) == 0)
|
||||
{
|
||||
/* do we have an exact match? */
|
||||
if (match_chars == (int) (strlen (longopts[optindex].name)))
|
||||
{
|
||||
longopt_match = optindex;
|
||||
break;
|
||||
}
|
||||
/* do any characters match? */
|
||||
else
|
||||
{
|
||||
if (longopt_match < 0)
|
||||
longopt_match = optindex;
|
||||
else
|
||||
{
|
||||
/* we have ambiguous options */
|
||||
if (data->opterr)
|
||||
fprintf (stderr, "%s: option `%s' is ambiguous "
|
||||
"(could be `--%s' or `--%s')\n",
|
||||
argv[0],
|
||||
argv[data->optind],
|
||||
longopts[longopt_match].name,
|
||||
longopts[optindex].name);
|
||||
return (data->optopt = '?');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (longopt_match >= 0)
|
||||
has_arg = longopts[longopt_match].has_arg;
|
||||
has_arg = longopts[longopt_match].has_arg;
|
||||
}
|
||||
|
||||
/* if we didn't find a long option, is it a short option? */
|
||||
if (longopt_match < 0 && shortopts != NULL)
|
||||
if (longopt_match < 0 && shortopts != 0)
|
||||
{
|
||||
cp = strchr (shortopts, argv[optind][optwhere]);
|
||||
if (cp == NULL)
|
||||
{
|
||||
/* couldn't find option in shortopts */
|
||||
if (opterr)
|
||||
fprintf (stderr,
|
||||
"%s: invalid option -- `-%c'\n",
|
||||
argv[0], argv[optind][optwhere]);
|
||||
optwhere++;
|
||||
if (argv[optind][optwhere] == '\0')
|
||||
{
|
||||
optind++;
|
||||
optwhere = 1;
|
||||
}
|
||||
return (optopt = '?');
|
||||
}
|
||||
cp = strchr (shortopts, argv[data->optind][data->optwhere]);
|
||||
if (cp == 0)
|
||||
{
|
||||
/* couldn't find option in shortopts */
|
||||
if (data->opterr)
|
||||
fprintf (stderr,
|
||||
"%s: invalid option -- `-%c'\n",
|
||||
argv[0], argv[data->optind][data->optwhere]);
|
||||
data->optwhere++;
|
||||
if (argv[data->optind][data->optwhere] == '\0')
|
||||
{
|
||||
data->optind++;
|
||||
data->optwhere = 1;
|
||||
}
|
||||
return (data->optopt = '?');
|
||||
}
|
||||
has_arg = ((cp[1] == ':')
|
||||
? ((cp[2] == ':') ? OPTIONAL_ARG : REQUIRED_ARG) : NO_ARG);
|
||||
possible_arg = argv[optind] + optwhere + 1;
|
||||
optopt = *cp;
|
||||
? ((cp[2] == ':') ? OPTIONAL_ARG : REQUIRED_ARG) : NO_ARG);
|
||||
possible_arg = argv[data->optind] + data->optwhere + 1;
|
||||
data->optopt = *cp;
|
||||
}
|
||||
/* get argument and reset optwhere */
|
||||
|
||||
/* get argument and reset data->optwhere */
|
||||
arg_next = 0;
|
||||
switch (has_arg)
|
||||
{
|
||||
case OPTIONAL_ARG:
|
||||
if (*possible_arg == '=')
|
||||
possible_arg++;
|
||||
optarg = (*possible_arg != '\0') ? possible_arg : NULL;
|
||||
optwhere = 1;
|
||||
possible_arg++;
|
||||
data->optarg = (*possible_arg != '\0') ? possible_arg : 0;
|
||||
data->optwhere = 1;
|
||||
break;
|
||||
case REQUIRED_ARG:
|
||||
if (*possible_arg == '=')
|
||||
possible_arg++;
|
||||
possible_arg++;
|
||||
if (*possible_arg != '\0')
|
||||
{
|
||||
optarg = possible_arg;
|
||||
optwhere = 1;
|
||||
}
|
||||
else if (optind + 1 >= argc)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
fprintf (stderr, "%s: argument required for option `", argv[0]);
|
||||
if (longopt_match >= 0)
|
||||
fprintf (stderr, "--%s'\n", longopts[longopt_match].name);
|
||||
else
|
||||
fprintf (stderr, "-%c'\n", *cp);
|
||||
}
|
||||
optind++;
|
||||
return (optopt = ':');
|
||||
}
|
||||
{
|
||||
data->optarg = possible_arg;
|
||||
data->optwhere = 1;
|
||||
}
|
||||
else if (data->optind + 1 >= argc)
|
||||
{
|
||||
if (data->opterr)
|
||||
{
|
||||
fprintf (stderr, "%s: argument required for option `", argv[0]);
|
||||
if (longopt_match >= 0)
|
||||
fprintf (stderr, "--%s'\n", longopts[longopt_match].name);
|
||||
else
|
||||
fprintf (stderr, "-%c'\n", *cp);
|
||||
}
|
||||
data->optind++;
|
||||
return (data->optopt = ':');
|
||||
}
|
||||
else
|
||||
{
|
||||
optarg = argv[optind + 1];
|
||||
arg_next = 1;
|
||||
optwhere = 1;
|
||||
}
|
||||
{
|
||||
data->optarg = argv[data->optind + 1];
|
||||
arg_next = 1;
|
||||
data->optwhere = 1;
|
||||
}
|
||||
break;
|
||||
default: /* shouldn't happen */
|
||||
case NO_ARG:
|
||||
if (longopt_match < 0)
|
||||
{
|
||||
optwhere++;
|
||||
if (argv[optind][optwhere] == '\0')
|
||||
optwhere = 1;
|
||||
}
|
||||
{
|
||||
data->optwhere++;
|
||||
if (argv[data->optind][data->optwhere] == '\0')
|
||||
data->optwhere = 1;
|
||||
}
|
||||
else
|
||||
optwhere = 1;
|
||||
optarg = NULL;
|
||||
data->optwhere = 1;
|
||||
data->optarg = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
/* do we have to permute or otherwise modify optind? */
|
||||
if (ordering == PERMUTE && optwhere == 1 && num_nonopts != 0)
|
||||
/* do we have to permute or otherwise modify data->optind? */
|
||||
if (ordering == PERMUTE && data->optwhere == 1 && num_nonopts != 0)
|
||||
{
|
||||
permute (argv + permute_from, num_nonopts, 1 + arg_next);
|
||||
optind = permute_from + 1 + arg_next;
|
||||
data->optind = permute_from + 1 + arg_next;
|
||||
}
|
||||
else if (optwhere == 1)
|
||||
optind = optind + 1 + arg_next;
|
||||
else if (data->optwhere == 1)
|
||||
data->optind = data->optind + 1 + arg_next;
|
||||
|
||||
/* finally return */
|
||||
if (longopt_match >= 0)
|
||||
{
|
||||
if (longind != NULL)
|
||||
*longind = longopt_match;
|
||||
if (longopts[longopt_match].flag != NULL)
|
||||
{
|
||||
*(longopts[longopt_match].flag) = longopts[longopt_match].val;
|
||||
return 0;
|
||||
}
|
||||
if (longind != 0)
|
||||
*longind = longopt_match;
|
||||
if (longopts[longopt_match].flag != 0)
|
||||
{
|
||||
*(longopts[longopt_match].flag) = longopts[longopt_match].val;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return longopts[longopt_match].val;
|
||||
return longopts[longopt_match].val;
|
||||
}
|
||||
else
|
||||
return optopt;
|
||||
return data->optopt;
|
||||
}
|
||||
|
||||
int
|
||||
getopt (int argc, char *const argv[], const char *optstring)
|
||||
{
|
||||
return getopt_internal (argc, argv, optstring, NULL, NULL, 0);
|
||||
struct getopt_data data;
|
||||
int r;
|
||||
|
||||
read_globals (&data);
|
||||
r = getopt_internal (argc, argv, optstring, 0, 0, 0, &data);
|
||||
write_globals (&data);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
getopt_long (int argc, char *const argv[], const char *shortopts,
|
||||
const struct option *longopts, int *longind)
|
||||
const struct option *longopts, int *longind)
|
||||
{
|
||||
return getopt_internal (argc, argv, shortopts, longopts, longind, 0);
|
||||
struct getopt_data data;
|
||||
int r;
|
||||
|
||||
read_globals (&data);
|
||||
r = getopt_internal (argc, argv, shortopts, longopts, longind, 0, &data);
|
||||
write_globals (&data);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
getopt_long_only (int argc, char *const argv[], const char *shortopts,
|
||||
const struct option *longopts, int *longind)
|
||||
const struct option *longopts, int *longind)
|
||||
{
|
||||
return getopt_internal (argc, argv, shortopts, longopts, longind, 1);
|
||||
struct getopt_data data;
|
||||
int r;
|
||||
|
||||
read_globals (&data);
|
||||
r = getopt_internal (argc, argv, shortopts, longopts, longind, 1, &data);
|
||||
write_globals (&data);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
__getopt_r (int argc, char *const argv[], const char *optstring,
|
||||
struct getopt_data *data)
|
||||
{
|
||||
return getopt_internal (argc, argv, optstring, 0, 0, 0, data);
|
||||
}
|
||||
|
||||
int
|
||||
__getopt_long_r (int argc, char *const argv[], const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
struct getopt_data *data)
|
||||
{
|
||||
return getopt_internal (argc, argv, shortopts, longopts, longind, 0, data);
|
||||
}
|
||||
|
||||
int
|
||||
__getopt_long_only_r (int argc, char *const argv[], const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
struct getopt_data *data)
|
||||
{
|
||||
return getopt_internal (argc, argv, shortopts, longopts, longind, 1, data);
|
||||
}
|
||||
|
||||
/* end of file GETOPT.C */
|
||||
|
|
Loading…
Reference in New Issue