lol
1LD_PRELOAD by itself only works with Cygwin builtin functions, but
2textdomain() and friends come from libintl. In order to override
3those functions, we have to "replace" cygintl-?.dll since functions are
4bound to a DLL name at link time. Our replacement will be used since
5it is loaded first by LD_PRELOAD.
6
7But as we are making this *the* libintl, we need to provide
8pass-throughs for the other functions which we're not overriding,
9otherwise Locale::gettext won't load (not to mention the program
10that we're trying to help2man).
11
12--- help2man-1.46.5/Makefile.in 2014-10-09 13:03:01.000000000 +0200
13+++ help2man-1.46.5/Makefile.in 2015-05-12 14:46:52.995521900 +0200
14@@ -76,7 +76,8 @@
15 fi
16
17 install_preload: install_dirs preload
18- $(INSTALL_PROGRAM) $(preload).so $(DESTDIR)$(pkglibdir)
19+ $(INSTALL_PROGRAM) lib/cygintl-8.dll $(DESTDIR)$(pkglibdir)
20+ ln -sf cygintl-8.dll $(DESTDIR)$(pkglibdir)/$(preload).so
21
22 install_l10n: install_dirs msg_l10n man_l10n info_l10n
23 set -e; \
24@@ -144,7 +146,9 @@
25
26 preload: $(preload).so
27 $(preload).so: $(srcdir)/$(preload).c
28- $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ -fPIC -shared $? $(LIBS)
29+ mkdir -p lib
30+ $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o lib/cygintl-8.dll -shared $? $(LIBS)
31+ ln -sf lib/cygintl-8.dll $@
32
33 man: $(target).1
34 $(target).1: $(srcdir)/$(target).PL $(srcdir)/$(target).h2m.PL
35--- help2man-1.46.5/bindtextdomain.c 2009-11-13 00:01:34.000000000 -0600
36+++ help2man-1.46.5/bindtextdomain.c 2011-12-29 00:24:33.608078600 -0600
37@@ -27,12 +27,34 @@ static char *(*r_textdomain)(char const
38 static char *(*r_bindtextdomain)(char const *, char const *) = 0;
39 static char *(*r_bind_textdomain_codeset)(char const *, char const *) = 0;
40
41+#ifdef __CYGWIN__
42+static void *RTLD_NEXT = 0;
43+static char *(*r_gettext)(const char *) = 0;
44+static char *(*r_dgettext)(const char *, const char *) = 0;
45+static char *(*r_dcgettext)(const char *, const char *, int) = 0;
46+static char *(*r_ngettext)(const char *, const char *, unsigned long int) = 0;
47+static char *(*r_dngettext)(const char *, const char *, const char *,
48+ unsigned long int) = 0;
49+static char *(*r_dcngettext)(const char *, const char *, const char *,
50+ unsigned long int, int) = 0;
51+static char *(*r_setlocale)(int, const char *) = 0;
52+
53+#define SYM(sym) libintl_ ## sym
54+#else
55+#define SYM(sym) sym
56+#endif
57+
58 void setup()
59 {
60 static int done = 0;
61 if (done++)
62 return;
63
64+#ifdef __CYGWIN__
65+ if (!(RTLD_NEXT = dlopen("/usr/bin/cygintl-8.dll", RTLD_LAZY)))
66+ die("libintl8 not found");
67+#endif
68+
69 if (!(e_textdomain = getenv("TEXTDOMAIN")))
70 die("TEXTDOMAIN not set");
71
72@@ -48,9 +70,19 @@ void setup()
73 if (!(r_bind_textdomain_codeset = dlsym(RTLD_NEXT,
74 "bind_textdomain_codeset")))
75 die("can't find symbol \"bind_textdomain_codeset\"");
76+
77+#ifdef __CYGWIN__
78+ r_gettext = dlsym(RTLD_NEXT, "libintl_gettext");
79+ r_dgettext = dlsym(RTLD_NEXT, "libintl_dgettext");
80+ r_dcgettext = dlsym(RTLD_NEXT, "libintl_dcgettext");
81+ r_ngettext = dlsym(RTLD_NEXT, "libintl_ngettext");
82+ r_dngettext = dlsym(RTLD_NEXT, "libintl_dngettext");
83+ r_dcngettext = dlsym(RTLD_NEXT, "libintl_dcngettext");
84+ r_setlocale = dlsym(RTLD_NEXT, "libintl_setlocale");
85+#endif
86 }
87
88-char *textdomain(char const *domainname)
89+char *SYM(textdomain)(char const *domainname)
90 {
91 char *r;
92 setup();
93@@ -61,7 +93,7 @@ char *textdomain(char const *domainname)
94 return r;
95 }
96
97-char *bindtextdomain(char const *domainname, char const *dirname)
98+char *SYM(bindtextdomain)(char const *domainname, char const *dirname)
99 {
100 char const *dir = dirname;
101 setup();
102@@ -71,7 +103,7 @@ char *bindtextdomain(char const *domainn
103 return r_bindtextdomain(domainname, dir);
104 }
105
106-char *bind_textdomain_codeset(char const *domainname, char const *codeset)
107+char *SYM(bind_textdomain_codeset)(char const *domainname, char const *codeset)
108 {
109 char *r;
110 setup();
111@@ -81,3 +113,54 @@ char *bind_textdomain_codeset(char const
112
113 return r;
114 }
115+
116+#ifdef __CYGWIN__
117+
118+char *libintl_gettext(const char *msgid)
119+{
120+ setup();
121+ return r_gettext(msgid);
122+}
123+
124+char *libintl_dgettext (const char *domainname, const char *msgid)
125+{
126+ setup();
127+ return r_dgettext(domainname, msgid);
128+}
129+
130+char *libintl_dcgettext (const char *domainname, const char *msgid,
131+ int category)
132+{
133+ setup();
134+ return r_dcgettext (domainname, msgid, category);
135+}
136+
137+char *libintl_ngettext (const char *msgid1, const char *msgid2,
138+ unsigned long int n)
139+{
140+ setup();
141+ return r_ngettext (msgid1, msgid2, n);
142+}
143+
144+char *libintl_dngettext (const char *domainname, const char *msgid1,
145+ const char *msgid2, unsigned long int n)
146+{
147+ setup();
148+ return r_dngettext (domainname, msgid1, msgid2, n);
149+}
150+
151+char *libintl_dcngettext (const char *domainname,
152+ const char *msgid1, const char *msgid2,
153+ unsigned long int n, int category)
154+{
155+ setup();
156+ return r_dcngettext (domainname, msgid1, msgid2, n, category);
157+}
158+
159+char *libintl_setlocale (int i, const char *s)
160+{
161+ setup();
162+ return r_setlocale (i, s);
163+}
164+
165+#endif