]> granicus.if.org Git - postgresql/commitdiff
Fix MinGW build, broken by my previous patch to add a setlocale() wrapper
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 1 Sep 2011 11:02:40 +0000 (14:02 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Thu, 1 Sep 2011 11:04:19 +0000 (14:04 +0300)
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.

configure
configure.in
src/interfaces/ecpg/ecpglib/Makefile
src/port/chklocale.c
src/port/win32setlocale.c [new file with mode: 0644]
src/tools/msvc/Mkvcbuild.pm

index 9084db34013e5d28fb902f0730e33b6b4c678deb..a5ff285a8dce1367da8fb5f9a0c1dea424bbb014 100755 (executable)
--- a/configure
+++ b/configure
@@ -21090,6 +21090,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32setlocale.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32setlocale.$ac_objext"
+ ;;
+esac
+
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_SYMLINK 1
index d8b7c9edb8c9988b38eb322d285e418d6c1a161a..126f841ea6260de7a9132e01720379c0526cb9df 100644 (file)
@@ -1374,6 +1374,7 @@ if test "$PORTNAME" = "win32"; then
   AC_LIBOBJ(open)
   AC_LIBOBJ(win32env)
   AC_LIBOBJ(win32error)
+  AC_LIBOBJ(win32setlocale)
   AC_DEFINE([HAVE_SYMLINK], 1,
             [Define to 1 if you have the `symlink' function.])
   AC_CHECK_TYPES(MINIDUMP_TYPE, [pgac_minidump_type=yes], [pgac_minidump_type=no], [
index cdf84c3b09c27cd53bacd43061e604d01645e3af..2b2ffb6207327fc068789e86d3e7b193e13c4f8d 100644 (file)
@@ -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 \
        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
 ifneq ($(PORTNAME), win32)
@@ -57,7 +57,7 @@ include $(top_srcdir)/src/Makefile.shlib
 # necessarily use the same object files as the backend uses. Instead,
 # 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) $< .
 
 misc.o: misc.c $(top_builddir)/src/port/pg_config_paths.h
@@ -74,6 +74,6 @@ uninstall: uninstall-lib
 
 clean distclean: clean-lib
        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
index cd911b84cee56a0ce33f762773f74e3a08cfd371..e4f3dc99e0e3e34c76c0804fa601a69cda1c3e32 100644 (file)
@@ -356,109 +356,3 @@ pg_get_encoding_from_locale(const char *ctype, bool write_message)
 }
 
 #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 */
diff --git a/src/port/win32setlocale.c b/src/port/win32setlocale.c
new file mode 100644 (file)
index 0000000..a301e76
--- /dev/null
@@ -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;
+}
index 1d10ee98e83122695538c29ada336653d4e7a5fc..61656e6d6eebe4a41a4ef7f1c656be6768b0275f 100644 (file)
@@ -53,7 +53,7 @@ sub mkvcbuild
       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
       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->AddDefine('FRONTEND');