#ifndef _NO_PROTO
# define _NO_PROTO
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "share/compat.h"
#if !defined __STDC__ || !__STDC__
# ifndef const
# define const
# endif
#endif
#include <stdio.h>
#define GETOPT_INTERFACE_VERSION 2
#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
# include <gnu-versions.h>
# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
# define ELIDE_CODE
# endif
#endif
#if 1
#ifdef __GNU_LIBRARY__
# include <stdlib.h>
# include <unistd.h>
#endif
#ifdef VMS
# include <unixlib.h>
# ifdef HAVE_STRING_H
# include <string.h>
# endif
#endif
#ifndef _
# ifdef HAVE_LIBINTL_H
# include <libintl.h>
# define _(msgid) gettext (msgid)
# else
# define _(msgid) (msgid)
# endif
#endif
#include "share/getopt.h"
char *share__optarg = 0;
int share__optind = 1;
static int share____getopt_initialized = 0;
static char *nextchar;
int share__opterr = 1;
int share__optopt = '?';
static enum
{
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
} ordering;
static char *posixly_correct;
#ifdef __GNU_LIBRARY__
# include <string.h>
# define my_index strchr
#else
#include <string.h>
#ifndef getenv
extern char *getenv (const char * name);
#endif
static char *
my_index (const char *str, int chr)
{
while (*str)
{
if (*str == chr)
return (char *) str;
str++;
}
return 0;
}
#ifdef __GNUC__
# if (!defined __STDC__ || !__STDC__) && !defined strlen
extern int strlen (const char *);
# endif
#endif
#endif
static int first_nonopt;
static int last_nonopt;
#ifdef _LIBC
extern char *__getopt_nonoption_flags;
static int nonoption_flags_max_len;
static int nonoption_flags_len;
static int original_argc;
static char *const *original_argv;
static void
__attribute__ ((unused))
store_args_and_env (int argc, char *const *argv)
{
original_argc = argc;
original_argv = argv;
}
# ifdef text_set_element
text_set_element (__libc_subinit, store_args_and_env);
# endif
# define SWAP_FLAGS(ch1, ch2) \
if (nonoption_flags_len > 0) \
{ \
char __tmp = __getopt_nonoption_flags[ch1]; \
__getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
__getopt_nonoption_flags[ch2] = __tmp; \
}
#else
# define SWAP_FLAGS(ch1, ch2)
#endif
#if defined __STDC__ && __STDC__
static void exchange (char **);
#endif
static void
exchange (char **argv)
{
int bottom = first_nonopt;
int middle = last_nonopt;
int top = share__optind;
char *tem;
#ifdef _LIBC
if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
{
char *new_str = malloc (top + 1);
if (new_str == NULL)
nonoption_flags_len = nonoption_flags_max_len = 0;
else
{
memset (__mempcpy (new_str, __getopt_nonoption_flags,
nonoption_flags_max_len),
'\0', top + 1 - nonoption_flags_max_len);
nonoption_flags_max_len = top + 1;
__getopt_nonoption_flags = new_str;
}
}
#endif
while (top > middle && middle > bottom)
{
if (top - middle > middle - bottom)
{
int len = middle - bottom;
register int i;
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);
}
top -= len;
}
else
{
int len = top - middle;
register int i;
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);
}
bottom += len;
}
}
first_nonopt += (share__optind - last_nonopt);
last_nonopt = share__optind;
}
#if defined __STDC__ && __STDC__
static const char *share___getopt_initialize (int, char *const *, const char *);
#endif
static const char *
share___getopt_initialize (int argc, char *const *argv, const char *optstring )
{
first_nonopt = last_nonopt = share__optind;
nextchar = NULL;
posixly_correct = getenv ("POSIXLY_CORRECT");
if (optstring[0] == '-')
{
ordering = RETURN_IN_ORDER;
++optstring;
}
else if (optstring[0] == '+')
{
ordering = REQUIRE_ORDER;
++optstring;
}
else if (posixly_correct != NULL)
ordering = REQUIRE_ORDER;
else
ordering = PERMUTE;
#ifdef _LIBC
if (posixly_correct == NULL
&& argc == original_argc && argv == original_argv)
{
if (nonoption_flags_max_len == 0)
{
if (__getopt_nonoption_flags == NULL
|| __getopt_nonoption_flags[0] == '\0')
nonoption_flags_max_len = -1;
else
{
const char *orig_str = __getopt_nonoption_flags;
int len = nonoption_flags_max_len = strlen (orig_str);
if (nonoption_flags_max_len < argc)
nonoption_flags_max_len = argc;
__getopt_nonoption_flags =
malloc (nonoption_flags_max_len);
if (__getopt_nonoption_flags == NULL)
nonoption_flags_max_len = -1;
else
memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
'\0', nonoption_flags_max_len - len);
}
}
nonoption_flags_len = nonoption_flags_max_len;
}
else
nonoption_flags_len = 0;
#else
(void)argc, (void)argv;
#endif
return optstring;
}
int
share___getopt_internal (
int argc,
char *const *argv,
const char *optstring,
const struct share__option *longopts,
int *longind,
int long_only )
{
share__optarg = NULL;
if (share__optind == 0 || !share____getopt_initialized)
{
if (share__optind == 0)
share__optind = 1;
optstring = share___getopt_initialize (argc, argv, optstring);
share____getopt_initialized = 1;
}
#ifdef _LIBC
# define NONOPTION_P (argv[share__optind][0] != '-' || argv[share__optind][1] == '\0' \
|| (share__optind < nonoption_flags_len \
&& __getopt_nonoption_flags[share__optind] == '1'))
#else
# define NONOPTION_P (argv[share__optind][0] != '-' || argv[share__optind][1] == '\0')
#endif
if (nextchar == NULL || *nextchar == '\0')
{
if (last_nonopt > share__optind)
last_nonopt = share__optind;
if (first_nonopt > share__optind)
first_nonopt = share__optind;
if (ordering == PERMUTE)
{
if (first_nonopt != last_nonopt && last_nonopt != share__optind)
exchange ((char **) argv);
else if (last_nonopt != share__optind)
first_nonopt = share__optind;
while (share__optind < argc && NONOPTION_P)
share__optind++;
last_nonopt = share__optind;
}
if (share__optind != argc && !strcmp (argv[share__optind], "--"))
{
share__optind++;
if (first_nonopt != last_nonopt && last_nonopt != share__optind)
exchange ((char **) argv);
else if (first_nonopt == last_nonopt)
first_nonopt = share__optind;
last_nonopt = argc;
share__optind = argc;
}
if (share__optind == argc)
{
if (first_nonopt != last_nonopt)
share__optind = first_nonopt;
return -1;
}
if (NONOPTION_P)
{
if (ordering == REQUIRE_ORDER)
return -1;
share__optarg = argv[share__optind++];
return 1;
}
nextchar = (argv[share__optind] + 1
+ (longopts != NULL && argv[share__optind][1] == '-'));
}
if (longopts != NULL
&& (argv[share__optind][1] == '-'
|| (long_only && (argv[share__optind][2] || !my_index (optstring, argv[share__optind][1])))))
{
char *nameend;
const struct share__option *p;
const struct share__option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = -1;
int option_index;
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
;
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((size_t) (nameend - nextchar) == strlen (p->name))
{
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
pfound = p;
indfound = option_index;
}
else
ambig = 1;
}
if (ambig && !exact)
{
if (share__opterr)
flac_fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
argv[0], argv[share__optind]);
nextchar += strlen (nextchar);
share__optind++;
share__optopt = 0;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
share__optind++;
if (*nameend)
{
if (pfound->has_arg)
share__optarg = nameend + 1;
else
{
if (share__opterr)
{
if (argv[share__optind - 1][1] == '-')
flac_fprintf (stderr,
_("%s: option `--%s' doesn't allow an argument\n"),
argv[0], pfound->name);
else
flac_fprintf (stderr,
_("%s: option `%c%s' doesn't allow an argument\n"),
argv[0], argv[share__optind - 1][0], pfound->name);
}
nextchar += strlen (nextchar);
share__optopt = pfound->val;
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (share__optind < argc)
share__optarg = argv[share__optind++];
else
{
if (share__opterr)
flac_fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[share__optind - 1]);
nextchar += strlen (nextchar);
share__optopt = pfound->val;
return optstring[0] == ':' ? ':' : '?';
}
}
nextchar += strlen (nextchar);
if (longind != NULL)
*longind = option_index;
if (pfound->flag)
{
*(pfound->flag) = pfound->val;
return 0;
}
return pfound->val;
}
if (!long_only || argv[share__optind][1] == '-'
|| my_index (optstring, *nextchar) == NULL)
{
if (share__opterr)
{
if (argv[share__optind][1] == '-')
flac_fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
argv[0], nextchar);
else
flac_fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
argv[0], argv[share__optind][0], nextchar);
}
nextchar = (char *) "";
share__optind++;
share__optopt = 0;
return '?';
}
}
{
char c = *nextchar++;
char *temp = my_index (optstring, c);
if (*nextchar == '\0')
++share__optind;
if (temp == NULL || c == ':')
{
if (share__opterr)
{
if (posixly_correct)
flac_fprintf (stderr, _("%s: illegal option -- %c\n"),
argv[0], c);
else
flac_fprintf (stderr, _("%s: invalid option -- %c\n"),
argv[0], c);
}
share__optopt = c;
return '?';
}
if (temp[0] == 'W' && temp[1] == ';')
{
char *nameend;
const struct share__option *p;
const struct share__option *pfound = NULL;
int exact = 0;
int ambig = 0;
int indfound = 0;
int option_index;
if (*nextchar != '\0')
{
share__optarg = nextchar;
share__optind++;
}
else if (share__optind == argc)
{
if (share__opterr)
{
flac_fprintf (stderr, _("%s: option requires an argument -- %c\n"),
argv[0], c);
}
share__optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
return c;
}
else
share__optarg = argv[share__optind++];
for (nextchar = nameend = share__optarg; *nameend && *nameend != '='; nameend++)
;
for (p = longopts, option_index = 0; p->name; p++, option_index++)
if (!strncmp (p->name, nextchar, nameend - nextchar))
{
if ((size_t) (nameend - nextchar) == strlen (p->name))
{
pfound = p;
indfound = option_index;
exact = 1;
break;
}
else if (pfound == NULL)
{
pfound = p;
indfound = option_index;
}
else
ambig = 1;
}
if (ambig && !exact)
{
if (share__opterr)
flac_fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
argv[0], argv[share__optind]);
nextchar += strlen (nextchar);
share__optind++;
return '?';
}
if (pfound != NULL)
{
option_index = indfound;
if (*nameend)
{
if (pfound->has_arg)
share__optarg = nameend + 1;
else
{
if (share__opterr)
flac_fprintf (stderr, _("\
%s: option `-W %s' doesn't allow an argument\n"),
argv[0], pfound->name);
nextchar += strlen (nextchar);
return '?';
}
}
else if (pfound->has_arg == 1)
{
if (share__optind < argc)
share__optarg = argv[share__optind++];
else
{
if (share__opterr)
flac_fprintf (stderr,
_("%s: option `%s' requires an argument\n"),
argv[0], argv[share__optind - 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 = NULL;
return 'W';
}
if (temp[1] == ':')
{
if (temp[2] == ':')
{
if (*nextchar != '\0')
{
share__optarg = nextchar;
share__optind++;
}
else
share__optarg = NULL;
nextchar = NULL;
}
else
{
if (*nextchar != '\0')
{
share__optarg = nextchar;
share__optind++;
}
else if (share__optind == argc)
{
if (share__opterr)
{
flac_fprintf (stderr,
_("%s: option requires an argument -- %c\n"),
argv[0], c);
}
share__optopt = c;
if (optstring[0] == ':')
c = ':';
else
c = '?';
}
else
share__optarg = argv[share__optind++];
nextchar = NULL;
}
}
return c;
}
}
int
share__getopt (int argc, char *const *argv, const char *optstring)
{
return share___getopt_internal (argc, argv, optstring,
(const struct share__option *) 0,
(int *) 0,
0);
}
#endif
#ifdef TEST
int
main (int argc, char **argv)
{
int c;
int digit_optind = 0;
while (1)
{
int this_option_optind = share__optind ? share__optind : 1;
c = share__getopt (argc, argv, "abc:d:0123456789");
if (c == -1)
break;
switch (c)
{
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
if (digit_optind != 0 && digit_optind != this_option_optind)
flac_printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
flac_printf ("option %c\n", c);
break;
case 'a':
flac_printf ("option a\n");
break;
case 'b':
flac_printf ("option b\n");
break;
case 'c':
flac_printf ("option c with value `%s'\n", share__optarg);
break;
case '?':
break;
default:
flac_printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (share__optind < argc)
{
flac_printf ("non-option ARGV-elements: ");
while (share__optind < argc)
flac_printf ("%s ", argv[share__optind++]);
flac_printf ("\n");
}
exit (0);
}
#endif