Files
MSYS2-packages/libargp/libargp-optional-variables.patch
T

100 lines
3.6 KiB
Diff

Make optional variables work in a Windows DLL
Patch by Fedin Pavel
http://cygwin.com/ml/cygwin/2013-07/msg00337.html
diff -ru src/libargp-20110921.orig/gllib/argp.h src/libargp-20110921/gllib/argp.h
--- src/libargp-20110921.orig/gllib/argp.h 2011-09-23 03:31:26.000000000 +0500
+++ src/libargp-20110921/gllib/argp.h 2013-07-15 12:03:51.616647900 +0500
@@ -64,6 +64,18 @@
typedef int error_t;
# define __error_t_defined
#endif
+
+#ifndef DLL_EXPORT
+#ifdef __CYGWIN__
+#define __dllexport __declspec(dllexport)
+#endif
+#ifdef _WIN32
+#define __dllexport __declspec(dllexport)
+#endif
+#endif
+#ifndef __dllexport
+#define __dllexport
+#endif
#ifdef __cplusplus
extern "C" {
@@ -441,14 +453,14 @@
option --version is added (unless the ARGP_NO_HELP flag is used), which
will print this string followed by a newline and exit (unless the
ARGP_NO_EXIT flag is used). Overridden by ARGP_PROGRAM_VERSION_HOOK. */
-extern const char *argp_program_version;
+__dllexport extern const char *argp_program_version;
/* If defined or set by the user program to a non-zero value, then a default
option --version is added (unless the ARGP_NO_HELP flag is used), which
calls this function with a stream to print the version to and a pointer to
the current parsing state, and then exits (unless the ARGP_NO_EXIT flag is
used). This variable takes precedent over ARGP_PROGRAM_VERSION. */
-extern void (*argp_program_version_hook) (FILE *__restrict __stream,
+__dllexport extern void (*argp_program_version_hook) (FILE *__restrict __stream,
struct argp_state *__restrict
__state);
@@ -457,12 +469,12 @@
argp_help if the ARGP_HELP_BUG_ADDR flag is set (as it is by various
standard help messages), embedded in a sentence that says something like
`Report bugs to ADDR.'. */
-extern const char *argp_program_bug_address;
+__dllexport extern const char *argp_program_bug_address;
/* The exit status that argp will use when exiting due to a parsing error.
If not defined or set by the user program, this defaults to EX_USAGE from
<sysexits.h>. */
-extern error_t argp_err_exit_status;
+__dllexport extern error_t argp_err_exit_status;
/* Flags for argp_help. */
#define ARGP_HELP_USAGE 0x01 /* a Usage: message. */
diff -ru src/libargp-20110921.orig/gllib/argp-parse.c src/libargp-20110921/gllib/argp-parse.c
--- src/libargp-20110921.orig/gllib/argp-parse.c 2011-09-23 03:31:26.000000000 +0500
+++ src/libargp-20110921/gllib/argp-parse.c 2013-07-15 11:39:49.690236100 +0500
@@ -64,6 +64,36 @@
/* EZ alias for ARGP_ERR_UNKNOWN. */
#define EBADKEY ARGP_ERR_UNKNOWN
+/* Windows does not support things like weak symbols, neither it will merge two
+ external symbols. In order to make our optional variables working, we have
+ to do this trick. What we do here is looking up respective variables in
+ main .exe file and patching our versions with correct pointers
+ Note that the whole thing relies on these variables being declared with
+ __declspec(dllexport). */
+#ifdef DLL_EXPORT
+
+#include <windows.h>
+
+#define PatchPtr(var) \
+ p = (void **)GetProcAddress(NULL, #var); \
+ if (p) var = *p;
+
+#define PatchInt(var) \
+ i = (int *)GetProcAddress(NULL, #var); \
+ if (i) var = *i;
+
+static void __attribute__((constructor)) patch_vars(void)
+{
+ void **p;
+ int *i;
+
+ PatchPtr(argp_program_version);
+ PatchPtr(argp_program_version_hook);
+ PatchPtr(argp_program_bug_address);
+ PatchInt(argp_err_exit_status);
+}
+#endif
+
/* Default options. */
/* When argp is given the --HANG switch, _ARGP_HANG is set and argp will sleep