Fix MinGW-Bug [2144266]: getopt() sets `optind' incorrectly.
This commit is contained in:
parent
13ff1518ee
commit
e77c4e6672
@ -1,3 +1,14 @@
|
|||||||
|
2008-10-03 Keith Marshall <keithmarshall@users.sourceforge.net>
|
||||||
|
|
||||||
|
Fix MinGW-Bug [2144266]: getopt() sets `optind' incorrectly.
|
||||||
|
(Reported by Christian Franke)
|
||||||
|
|
||||||
|
* mingwex/getopt.c (optind): Make global variable value conform to
|
||||||
|
behaviour specified by POSIX; do not use it for internal state in...
|
||||||
|
(getopt_parse): ...this static function; use...
|
||||||
|
(optbase): ...this new static local variable instead.
|
||||||
|
(getopt_resolved): Update `optind' as required.
|
||||||
|
|
||||||
2008-10-03 Keith Marshall <keithmarshall@users.sourceforge.net>
|
2008-10-03 Keith Marshall <keithmarshall@users.sourceforge.net>
|
||||||
|
|
||||||
Improve package identification in configure script.
|
Improve package identification in configure script.
|
||||||
|
@ -254,6 +254,12 @@ struct option *opt, int index, int *retindex, const CHAR *optstring )
|
|||||||
if( retindex != NULL )
|
if( retindex != NULL )
|
||||||
*retindex = index;
|
*retindex = index;
|
||||||
|
|
||||||
|
/* On return, `optind' should normally refer to the argument, if any,
|
||||||
|
* which follows the current one; it is convenient to set this, before
|
||||||
|
* checking for the presence of any `optarg'.
|
||||||
|
*/
|
||||||
|
optind = *argind + 1;
|
||||||
|
|
||||||
if( optarg && (opt[index].has_arg == no_argument) )
|
if( optarg && (opt[index].has_arg == no_argument) )
|
||||||
/*
|
/*
|
||||||
* it is an error for the user to specify an option specific argument
|
* it is an error for the user to specify an option specific argument
|
||||||
@ -267,12 +273,12 @@ struct option *opt, int index, int *retindex, const CHAR *optstring )
|
|||||||
/* similarly, it is an error if no argument is specified
|
/* similarly, it is an error if no argument is specified
|
||||||
* with an option which requires one ...
|
* with an option which requires one ...
|
||||||
*/
|
*/
|
||||||
if( (*argind + 1) < argc )
|
if( optind < argc )
|
||||||
/*
|
/*
|
||||||
* ... except that the requirement may be satisfied from
|
* ... except that the requirement may be satisfied from
|
||||||
* the following comand line argument, if any ...
|
* the following command line argument, if any ...
|
||||||
*/
|
*/
|
||||||
optarg = argv[++*argind];
|
optarg = argv[*argind = optind++];
|
||||||
|
|
||||||
else
|
else
|
||||||
/* so fail this case, only if no such argument exists!
|
/* so fail this case, only if no such argument exists!
|
||||||
@ -303,19 +309,23 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
/* Common core implementation for ALL `getopt' functions.
|
/* Common core implementation for ALL `getopt' functions.
|
||||||
*/
|
*/
|
||||||
static int argind = 0;
|
static int argind = 0;
|
||||||
|
static int optbase = 0;
|
||||||
static const CHAR *nextchar = NULL;
|
static const CHAR *nextchar = NULL;
|
||||||
static int optmark = 0;
|
static int optmark = 0;
|
||||||
|
|
||||||
if( (argind == 0) || (optind == 0) )
|
if( optind < optbase )
|
||||||
{
|
{
|
||||||
/* POSIX wants `optind' to have an initial value of one, but we want
|
/* POSIX does not prescribe any definitive mechanism for restarting
|
||||||
* it to be initialised to zero, when we are called for the first time,
|
* a `getopt' scan, but some applications may require such capability.
|
||||||
* (as indicated by `argind' having a value of zero). We also want to
|
* We will support it, by allowing the caller to adjust the value of
|
||||||
* allow the caller to reset the `getopt' parser, causing it to scan
|
* `optind' downwards, (nominally setting it to zero). Since POSIX
|
||||||
* the arguments again, (or to scan a new set of arguments); this
|
* wants `optind' to have an initial value of one, but we want all
|
||||||
* may be achieved by the caller resetting `optind' to zero.
|
* of our internal placeholders to be initialised to zero, when we
|
||||||
|
* are called for the first time, we will handle such a reset by
|
||||||
|
* adjusting all of the internal placeholders to one less than the
|
||||||
|
* adjusted `optind' value, (but never to less than zero).
|
||||||
*/
|
*/
|
||||||
optmark = optind = argind = 0;
|
optmark = optbase = argind = (optind > 0) ? optind - 1 : 0;
|
||||||
nextchar = NULL;
|
nextchar = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,10 +373,12 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
return getopt_missing_arg( optstring );
|
return getopt_missing_arg( optstring );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
optind = argind + 1;
|
||||||
nextchar = NULL;
|
nextchar = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
optarg = NULL;
|
optarg = NULL;
|
||||||
|
optind = (nextchar && *nextchar) ? argind : argind + 1;
|
||||||
return optopt;
|
return optopt;
|
||||||
}
|
}
|
||||||
/* if we didn't find a valid match for the specified option character,
|
/* if we didn't find a valid match for the specified option character,
|
||||||
@ -378,11 +390,13 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
nextchar = NULL;
|
nextchar = NULL;
|
||||||
optopt = 0;
|
optopt = 0;
|
||||||
}
|
}
|
||||||
else complain( "invalid option -- %c", optopt );
|
else
|
||||||
|
complain( "invalid option -- %c", optopt );
|
||||||
|
optind = (nextchar && *nextchar) ? argind : argind + 1;
|
||||||
return getopt_unknown;
|
return getopt_unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( optmark > optind )
|
if( optmark > optbase )
|
||||||
{
|
{
|
||||||
/* This can happen, in GNU parsing mode ONLY, when we have
|
/* This can happen, in GNU parsing mode ONLY, when we have
|
||||||
* skipped over non-option arguments, and found a subsequent
|
* skipped over non-option arguments, and found a subsequent
|
||||||
@ -416,25 +430,25 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
* overwriting these saved arguments, while making space
|
* overwriting these saved arguments, while making space
|
||||||
* to replace them in their permuted location.
|
* to replace them in their permuted location.
|
||||||
*/
|
*/
|
||||||
for( --optmark; optmark >= optind; --optmark )
|
for( --optmark; optmark >= optbase; --optmark )
|
||||||
arglist[optmark + optspan] = arglist[optmark];
|
arglist[optmark + optspan] = arglist[optmark];
|
||||||
|
|
||||||
/* restore the temporarily saved option arguments to
|
/* restore the temporarily saved option arguments to
|
||||||
* their permuted location.
|
* their permuted location.
|
||||||
*/
|
*/
|
||||||
for( index = 0; index < optspan; ++index )
|
for( index = 0; index < optspan; ++index )
|
||||||
arglist[optind + index] = this_arg[index];
|
arglist[optbase + index] = this_arg[index];
|
||||||
|
|
||||||
/* adjust `optind', to account for the relocated option.
|
/* adjust `optbase', to account for the relocated option.
|
||||||
*/
|
*/
|
||||||
optind += optspan;
|
optbase += optspan;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
/* no permutation occurred ...
|
/* no permutation occurred ...
|
||||||
* simply adjust `optind' for all options parsed so far.
|
* simply adjust `optbase' for all options parsed so far.
|
||||||
*/
|
*/
|
||||||
optind = argind + 1;
|
optbase = argind + 1;
|
||||||
|
|
||||||
/* enter main parsing loop ...
|
/* enter main parsing loop ...
|
||||||
*/
|
*/
|
||||||
@ -468,7 +482,7 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
{
|
{
|
||||||
/* this is an explicit `--' end of options marker, so wrap up now!
|
/* this is an explicit `--' end of options marker, so wrap up now!
|
||||||
*/
|
*/
|
||||||
if( optmark > optind )
|
if( optmark > optbase )
|
||||||
{
|
{
|
||||||
/* permuting the argument list as necessary ...
|
/* permuting the argument list as necessary ...
|
||||||
* (note use of `this_arg' and `arglist', as above).
|
* (note use of `this_arg' and `arglist', as above).
|
||||||
@ -479,16 +493,16 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
/* move all preceding non-option arguments to the right ...
|
/* move all preceding non-option arguments to the right ...
|
||||||
*/
|
*/
|
||||||
do arglist[optmark] = arglist[optmark - 1];
|
do arglist[optmark] = arglist[optmark - 1];
|
||||||
while( optmark-- > optind );
|
while( optmark-- > optbase );
|
||||||
|
|
||||||
/* reinstate the `--' marker, in its permuted location.
|
/* reinstate the `--' marker, in its permuted location.
|
||||||
*/
|
*/
|
||||||
arglist[optind] = this_arg;
|
arglist[optbase] = this_arg;
|
||||||
}
|
}
|
||||||
/* ... before finally bumping `optind' past the `--' marker,
|
/* ... before finally bumping `optbase' past the `--' marker,
|
||||||
* and returning the `all done' completion indicator.
|
* and returning the `all done' completion indicator.
|
||||||
*/
|
*/
|
||||||
++optind;
|
optind = ++optbase;
|
||||||
return getopt_all_done;
|
return getopt_all_done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -549,9 +563,10 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
{
|
{
|
||||||
/* if this is not the first, then we have an ambiguity ...
|
/* if this is not the first, then we have an ambiguity ...
|
||||||
*/
|
*/
|
||||||
complain( "option `%s' is ambiguous", argv[argind] );
|
|
||||||
nextchar = NULL;
|
|
||||||
optopt = 0;
|
optopt = 0;
|
||||||
|
nextchar = NULL;
|
||||||
|
optind = argind + 1;
|
||||||
|
complain( "option `%s' is ambiguous", argv[argind] );
|
||||||
return getopt_unknown;
|
return getopt_unknown;
|
||||||
}
|
}
|
||||||
/* otherwise just note that we've found a possible match ...
|
/* otherwise just note that we've found a possible match ...
|
||||||
@ -576,6 +591,7 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
*/
|
*/
|
||||||
optopt = 0;
|
optopt = 0;
|
||||||
nextchar = NULL;
|
nextchar = NULL;
|
||||||
|
optind = argind + 1;
|
||||||
complain( "unrecognised option `%s'", argv[argind] );
|
complain( "unrecognised option `%s'", argv[argind] );
|
||||||
return getopt_unknown;
|
return getopt_unknown;
|
||||||
}
|
}
|
||||||
@ -601,6 +617,7 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
* option, with return value defined as `getopt_ordered'.
|
* option, with return value defined as `getopt_ordered'.
|
||||||
*/
|
*/
|
||||||
nextchar = NULL;
|
nextchar = NULL;
|
||||||
|
optind = argind + 1;
|
||||||
optarg = argv[argind];
|
optarg = argv[argind];
|
||||||
return getopt_ordered;
|
return getopt_ordered;
|
||||||
}
|
}
|
||||||
@ -615,6 +632,7 @@ int getopt_parse( int mode, getopt_std_args, ... )
|
|||||||
}
|
}
|
||||||
/* fall through when all arguments have been evaluated,
|
/* fall through when all arguments have been evaluated,
|
||||||
*/
|
*/
|
||||||
|
optind = optbase;
|
||||||
return getopt_all_done;
|
return getopt_all_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user