Skip to content

Commit 65e899b

Browse files
committed
Fix MinGW build, broken by my previous patch to add a setlocale() wrapper
on Windows. ecpglib doesn't link with libpgport, but picks and compiles the .c files it needs individually. To cope with that, move the setlocale() wrapper from chklocale.c to a separate setlocale.c file, and include that in ecpglib.
1 parent a88b6e4 commit 65e899b

File tree

6 files changed

+126
-110
lines changed

6 files changed

+126
-110
lines changed

configure

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21149,6 +21149,12 @@ esac
2114921149
;;
2115021150
esac
2115121151

21152+
case " $LIBOBJS " in
21153+
*" win32setlocale.$ac_objext "* ) ;;
21154+
*) LIBOBJS="$LIBOBJS win32setlocale.$ac_objext"
21155+
;;
21156+
esac
21157+
2115221158

2115321159
cat >>confdefs.h <<\_ACEOF
2115421160
#define HAVE_SYMLINK 1

configure.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,6 +1369,7 @@ if test "$PORTNAME" = "win32"; then
13691369
AC_LIBOBJ(open)
13701370
AC_LIBOBJ(win32env)
13711371
AC_LIBOBJ(win32error)
1372+
AC_LIBOBJ(win32setlocale)
13721373
AC_DEFINE([HAVE_SYMLINK], 1,
13731374
[Define to 1 if you have the `symlink' function.])
13741375
AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [

src/interfaces/ecpg/ecpglib/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ LIBS := $(filter-out -lpgport, $(LIBS))
2626

2727
OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
2828
connect.o misc.o path.o pgstrcasecmp.o \
29-
$(filter snprintf.o strlcpy.o, $(LIBOBJS))
29+
$(filter snprintf.o strlcpy.o win32setlocale.o, $(LIBOBJS))
3030

3131
# thread.c is needed only for non-WIN32 implementation of path.c
3232
ifneq ($(PORTNAME), win32)
@@ -57,7 +57,7 @@ include $(top_srcdir)/src/Makefile.shlib
5757
# necessarily use the same object files as the backend uses. Instead,
5858
# symlink the source files in here and build our own object file.
5959

60-
path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c: % : $(top_srcdir)/src/port/%
60+
path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c: % : $(top_srcdir)/src/port/%
6161
rm -f $@ && $(LN_S) $< .
6262

6363
misc.o: misc.c $(top_builddir)/src/port/pg_config_paths.h
@@ -74,6 +74,6 @@ uninstall: uninstall-lib
7474

7575
clean distclean: clean-lib
7676
rm -f $(OBJS)
77-
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c
77+
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c
7878

7979
maintainer-clean: distclean maintainer-clean-lib

src/port/chklocale.c

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -356,109 +356,3 @@ pg_get_encoding_from_locale(const char *ctype, bool write_message)
356356
}
357357

358358
#endif /* (HAVE_LANGINFO_H && CODESET) || WIN32 */
359-
360-
#ifdef WIN32
361-
/*
362-
* Windows has a problem with locale names that have a dot in the country
363-
* name. For example:
364-
*
365-
* "Chinese (Traditional)_Hong Kong S.A.R..950"
366-
*
367-
* For some reason, setlocale() doesn't accept that. Fortunately, Windows'
368-
* setlocale() accepts various alternative names for such countries, so we
369-
* provide a wrapper setlocale() function that maps the troublemaking locale
370-
* names to accepted aliases.
371-
*/
372-
373-
#undef setlocale
374-
375-
struct locale_map
376-
{
377-
const char *locale_name_part; /* string in locale name to replace */
378-
const char *replacement; /* string to replace it with */
379-
};
380-
381-
static const struct locale_map locale_map_list[] = {
382-
383-
/*
384-
* "HKG" is listed here:
385-
* http://msdn.microsoft.com/en-us/library/cdax410z%28v=vs.71%29.aspx
386-
* (Country/Region Strings).
387-
*
388-
* "ARE" is the ISO-3166 three-letter code for U.A.E. It is not on the
389-
* above list, but seems to work anyway.
390-
*/
391-
{ "Hong Kong S.A.R.", "HKG" },
392-
{ "U.A.E.", "ARE" },
393-
394-
/*
395-
* The ISO-3166 country code for Macau S.A.R. is MAC, but Windows doesn't
396-
* seem to recognize that. And Macau isn't listed in the table of
397-
* accepted abbreviations linked above. Fortunately, "ZHM" seems to be
398-
* accepted as an alias for "Chinese (Traditional)_Macau S.A.R..950". I'm
399-
* not sure where "ZHM" comes from, must be some legacy naming scheme. But
400-
* hey, it works.
401-
*
402-
* Note that unlike HKG and ARE, ZHM is an alias for the *whole* locale
403-
* name, not just the country part.
404-
*
405-
* Some versions of Windows spell it "Macau", others "Macao".
406-
*/
407-
{ "Chinese (Traditional)_Macau S.A.R..950", "ZHM" },
408-
{ "Chinese_Macau S.A.R..950", "ZHM" },
409-
{ "Chinese (Traditional)_Macao S.A.R..950", "ZHM" },
410-
{ "Chinese_Macao S.A.R..950", "ZHM" }
411-
};
412-
413-
char *
414-
pgwin32_setlocale(int category, const char *locale)
415-
{
416-
char *result;
417-
char *alias;
418-
int i;
419-
420-
if (locale == NULL)
421-
return setlocale(category, locale);
422-
423-
/* Check if the locale name matches any of the problematic ones. */
424-
alias = NULL;
425-
for (i = 0; i < lengthof(locale_map_list); i++)
426-
{
427-
const char *needle = locale_map_list[i].locale_name_part;
428-
const char *replacement = locale_map_list[i].replacement;
429-
char *match;
430-
431-
match = strstr(locale, needle);
432-
if (match != NULL)
433-
{
434-
/* Found a match. Replace the matched string. */
435-
int matchpos = match - locale;
436-
int replacementlen = strlen(replacement);
437-
char *rest = match + strlen(needle);
438-
int restlen = strlen(rest);
439-
440-
alias = malloc(matchpos + replacementlen + restlen + 1);
441-
if (!alias)
442-
return NULL;
443-
444-
memcpy(&alias[0], &locale[0], matchpos);
445-
memcpy(&alias[matchpos], replacement, replacementlen);
446-
memcpy(&alias[matchpos + replacementlen], rest, restlen + 1); /* includes null terminator */
447-
448-
break;
449-
}
450-
}
451-
452-
/* Call the real setlocale() function */
453-
if (alias)
454-
{
455-
result = setlocale(category, alias);
456-
free(alias);
457-
}
458-
else
459-
result = setlocale(category, locale);
460-
461-
return result;
462-
}
463-
464-
#endif /* WIN32 */

src/port/win32setlocale.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* win32setlocale.c
4+
* Wrapper to work around bugs in Windows setlocale() implementation
5+
*
6+
* Copyright (c) 2011, PostgreSQL Global Development Group
7+
*
8+
* IDENTIFICATION
9+
* src/port/win32setlocale.c
10+
*
11+
*
12+
* Windows has a problem with locale names that have a dot in the country
13+
* name. For example:
14+
*
15+
* "Chinese (Traditional)_Hong Kong S.A.R..950"
16+
*
17+
* For some reason, setlocale() doesn't accept that. Fortunately, Windows'
18+
* setlocale() accepts various alternative names for such countries, so we
19+
* provide a wrapper setlocale() function that maps the troublemaking locale
20+
* names to accepted aliases.
21+
*-------------------------------------------------------------------------
22+
*/
23+
24+
#include "c.h"
25+
26+
#undef setlocale
27+
28+
struct locale_map
29+
{
30+
const char *locale_name_part; /* string in locale name to replace */
31+
const char *replacement; /* string to replace it with */
32+
};
33+
34+
static const struct locale_map locale_map_list[] = {
35+
36+
/*
37+
* "HKG" is listed here:
38+
* http://msdn.microsoft.com/en-us/library/cdax410z%28v=vs.71%29.aspx
39+
* (Country/Region Strings).
40+
*
41+
* "ARE" is the ISO-3166 three-letter code for U.A.E. It is not on the
42+
* above list, but seems to work anyway.
43+
*/
44+
{ "Hong Kong S.A.R.", "HKG" },
45+
{ "U.A.E.", "ARE" },
46+
47+
/*
48+
* The ISO-3166 country code for Macau S.A.R. is MAC, but Windows doesn't
49+
* seem to recognize that. And Macau isn't listed in the table of
50+
* accepted abbreviations linked above. Fortunately, "ZHM" seems to be
51+
* accepted as an alias for "Chinese (Traditional)_Macau S.A.R..950". I'm
52+
* not sure where "ZHM" comes from, must be some legacy naming scheme. But
53+
* hey, it works.
54+
*
55+
* Note that unlike HKG and ARE, ZHM is an alias for the *whole* locale
56+
* name, not just the country part.
57+
*
58+
* Some versions of Windows spell it "Macau", others "Macao".
59+
*/
60+
{ "Chinese (Traditional)_Macau S.A.R..950", "ZHM" },
61+
{ "Chinese_Macau S.A.R..950", "ZHM" },
62+
{ "Chinese (Traditional)_Macao S.A.R..950", "ZHM" },
63+
{ "Chinese_Macao S.A.R..950", "ZHM" }
64+
};
65+
66+
char *
67+
pgwin32_setlocale(int category, const char *locale)
68+
{
69+
char *result;
70+
char *alias;
71+
int i;
72+
73+
if (locale == NULL)
74+
return setlocale(category, locale);
75+
76+
/* Check if the locale name matches any of the problematic ones. */
77+
alias = NULL;
78+
for (i = 0; i < lengthof(locale_map_list); i++)
79+
{
80+
const char *needle = locale_map_list[i].locale_name_part;
81+
const char *replacement = locale_map_list[i].replacement;
82+
char *match;
83+
84+
match = strstr(locale, needle);
85+
if (match != NULL)
86+
{
87+
/* Found a match. Replace the matched string. */
88+
int matchpos = match - locale;
89+
int replacementlen = strlen(replacement);
90+
char *rest = match + strlen(needle);
91+
int restlen = strlen(rest);
92+
93+
alias = malloc(matchpos + replacementlen + restlen + 1);
94+
if (!alias)
95+
return NULL;
96+
97+
memcpy(&alias[0], &locale[0], matchpos);
98+
memcpy(&alias[matchpos], replacement, replacementlen);
99+
memcpy(&alias[matchpos + replacementlen], rest, restlen + 1); /* includes null terminator */
100+
101+
break;
102+
}
103+
}
104+
105+
/* Call the real setlocale() function */
106+
if (alias)
107+
{
108+
result = setlocale(category, alias);
109+
free(alias);
110+
}
111+
else
112+
result = setlocale(category, locale);
113+
114+
return result;
115+
}

src/tools/msvc/Mkvcbuild.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ sub mkvcbuild
5353
snprintf.c strlcat.c strlcpy.c dirmod.c exec.c noblock.c path.c
5454
pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c
5555
sprompt.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c
56-
win32error.c);
56+
win32error.c win32setlocale.c);
5757

5858
$libpgport = $solution->AddProject('libpgport','lib','misc');
5959
$libpgport->AddDefine('FRONTEND');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy