diff options
author | Keith Marshall <keithmarshall@@users.sf.net> | 2009-02-08 18:02:17 +0000 |
---|---|---|
committer | Keith Marshall <keithmarshall@@users.sf.net> | 2009-02-08 18:02:17 +0000 |
commit | ce6ef36015f0abdae8b07f3b1178d51b7bb95401 (patch) | |
tree | 6468d559182e3d4af4637a39cc4b8c7226b6c968 /winsup/mingw | |
parent | f8471cd02373096345dff5ac8b405a6e7a8b0e1a (diff) | |
download | newlib-ce6ef36015f0abdae8b07f3b1178d51b7bb95401.zip newlib-ce6ef36015f0abdae8b07f3b1178d51b7bb95401.tar.gz newlib-ce6ef36015f0abdae8b07f3b1178d51b7bb95401.tar.bz2 |
MinGW-Feature-Request [2222263]: Make getopt() GNU / BSD compatibile.
Diffstat (limited to 'winsup/mingw')
-rw-r--r-- | winsup/mingw/ChangeLog | 8 | ||||
-rw-r--r-- | winsup/mingw/mingwex/getopt.c | 37 |
2 files changed, 39 insertions, 6 deletions
diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog index 0ec3b0d..1a8d264 100644 --- a/winsup/mingw/ChangeLog +++ b/winsup/mingw/ChangeLog @@ -1,3 +1,11 @@ +2009-02-08 Keith Marshall <keithmarshall@users.sourceforge.net> + + MinGW-Feature-Request [2222263]: Make getopt() GNU / BSD compatibile. + (Requested by Robert Riebisch) + + * mingwex/getopt.c (getopt_parse): Track external increments of... + (optind): ...this global variable. + 2009-01-10 Chris Sutcliffe <ir0nh34d@users.sourceforge.net> * include/_mingw.h: Increment version to 3.15.2. diff --git a/winsup/mingw/mingwex/getopt.c b/winsup/mingw/mingwex/getopt.c index 29753ca..4f081d1 100644 --- a/winsup/mingw/mingwex/getopt.c +++ b/winsup/mingw/mingwex/getopt.c @@ -328,18 +328,18 @@ int getopt_parse( int mode, getopt_std_args, ... ) * We will support it, by allowing the caller to adjust the value of * `optind' downwards, (nominally setting it to zero). Since POSIX * wants `optind' to have an initial value of one, but we want all - * of our internal placeholders to be initialised to zero, when we + * of our internal place holders 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). + * adjusting all of the internal place holders to one less than + * the adjusted `optind' value, (but never to less than zero). */ if( optreset ) { /* User has explicitly requested reinitialisation... * We need to reset `optind' to it's normal initial value of 1, * to avoid a potential infinitely recursive loop; by doing this - * up front, we also ensure that the remaining placeholders will - * be correctly reinitialised to no less than zero. + * up front, we also ensure that the remaining place holders + * will be correctly reinitialised to no less than zero. */ optind = 1; @@ -348,12 +348,37 @@ int getopt_parse( int mode, getopt_std_args, ... ) optreset = 0; } - /* Now, we may safely reinitialise the internal placeholders, to + /* Now, we may safely reinitialise the internal place holders, to * one less than `optind', without fear of making them negative. */ optmark = optbase = argind = optind - 1; nextchar = NULL; } + + /* From a POSIX perspective, the following is `undefined behaviour'; + * we implement it thus, for compatibility with GNU and BSD getopt. + */ + else if( optind > (argind + 1) ) + { + /* Some applications expect to be able to manipulate `optind', + * causing `getopt' to skip over one or more elements of `argv'; + * POSIX doesn't require us to support this brain-damaged concept; + * (indeed, POSIX defines no particular behaviour, in the event of + * such usage, so it must be considered a bug for an application + * to rely on any particular outcome); nonetheless, Mac-OS-X and + * BSD actually provide *documented* support for this capability, + * so we ensure that our internal place holders keep track of + * external `optind' increments; (`argind' must lag by one). + */ + argind = optind - 1; + + /* When `optind' is misused, in this fashion, we also abandon any + * residual text in the argument we had been parsing; this is done + * without any further processing of such abandoned text, assuming + * that the caller is equipped to handle it appropriately. + */ + nextchar = NULL; + } if( nextchar && *nextchar ) { |