mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-05-29 18:51:15 -03:00
Remove trailing whitespaces and change tabs to spaces
This commit is contained in:
726
wgetopt.cpp
726
wgetopt.cpp
@@ -1,24 +1,24 @@
|
||||
/** \file wgetopt.c
|
||||
A version of the getopt library for use with wide character strings.
|
||||
A version of the getopt library for use with wide character strings.
|
||||
|
||||
This is simply the gnu getopt library, but converted for use with
|
||||
wchar_t instead of char. This is not usually useful since the argv
|
||||
array is always defined to be of type char**, but in fish, all
|
||||
internal commands use wide characters and hence this library is
|
||||
useful.
|
||||
This is simply the gnu getopt library, but converted for use with
|
||||
wchar_t instead of char. This is not usually useful since the argv
|
||||
array is always defined to be of type char**, but in fish, all
|
||||
internal commands use wide characters and hence this library is
|
||||
useful.
|
||||
|
||||
If you want to use this version of getopt in your program,
|
||||
download the fish sourcecode, available at <a
|
||||
href='http://ridiculousfish.com/shell/'>the fish homepage</a>. Extract
|
||||
the sourcode, copy wgetopt.c and wgetopt.h into your program
|
||||
directory, include wgetopt.h in your program, and use all the
|
||||
regular getopt functions, prefixing every function, global
|
||||
variable and structure with a 'w', and use only wide character
|
||||
strings. There are no other functional changes in this version of
|
||||
getopt besides using wide character strings.
|
||||
If you want to use this version of getopt in your program,
|
||||
download the fish sourcecode, available at <a
|
||||
href='http://ridiculousfish.com/shell/'>the fish homepage</a>. Extract
|
||||
the sourcode, copy wgetopt.c and wgetopt.h into your program
|
||||
directory, include wgetopt.h in your program, and use all the
|
||||
regular getopt functions, prefixing every function, global
|
||||
variable and structure with a 'w', and use only wide character
|
||||
strings. There are no other functional changes in this version of
|
||||
getopt besides using wide character strings.
|
||||
|
||||
For examples of how to use wgetopt, see the fish builtin
|
||||
functions, many of which are defined in builtin.c.
|
||||
For examples of how to use wgetopt, see the fish builtin
|
||||
functions, many of which are defined in builtin.c.
|
||||
|
||||
*/
|
||||
|
||||
@@ -70,11 +70,11 @@
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||
contain conflicting prototypes for getopt. */
|
||||
#include <stdlib.h>
|
||||
#endif /* GNU C library. */
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
@@ -170,7 +170,7 @@ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
|
||||
|
||||
static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
/* Value of POSIXLY_CORRECT environment variable. */
|
||||
@@ -193,13 +193,13 @@ static char *posixly_correct;
|
||||
#define _(wstr) wstr
|
||||
#endif
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
because there are many ways it can cause trouble.
|
||||
On some systems, it contains special magic macros that don't work
|
||||
in GCC. */
|
||||
#include <string.h>
|
||||
#define my_index wcschr
|
||||
#define my_index wcschr
|
||||
#else
|
||||
|
||||
/* Avoid depending on library functions or files
|
||||
@@ -210,13 +210,13 @@ char *getenv ();
|
||||
static wchar_t *
|
||||
my_index (const wchar_t *str, int chr)
|
||||
{
|
||||
while (*str)
|
||||
while (*str)
|
||||
{
|
||||
if (*str == chr)
|
||||
return (wchar_t *) str;
|
||||
str++;
|
||||
if (*str == chr)
|
||||
return (wchar_t *) str;
|
||||
str++;
|
||||
}
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
@@ -254,56 +254,56 @@ static int last_nonopt;
|
||||
static void
|
||||
exchange (wchar_t **argv)
|
||||
{
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = woptind;
|
||||
wchar_t *tem;
|
||||
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
but it consists of two parts that need to be swapped next. */
|
||||
int bottom = first_nonopt;
|
||||
int middle = last_nonopt;
|
||||
int top = woptind;
|
||||
wchar_t *tem;
|
||||
|
||||
while (top > middle && middle > bottom)
|
||||
/* Exchange the shorter segment with the far end of the longer segment.
|
||||
That puts the shorter segment into the right place.
|
||||
It leaves the longer segment in the right place overall,
|
||||
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;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
/* 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;
|
||||
}
|
||||
/* Exclude the moved top segment from further swapping. */
|
||||
bottom += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
/* Update records for the slots the non-options now occupy. */
|
||||
|
||||
first_nonopt += (woptind - last_nonopt);
|
||||
last_nonopt = woptind;
|
||||
first_nonopt += (woptind - last_nonopt);
|
||||
last_nonopt = woptind;
|
||||
}
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
@@ -311,34 +311,34 @@ exchange (wchar_t **argv)
|
||||
static const wchar_t *
|
||||
_wgetopt_initialize (const wchar_t *optstring)
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
first_nonopt = last_nonopt = woptind = 1;
|
||||
first_nonopt = last_nonopt = woptind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
nextchar = NULL;
|
||||
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
@@ -400,312 +400,312 @@ _wgetopt_initialize (const wchar_t *optstring)
|
||||
int
|
||||
_wgetopt_internal (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct woption *longopts, int *longind, int long_only)
|
||||
{
|
||||
woptarg = NULL;
|
||||
woptarg = NULL;
|
||||
|
||||
if (woptind == 0)
|
||||
optstring = _wgetopt_initialize (optstring);
|
||||
if (woptind == 0)
|
||||
optstring = _wgetopt_initialize (optstring);
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
exchange them so that the options come first. */
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (last_nonopt != woptind)
|
||||
first_nonopt = woptind;
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (last_nonopt != woptind)
|
||||
first_nonopt = woptind;
|
||||
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (woptind < argc
|
||||
&& (argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
woptind++;
|
||||
last_nonopt = woptind;
|
||||
}
|
||||
|
||||
/* 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 (woptind != argc && !wcscmp (argv[woptind], L"--"))
|
||||
{
|
||||
woptind++;
|
||||
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = woptind;
|
||||
last_nonopt = argc;
|
||||
|
||||
woptind = argc;
|
||||
}
|
||||
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
if (woptind == 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)
|
||||
woptind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* 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 ((argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
woptarg = argv[woptind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[woptind] + 1
|
||||
+ (longopts != NULL && argv[woptind][1] == '-'));
|
||||
while (woptind < argc
|
||||
&& (argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
woptind++;
|
||||
last_nonopt = woptind;
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
/* 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. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[woptind][1] == '-'
|
||||
|| (long_only && (argv[woptind][2] || !my_index (optstring, argv[woptind][1])))))
|
||||
if (woptind != argc && !wcscmp (argv[woptind], L"--"))
|
||||
{
|
||||
wchar_t *nameend;
|
||||
const struct woption *p;
|
||||
const struct woption *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound = 0; /* set to zero by Anton */
|
||||
int option_index;
|
||||
woptind++;
|
||||
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
if (first_nonopt != last_nonopt && last_nonopt != woptind)
|
||||
exchange ((wchar_t **) argv);
|
||||
else if (first_nonopt == last_nonopt)
|
||||
first_nonopt = woptind;
|
||||
last_nonopt = argc;
|
||||
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!wcsncmp(p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((unsigned int)(nameend - nextchar) == (unsigned int)wcslen (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 (wopterr)
|
||||
fwprintf (stderr, _(L"%ls: Option '%ls' is ambiguous\n"),
|
||||
argv[0], argv[woptind]);
|
||||
nextchar += wcslen (nextchar);
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
woptind++;
|
||||
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)
|
||||
woptarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind - 1][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr,
|
||||
_(L"%ls: Option '--%ls' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr,
|
||||
_(L"%ls: Option '%lc%ls' doesn't allow an argument\n"),
|
||||
argv[0], argv[woptind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += wcslen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (woptind < argc)
|
||||
woptarg = argv[woptind++];
|
||||
else
|
||||
{
|
||||
if (wopterr)
|
||||
fwprintf (stderr, _(L"%ls: Option '%ls' requires an argument\n"),
|
||||
argv[0], argv[woptind - 1]);
|
||||
nextchar += wcslen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += wcslen (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[woptind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr, _(L"%ls: Unrecognized option '--%ls'\n"),
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr, _(L"%ls: Unrecognized option '%lc%ls'\n"),
|
||||
argv[0], argv[woptind][0], nextchar);
|
||||
}
|
||||
nextchar = (wchar_t *) L"";
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
woptind = argc;
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
/* If we have done all the ARGV-elements, stop the scan
|
||||
and back over any non-options that we skipped and permuted. */
|
||||
|
||||
{
|
||||
wchar_t c = *nextchar++;
|
||||
wchar_t *temp = const_cast<wchar_t*>(my_index (optstring, c));
|
||||
if (woptind == 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)
|
||||
woptind = first_nonopt;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Increment `woptind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++woptind;
|
||||
/* 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 (temp == NULL || c == ':')
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, _(L"%ls: Illegal option -- %lc\n"), argv[0], c);
|
||||
else
|
||||
fwprintf (stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
woptind++;
|
||||
}
|
||||
else
|
||||
woptarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
woptind++;
|
||||
}
|
||||
else if (woptind == argc)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, _(L"%ls: Option requires an argument -- %lc\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `woptind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
woptarg = argv[woptind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
if ((argv[woptind][0] != '-' || argv[woptind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
woptarg = argv[woptind++];
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[woptind] + 1
|
||||
+ (longopts != NULL && argv[woptind][1] == '-'));
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& (argv[woptind][1] == '-'
|
||||
|| (long_only && (argv[woptind][2] || !my_index (optstring, argv[woptind][1])))))
|
||||
{
|
||||
wchar_t *nameend;
|
||||
const struct woption *p;
|
||||
const struct woption *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
int indfound = 0; /* set to zero by Anton */
|
||||
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 (!wcsncmp(p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if ((unsigned int)(nameend - nextchar) == (unsigned int)wcslen (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 (wopterr)
|
||||
fwprintf (stderr, _(L"%ls: Option '%ls' is ambiguous\n"),
|
||||
argv[0], argv[woptind]);
|
||||
nextchar += wcslen (nextchar);
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (pfound != NULL)
|
||||
{
|
||||
option_index = indfound;
|
||||
woptind++;
|
||||
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)
|
||||
woptarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind - 1][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr,
|
||||
_(L"%ls: Option '--%ls' doesn't allow an argument\n"),
|
||||
argv[0], pfound->name);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr,
|
||||
_(L"%ls: Option '%lc%ls' doesn't allow an argument\n"),
|
||||
argv[0], argv[woptind - 1][0], pfound->name);
|
||||
}
|
||||
nextchar += wcslen (nextchar);
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
else if (pfound->has_arg == 1)
|
||||
{
|
||||
if (woptind < argc)
|
||||
woptarg = argv[woptind++];
|
||||
else
|
||||
{
|
||||
if (wopterr)
|
||||
fwprintf (stderr, _(L"%ls: Option '%ls' requires an argument\n"),
|
||||
argv[0], argv[woptind - 1]);
|
||||
nextchar += wcslen (nextchar);
|
||||
return optstring[0] == ':' ? ':' : '?';
|
||||
}
|
||||
}
|
||||
nextchar += wcslen (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[woptind][1] == '-'
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (argv[woptind][1] == '-')
|
||||
/* --option */
|
||||
fwprintf (stderr, _(L"%ls: Unrecognized option '--%ls'\n"),
|
||||
argv[0], nextchar);
|
||||
else
|
||||
/* +option or -option */
|
||||
fwprintf (stderr, _(L"%ls: Unrecognized option '%lc%ls'\n"),
|
||||
argv[0], argv[woptind][0], nextchar);
|
||||
}
|
||||
nextchar = (wchar_t *) L"";
|
||||
woptind++;
|
||||
return '?';
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
wchar_t c = *nextchar++;
|
||||
wchar_t *temp = const_cast<wchar_t*>(my_index (optstring, c));
|
||||
|
||||
/* Increment `woptind' when we start to process its last character. */
|
||||
if (*nextchar == '\0')
|
||||
++woptind;
|
||||
|
||||
if (temp == NULL || c == ':')
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, _(L"%ls: Illegal option -- %lc\n"), argv[0], c);
|
||||
else
|
||||
fwprintf (stderr, _(L"%ls: Invalid option -- %lc\n"), argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
return '?';
|
||||
}
|
||||
if (temp[1] == ':')
|
||||
{
|
||||
if (temp[2] == ':')
|
||||
{
|
||||
/* This is an option that accepts an argument optionally. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
woptind++;
|
||||
}
|
||||
else
|
||||
woptarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is an option that requires an argument. */
|
||||
if (*nextchar != '\0')
|
||||
{
|
||||
woptarg = nextchar;
|
||||
/* If we end this ARGV-element by taking the rest as an arg,
|
||||
we must advance to the next element now. */
|
||||
woptind++;
|
||||
}
|
||||
else if (woptind == argc)
|
||||
{
|
||||
if (wopterr)
|
||||
{
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fwprintf (stderr, _(L"%ls: Option requires an argument -- %lc\n"),
|
||||
argv[0], c);
|
||||
}
|
||||
woptopt = c;
|
||||
if (optstring[0] == ':')
|
||||
c = ':';
|
||||
else
|
||||
c = '?';
|
||||
}
|
||||
else
|
||||
/* We already incremented `woptind' once;
|
||||
increment it again when taking next ARGV-elt as argument. */
|
||||
woptarg = argv[woptind++];
|
||||
nextchar = NULL;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
wgetopt (int argc, wchar_t *const *argv, const wchar_t *optstring)
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, optstring,
|
||||
(const struct woption *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
return _wgetopt_internal (argc, argv, optstring,
|
||||
(const struct woption *) 0,
|
||||
(int *) 0,
|
||||
0);
|
||||
}
|
||||
|
||||
int
|
||||
wgetopt_long (int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index)
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
int
|
||||
wgetopt_long_only (int argc, wchar_t *const *argv, const wchar_t *options, const struct woption *long_options, int *opt_index)
|
||||
{
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
return _wgetopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user