OSDN Git Service

Fix MinGW-Bug [2445962]; (reported by Keishi Suenaga).
authorkeithmarshall <keithmarshall>
Sun, 4 Jan 2009 17:35:36 +0000 (17:35 +0000)
committerkeithmarshall <keithmarshall>
Sun, 4 Jan 2009 17:35:36 +0000 (17:35 +0000)
winsup/mingw/ChangeLog
winsup/mingw/include/getopt.h
winsup/mingw/mingwex/getopt.c

index 58fc95a..8fa373a 100644 (file)
@@ -1,3 +1,15 @@
+2009-01-04  Keith Marshall  <keithmarshall@users.sourceforge.net>
+
+       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.
+
 2008-12-31  Keith Marshall  <keithmarshall@users.sourceforge.net>
 
        Partial fix for MinGW-Bug [2457778]: (Reported by Sisyphus).
index 00cd547..a57d3f0 100644 (file)
@@ -45,6 +45,17 @@ extern char *optarg;         /* pointer to argument of current option  */
 
 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 081cc56..29753ca 100644 (file)
@@ -87,6 +87,14 @@ enum
 
 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 @@ int getopt_parse( int mode, getopt_std_args, ... )
   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 @@ int getopt_parse( int mode, getopt_std_args, ... )
      * 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;
   }