Additionally, there's a problem on mingw, when using --enable-shared:
The value of 'optind' that the main() program sees is always 1.

This patch fixes it.


2025-06-29  Bruno Haible  <br...@clisp.org>

        options: Support use in a shared library on mingw.
        * lib/options.h (_gl_get_next_option): New declaration.
        (get_next_option): On mingw, define in terms of _gl_get_next_option.
        * lib/options.c (_gl_get_next_option): On mingw, define this function
        instead of get_next_option.

diff --git a/lib/options.c b/lib/options.c
index f981613bf8..6ff6064698 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -121,7 +121,11 @@ _gl_start_options (int argc, char **argv,
 }
 
 int
+#ifdef __MINGW32__
+_gl_get_next_option (int *optind_p, char **optarg_p, int *optopt_p)
+#else
 get_next_option (void)
+#endif
 {
   if (state.argv == NULL)
     {
@@ -141,5 +145,19 @@ get_next_option (void)
               *(options[i].variable) = options[i].value;
           }
     }
+#ifdef __MINGW32__
+  /* On mingw, when this file is compiled into a shared library, it pulls
+     mingw's getopt.o file (that defines getopt_long, opterr, optind, optarg,
+     optopt) into the same shared library.  Since these variables are declared
+     and defined without any __declspec(dllexport) or __declspec(dllimport),
+     the effect is that there are two copies of the variables: one in the
+     shared library and one in the executable.  Upon return from this function,
+     we need to copy the values of the output variables (optind, optarg, 
optopt)
+     from the shared library into the executable, where the main() function 
will
+     pick them up.  */
+  *optind_p = optind;
+  *optarg_p = optarg;
+  *optopt_p = optopt;
+#endif
   return ret;
 }
diff --git a/lib/options.h b/lib/options.h
index 044cc73265..66d8710ca4 100644
--- a/lib/options.h
+++ b/lib/options.h
@@ -247,6 +247,10 @@ extern void _gl_start_options (int argc, /*const*/ char 
**argv,
    specified) ':'.
    If the processing is terminated, it returns -1.  */
 extern int get_next_option (void);
+#ifdef __MINGW32__
+extern int _gl_get_next_option (int *optind_p, char **optarg_p, int *optopt_p);
+# define get_next_option() _gl_get_next_option (&optind, &optarg, &optopt)
+#endif
 
 #ifdef __cplusplus
 }




Reply via email to