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:02:40 +0000 (14:02 +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 a883a8f9465f5a8d5de1a630f02bd177a96d6657..039d5f863330b1adf6c3bc0817228d0c45f49a52 100755 (executable)
--- a/configure
+++ b/configure
@@ -21149,6 +21149,12 @@ esac
  ;;
 esac
 
+  case " $LIBOBJS " in
+  *" win32setlocale.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS win32setlocale.$ac_objext"
+ ;;
+esac
+
 
 cat >>confdefs.h <<\_ACEOF
 #define HAVE_SYMLINK 1
index 7ef9548a49b02af0dabccefa8f22bbdee66b16db..15a206b092f1f7947d0f576dd94233907a40bf20 100644 (file)
@@ -1369,6 +1369,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 1947ca3d010e46dc7270e3c105193f5dcb3e13ca..26ed62b0abfdf920539aceee580ed3852ce93ca6 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');