mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-09-07 09:39:19 +02:00
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.
This commit is contained in:
parent
83748f3a4e
commit
6952071450
6
configure
vendored
6
configure
vendored
@ -21090,6 +21090,12 @@ esac
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
case " $LIBOBJS " in
|
||||||
|
*" win32setlocale.$ac_objext "* ) ;;
|
||||||
|
*) LIBOBJS="$LIBOBJS win32setlocale.$ac_objext"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
|
||||||
cat >>confdefs.h <<\_ACEOF
|
cat >>confdefs.h <<\_ACEOF
|
||||||
#define HAVE_SYMLINK 1
|
#define HAVE_SYMLINK 1
|
||||||
|
@ -1374,6 +1374,7 @@ if test "$PORTNAME" = "win32"; then
|
|||||||
AC_LIBOBJ(open)
|
AC_LIBOBJ(open)
|
||||||
AC_LIBOBJ(win32env)
|
AC_LIBOBJ(win32env)
|
||||||
AC_LIBOBJ(win32error)
|
AC_LIBOBJ(win32error)
|
||||||
|
AC_LIBOBJ(win32setlocale)
|
||||||
AC_DEFINE([HAVE_SYMLINK], 1,
|
AC_DEFINE([HAVE_SYMLINK], 1,
|
||||||
[Define to 1 if you have the `symlink' function.])
|
[Define to 1 if you have the `symlink' function.])
|
||||||
AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [
|
AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [
|
||||||
|
@ -26,7 +26,7 @@ LIBS := $(filter-out -lpgport, $(LIBS))
|
|||||||
|
|
||||||
OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
|
OBJS= execute.o typename.o descriptor.o sqlda.o data.o error.o prepare.o memory.o \
|
||||||
connect.o misc.o path.o pgstrcasecmp.o \
|
connect.o misc.o path.o pgstrcasecmp.o \
|
||||||
$(filter snprintf.o strlcpy.o, $(LIBOBJS))
|
$(filter snprintf.o strlcpy.o win32setlocale.o, $(LIBOBJS))
|
||||||
|
|
||||||
# thread.c is needed only for non-WIN32 implementation of path.c
|
# thread.c is needed only for non-WIN32 implementation of path.c
|
||||||
ifneq ($(PORTNAME), win32)
|
ifneq ($(PORTNAME), win32)
|
||||||
@ -57,7 +57,7 @@ include $(top_srcdir)/src/Makefile.shlib
|
|||||||
# necessarily use the same object files as the backend uses. Instead,
|
# necessarily use the same object files as the backend uses. Instead,
|
||||||
# symlink the source files in here and build our own object file.
|
# symlink the source files in here and build our own object file.
|
||||||
|
|
||||||
path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c: % : $(top_srcdir)/src/port/%
|
path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c: % : $(top_srcdir)/src/port/%
|
||||||
rm -f $@ && $(LN_S) $< .
|
rm -f $@ && $(LN_S) $< .
|
||||||
|
|
||||||
misc.o: misc.c $(top_builddir)/src/port/pg_config_paths.h
|
misc.o: misc.c $(top_builddir)/src/port/pg_config_paths.h
|
||||||
@ -74,6 +74,6 @@ uninstall: uninstall-lib
|
|||||||
|
|
||||||
clean distclean: clean-lib
|
clean distclean: clean-lib
|
||||||
rm -f $(OBJS)
|
rm -f $(OBJS)
|
||||||
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c
|
rm -f path.c pgstrcasecmp.c snprintf.c strlcpy.c thread.c win32setlocale.c
|
||||||
|
|
||||||
maintainer-clean: distclean maintainer-clean-lib
|
maintainer-clean: distclean maintainer-clean-lib
|
||||||
|
@ -356,109 +356,3 @@ pg_get_encoding_from_locale(const char *ctype, bool write_message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif /* (HAVE_LANGINFO_H && CODESET) || WIN32 */
|
#endif /* (HAVE_LANGINFO_H && CODESET) || WIN32 */
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
/*
|
|
||||||
* Windows has a problem with locale names that have a dot in the country
|
|
||||||
* name. For example:
|
|
||||||
*
|
|
||||||
* "Chinese (Traditional)_Hong Kong S.A.R..950"
|
|
||||||
*
|
|
||||||
* For some reason, setlocale() doesn't accept that. Fortunately, Windows'
|
|
||||||
* setlocale() accepts various alternative names for such countries, so we
|
|
||||||
* provide a wrapper setlocale() function that maps the troublemaking locale
|
|
||||||
* names to accepted aliases.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#undef setlocale
|
|
||||||
|
|
||||||
struct locale_map
|
|
||||||
{
|
|
||||||
const char *locale_name_part; /* string in locale name to replace */
|
|
||||||
const char *replacement; /* string to replace it with */
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct locale_map locale_map_list[] = {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* "HKG" is listed here:
|
|
||||||
* http://msdn.microsoft.com/en-us/library/cdax410z%28v=vs.71%29.aspx
|
|
||||||
* (Country/Region Strings).
|
|
||||||
*
|
|
||||||
* "ARE" is the ISO-3166 three-letter code for U.A.E. It is not on the
|
|
||||||
* above list, but seems to work anyway.
|
|
||||||
*/
|
|
||||||
{ "Hong Kong S.A.R.", "HKG" },
|
|
||||||
{ "U.A.E.", "ARE" },
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The ISO-3166 country code for Macau S.A.R. is MAC, but Windows doesn't
|
|
||||||
* seem to recognize that. And Macau isn't listed in the table of
|
|
||||||
* accepted abbreviations linked above. Fortunately, "ZHM" seems to be
|
|
||||||
* accepted as an alias for "Chinese (Traditional)_Macau S.A.R..950". I'm
|
|
||||||
* not sure where "ZHM" comes from, must be some legacy naming scheme. But
|
|
||||||
* hey, it works.
|
|
||||||
*
|
|
||||||
* Note that unlike HKG and ARE, ZHM is an alias for the *whole* locale
|
|
||||||
* name, not just the country part.
|
|
||||||
*
|
|
||||||
* Some versions of Windows spell it "Macau", others "Macao".
|
|
||||||
*/
|
|
||||||
{ "Chinese (Traditional)_Macau S.A.R..950", "ZHM" },
|
|
||||||
{ "Chinese_Macau S.A.R..950", "ZHM" },
|
|
||||||
{ "Chinese (Traditional)_Macao S.A.R..950", "ZHM" },
|
|
||||||
{ "Chinese_Macao S.A.R..950", "ZHM" }
|
|
||||||
};
|
|
||||||
|
|
||||||
char *
|
|
||||||
pgwin32_setlocale(int category, const char *locale)
|
|
||||||
{
|
|
||||||
char *result;
|
|
||||||
char *alias;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (locale == NULL)
|
|
||||||
return setlocale(category, locale);
|
|
||||||
|
|
||||||
/* Check if the locale name matches any of the problematic ones. */
|
|
||||||
alias = NULL;
|
|
||||||
for (i = 0; i < lengthof(locale_map_list); i++)
|
|
||||||
{
|
|
||||||
const char *needle = locale_map_list[i].locale_name_part;
|
|
||||||
const char *replacement = locale_map_list[i].replacement;
|
|
||||||
char *match;
|
|
||||||
|
|
||||||
match = strstr(locale, needle);
|
|
||||||
if (match != NULL)
|
|
||||||
{
|
|
||||||
/* Found a match. Replace the matched string. */
|
|
||||||
int matchpos = match - locale;
|
|
||||||
int replacementlen = strlen(replacement);
|
|
||||||
char *rest = match + strlen(needle);
|
|
||||||
int restlen = strlen(rest);
|
|
||||||
|
|
||||||
alias = malloc(matchpos + replacementlen + restlen + 1);
|
|
||||||
if (!alias)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memcpy(&alias[0], &locale[0], matchpos);
|
|
||||||
memcpy(&alias[matchpos], replacement, replacementlen);
|
|
||||||
memcpy(&alias[matchpos + replacementlen], rest, restlen + 1); /* includes null terminator */
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Call the real setlocale() function */
|
|
||||||
if (alias)
|
|
||||||
{
|
|
||||||
result = setlocale(category, alias);
|
|
||||||
free(alias);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = setlocale(category, locale);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* WIN32 */
|
|
||||||
|
115
src/port/win32setlocale.c
Normal file
115
src/port/win32setlocale.c
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* win32setlocale.c
|
||||||
|
* Wrapper to work around bugs in Windows setlocale() implementation
|
||||||
|
*
|
||||||
|
* Copyright (c) 2011, PostgreSQL Global Development Group
|
||||||
|
*
|
||||||
|
* IDENTIFICATION
|
||||||
|
* src/port/win32setlocale.c
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Windows has a problem with locale names that have a dot in the country
|
||||||
|
* name. For example:
|
||||||
|
*
|
||||||
|
* "Chinese (Traditional)_Hong Kong S.A.R..950"
|
||||||
|
*
|
||||||
|
* For some reason, setlocale() doesn't accept that. Fortunately, Windows'
|
||||||
|
* setlocale() accepts various alternative names for such countries, so we
|
||||||
|
* provide a wrapper setlocale() function that maps the troublemaking locale
|
||||||
|
* names to accepted aliases.
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "c.h"
|
||||||
|
|
||||||
|
#undef setlocale
|
||||||
|
|
||||||
|
struct locale_map
|
||||||
|
{
|
||||||
|
const char *locale_name_part; /* string in locale name to replace */
|
||||||
|
const char *replacement; /* string to replace it with */
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct locale_map locale_map_list[] = {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* "HKG" is listed here:
|
||||||
|
* http://msdn.microsoft.com/en-us/library/cdax410z%28v=vs.71%29.aspx
|
||||||
|
* (Country/Region Strings).
|
||||||
|
*
|
||||||
|
* "ARE" is the ISO-3166 three-letter code for U.A.E. It is not on the
|
||||||
|
* above list, but seems to work anyway.
|
||||||
|
*/
|
||||||
|
{ "Hong Kong S.A.R.", "HKG" },
|
||||||
|
{ "U.A.E.", "ARE" },
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The ISO-3166 country code for Macau S.A.R. is MAC, but Windows doesn't
|
||||||
|
* seem to recognize that. And Macau isn't listed in the table of
|
||||||
|
* accepted abbreviations linked above. Fortunately, "ZHM" seems to be
|
||||||
|
* accepted as an alias for "Chinese (Traditional)_Macau S.A.R..950". I'm
|
||||||
|
* not sure where "ZHM" comes from, must be some legacy naming scheme. But
|
||||||
|
* hey, it works.
|
||||||
|
*
|
||||||
|
* Note that unlike HKG and ARE, ZHM is an alias for the *whole* locale
|
||||||
|
* name, not just the country part.
|
||||||
|
*
|
||||||
|
* Some versions of Windows spell it "Macau", others "Macao".
|
||||||
|
*/
|
||||||
|
{ "Chinese (Traditional)_Macau S.A.R..950", "ZHM" },
|
||||||
|
{ "Chinese_Macau S.A.R..950", "ZHM" },
|
||||||
|
{ "Chinese (Traditional)_Macao S.A.R..950", "ZHM" },
|
||||||
|
{ "Chinese_Macao S.A.R..950", "ZHM" }
|
||||||
|
};
|
||||||
|
|
||||||
|
char *
|
||||||
|
pgwin32_setlocale(int category, const char *locale)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
char *alias;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (locale == NULL)
|
||||||
|
return setlocale(category, locale);
|
||||||
|
|
||||||
|
/* Check if the locale name matches any of the problematic ones. */
|
||||||
|
alias = NULL;
|
||||||
|
for (i = 0; i < lengthof(locale_map_list); i++)
|
||||||
|
{
|
||||||
|
const char *needle = locale_map_list[i].locale_name_part;
|
||||||
|
const char *replacement = locale_map_list[i].replacement;
|
||||||
|
char *match;
|
||||||
|
|
||||||
|
match = strstr(locale, needle);
|
||||||
|
if (match != NULL)
|
||||||
|
{
|
||||||
|
/* Found a match. Replace the matched string. */
|
||||||
|
int matchpos = match - locale;
|
||||||
|
int replacementlen = strlen(replacement);
|
||||||
|
char *rest = match + strlen(needle);
|
||||||
|
int restlen = strlen(rest);
|
||||||
|
|
||||||
|
alias = malloc(matchpos + replacementlen + restlen + 1);
|
||||||
|
if (!alias)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
memcpy(&alias[0], &locale[0], matchpos);
|
||||||
|
memcpy(&alias[matchpos], replacement, replacementlen);
|
||||||
|
memcpy(&alias[matchpos + replacementlen], rest, restlen + 1); /* includes null terminator */
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call the real setlocale() function */
|
||||||
|
if (alias)
|
||||||
|
{
|
||||||
|
result = setlocale(category, alias);
|
||||||
|
free(alias);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = setlocale(category, locale);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
@ -53,7 +53,7 @@ sub mkvcbuild
|
|||||||
snprintf.c strlcat.c strlcpy.c dirmod.c exec.c noblock.c path.c
|
snprintf.c strlcat.c strlcpy.c dirmod.c exec.c noblock.c path.c
|
||||||
pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c
|
pgcheckdir.c pgmkdirp.c pgsleep.c pgstrcasecmp.c qsort.c qsort_arg.c
|
||||||
sprompt.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c
|
sprompt.c thread.c getopt.c getopt_long.c dirent.c rint.c win32env.c
|
||||||
win32error.c);
|
win32error.c win32setlocale.c);
|
||||||
|
|
||||||
$libpgport = $solution->AddProject('libpgport','lib','misc');
|
$libpgport = $solution->AddProject('libpgport','lib','misc');
|
||||||
$libpgport->AddDefine('FRONTEND');
|
$libpgport->AddDefine('FRONTEND');
|
||||||
|
Loading…
Reference in New Issue
Block a user