From: SourceForge.net <no...@so...> - 2009-01-04 22:06:07
|
Bugs item #2445962, was opened at 2008-12-18 19:22 Message generated for change (Comment added) made by keithmarshall You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=2445962&group_id=2435 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: mingw runtime Group: None >Status: Closed >Resolution: Fixed Priority: 5 Private: No Submitted By: Keishi Suenaga (skeishi) Assigned to: Keith Marshall (keithmarshall) Summary: Mingw getopt reset bug. Initial Comment: Following code returns no response, with mingwrt-3.15.1-mingw32.tar.gz. Remove optind=0; line then it works fine ( returns "opt=U" ). Keishi Suenaga(sk...@ya...) ------------------------------------------------- #include <stdio.h> #include <getopt.h> int main(int argc, char **argv) { int opt; int c = 2; char *v[2] = { "opt", "-U" }; optind = 0; /* this is the line */ opt = getopt(c, v, "Uv"); printf("opt=%c \n", opt ); return 0; } ------------------------------------------------- If you need fllowing Infomation. Host Operating System Information and Version Microsoft Windows XP Professional x64 Edition Version 2003 Service Pack 2 GCC Version Using built-in specs. Target: mingw32 Configured with: ../gcc-4.3.0/configure --enable-languages=c,ada,c++,fortran,jav a,objc,obj-c++ --disable-sjlj-exceptions --enable-shared --enable-libgcj --enabl e-libgomp --with-dwarf2 --disable-win32-registry --enable-libstdcxx-debug --enab le-concept-checks --enable-version-specific-runtime-libs --build=mingw32 --with- bugurl=http://www.mingw.org/bugs.shtml --prefix=/mingw --with-gmp=/mingw/src/gcc /gmp-mpfr-root --with-mpfr=/mingw/src/gcc/gmp-mpfr-root --with-libiconv-prefix=/ mingw/src/gcc/libiconv-root Thread model: win32 gcc version 4.3.0 20080305 (alpha-testing) mingw-20080502 (GCC) Binutils Version GNU ld (GNU Binutils) 2.18.50.20080109 Build Environment uname -a MINGW32_NT-5.2 MEDAKA 1.0.11(0.46/3/2) 2008-08-25 23:40 i686 Msys ---------------------------------------------------------------------- >Comment By: Keith Marshall (keithmarshall) Date: 2009-01-04 22:03 Message: I committed this, which I believe fixes this issue: 2009-01-04 Keith Marshall <kei...@us...> Fix MinGW-Bug [2445962]; (reported by Keishi Suenaga). Also add tentative support for BSD specific `optreset' feature. * include/getopt.h (optreset) [_BSD_SOURCE]: Define; map it to... (__mingw_optreset): ...this new global variable. * mingwex/getopt.c (__mingw_optreset): Instantiate it... (getopt_parse) [optind < 1]: ...make it true; use it to reset argument parsing context. Index: include/getopt.h =================================================================== RCS file: /cvs/mingw/mingw/include/getopt.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- include/getopt.h 31 Aug 2008 22:27:58 -0000 1.3 +++ include/getopt.h 4 Jan 2009 17:35:36 -0000 1.4 @@ -45,6 +45,17 @@ extern int getopt( int, char * const [], const char * ); +#ifdef _BSD_SOURCE +/* + * BSD adds the non-standard `optreset' feature, for reinitialisation + * of `getopt' parsing. We support this feature, for applications which + * proclaim their BSD heritage, before including this header; however, + * to maintain portability, developers are advised to avoid it. + */ +# define optreset __mingw_optreset + +extern int optreset; +#endif #ifdef __cplusplus } #endif Index: mingwex/getopt.c =================================================================== RCS file: /cvs/mingw/mingw/mingwex/getopt.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- mingwex/getopt.c 3 Oct 2008 22:56:18 -0000 1.7 +++ mingwex/getopt.c 4 Jan 2009 17:35:36 -0000 1.8 @@ -87,6 +87,14 @@ int optopt = getopt_unknown; /* return value for option being evaluated */ +/* Some BSD applications expect to be able to reinitialise `getopt' parsing + * by setting a global variable called `optreset'. We provide an obfuscated + * API, which allows applications to emulate this brain damage; however, any + * use of this is non-portable, and is strongly discouraged. + */ +#define optreset __mingw_optreset +int optreset = 0; + static __inline__ int getopt_missing_arg( const CHAR *optstring ) { @@ -313,7 +321,7 @@ static const CHAR *nextchar = NULL; static int optmark = 0; - if( optind < optbase ) + if( (optreset |= (optind < 1)) || (optind < optbase) ) { /* POSIX does not prescribe any definitive mechanism for restarting * a `getopt' scan, but some applications may require such capability. @@ -325,7 +333,25 @@ * adjusting all of the internal placeholders to one less than the * adjusted `optind' value, (but never to less than zero). */ - optmark = optbase = argind = (optind > 0) ? optind - 1 : 0; + 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. + */ + optind = 1; + + /* We also need to clear the `optreset' request... + */ + optreset = 0; + } + + /* Now, we may safely reinitialise the internal placeholders, to + * one less than `optind', without fear of making them negative. + */ + optmark = optbase = argind = optind - 1; nextchar = NULL; } ---------------------------------------------------------------------- Comment By: Keith Marshall (keithmarshall) Date: 2008-12-19 16:50 Message: Thanks for the report. Your patch confirms that my own evaluation of the problem is correct. I introduced a potential infinite recursion, when I fixed bug 2144266; using `optbase' instead of `optind' for internal state fixed that, but overlooked the need to update `optind', to break an internal recursive call cycle, if the user sets `optind' to less than 1. Unfortunately, while your patch appears to break the cycle, my own analysis tells me it isn't sufficient to fix it completely -- in your test case, the `optind' reset action occurs in the second pass, rather than where it belongs, in the first; however, I do have my own alternative patch almost ready to commit. ---------------------------------------------------------------------- Comment By: Keishi Suenaga (skeishi) Date: 2008-12-19 01:12 Message: I made a patch. This works fine in my case. Keishi Suenaga(sk...@ya...) ------------------------------------------------------------------------- diff -c mingwrt-3.15.1-mingw32/mingwex/getopt.c.orig mingwrt-3.15.1-mingw32/mingwex/getopt.c *** mingwrt-3.15.1-mingw32/mingwex/getopt.c.orig Sun Oct 5 03:12:01 2008 --- mingwrt-3.15.1-mingw32/mingwex/getopt.c Fri Dec 19 09:47:02 2008 *************** *** 326,331 **** --- 326,332 ---- * adjusted `optind' value, (but never to less than zero). */ optmark = optbase = argind = (optind > 0) ? optind - 1 : 0; + if(optind <= 0) optind = 1; nextchar = NULL; } --------------------------------------------------------------------------- ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=102435&aid=2445962&group_id=2435 |