Oops, I forgot to attach the patch, sorry.

Hiroshi Inoue wrote:
Hi,

I posted a patch 18 days ago but have got no responce.
Anyway I've simplified the patch by using an appropriate
 gettext module.

Hiroshi Inoue wrote:
Bruce Momjian wrote:
Tom Lane wrote:
Magnus Hagander <mag...@hagander.net> writes:
Thomas H. wrote:
so at least that explains the "changed" behaviour. nevertheless, LC_MESSAGES seems to be defunct - with the "locale" folder present,
pg always picks the os' language and ignores the lc_message value.
This looks like I can reproduce though, at least on cvs head. Did this
work for you in previous versions?
Maybe we were using a different build of gettext in the previous
releases, one that didn't look at the same info as the current code?


Where are we on this?

AFAICS there are 2 causes.

1. MSVC version of postgres is using a bad gettext module.
2. getenv() in mingw cannot see the result of putenv() in MSVC8.0.

As for 1, we have to use another gettext module. I can provide it
if requested.
As for 2, pg_putenv() or pg_unsetenv() in the attachced patch calls corresponding putenv() whose result can be referenced by getenv() in
 mingw.

In addtion the patch provides a functionality to Windows locale
name to ISO formatted locale name.

Comments ?

regards,
Hiroshi Inoue
Index: backend/main/main.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/main/main.c,v
retrieving revision 1.111
diff -c -c -r1.111 main.c
*** backend/main/main.c 11 Dec 2008 07:34:07 -0000      1.111
--- backend/main/main.c 26 Dec 2008 11:54:30 -0000
***************
*** 132,138 ****
         * environment, remove any LC_ALL setting, so that the environment
         * variables installed by pg_perm_setlocale have force.
         */
!       unsetenv("LC_ALL");
  
        /*
         * Catch standard options before doing much else
--- 132,138 ----
         * environment, remove any LC_ALL setting, so that the environment
         * variables installed by pg_perm_setlocale have force.
         */
!       pg_unsetenv("LC_ALL");
  
        /*
         * Catch standard options before doing much else
Index: backend/utils/adt/pg_locale.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v
retrieving revision 1.42
diff -c -c -r1.42 pg_locale.c
*** backend/utils/adt/pg_locale.c       23 Sep 2008 09:20:36 -0000      1.42
--- backend/utils/adt/pg_locale.c       26 Dec 2008 11:54:31 -0000
***************
*** 88,93 ****
--- 88,102 ----
  static char lc_numeric_envbuf[LC_ENV_BUFSIZE];
  static char lc_time_envbuf[LC_ENV_BUFSIZE];
  
+ /*    
+  *    The following 2 functions are ajusted ones for Windows MSVC. 
+  */
+ static int pg_putenv(const char *);   /* putenv() adjusted for MSVC */
+ extern void pg_unsetenv(const char *);        /* unsetenv() adjusted for MSVC 
*/
+ /*    The following function is available under MSVC8.0 or later */
+ #ifdef WIN32
+ static char *IsoLocaleName(const char *); /* MSVC specific */
+ #endif
  
  /*
   * pg_perm_setlocale
***************
*** 147,152 ****
--- 156,167 ----
                case LC_MESSAGES:
                        envvar = "LC_MESSAGES";
                        envbuf = lc_messages_envbuf;
+ #ifdef WIN32
+                       if (result = IsoLocaleName(locale), NULL == result)
+                               result = locale;
+ #endif /* WIN32 */
                        break;
  #endif
                case LC_MONETARY:
***************
*** 165,170 ****
--- 180,186 ----
                        elog(FATAL, "unrecognized LC category: %d", category);
                        envvar = NULL;          /* keep compiler quiet */
                        envbuf = NULL;
+                       return NULL;
                        break;
        }
  
***************
*** 181,189 ****
         */
        if (!SetEnvironmentVariable(envvar, result))
                return NULL;
!       if (_putenv(envbuf))
!               return NULL;
! #endif
  
        return result;
  }
--- 197,205 ----
         */
        if (!SetEnvironmentVariable(envvar, result))
                return NULL;
!       if (pg_putenv(envbuf))
!               result = NULL;
! #endif /* WIN32 */
  
        return result;
  }
***************
*** 214,219 ****
--- 230,335 ----
        return ret;
  }
  
+ /*
+  *    Ajusted version of putenv() for MSVC.
+  */
+ static
+ int pg_putenv(const char *envval)
+ {
+ #if defined(_MSC_VER) && (_MSC_VER >= 1300) /* VC7.0 or later */
+ /*
+  *    Each MSVC version has its own _putenv() in its runtime library
+  *    msvcrXX.dll. So we have to call _putenv() in msvcrt.dll so as
+  *    to be referenced by GnuWin32 library. 
+  */
+       typedef int (_cdecl *PUTENVPROC)(const char *);
+       HMODULE hmodule;
+       static PUTENVPROC       putenvFunc = NULL;
+       int     ret;
+       
+       if (NULL == putenvFunc)
+       {
+               if (hmodule = GetModuleHandle("msvcrt"), NULL == hmodule)
+                       return 1;
+               putenvFunc = (PUTENVPROC)GetProcAddress(hmodule, "_putenv");
+       }
+       if (NULL == putenvFunc)
+               return 1;
+       if (ret = putenvFunc(envval), 0 != ret)
+               return ret;
+ #endif /* _MSC_VER >= 1300 */
+       return putenv(envval);
+ }
+ 
+ /*
+  *    Adjusted version of unsetenv() for MSVC. 
+  */
+ void pg_unsetenv(const char *name)
+ {
+ #ifdef        WIN32
+       char *envbuf;
+ 
+       if (envbuf = (char *) malloc(strlen(name) + 2))
+       {
+               sprintf(envbuf, "%s=", name);
+               pg_putenv(envbuf);
+               free(envbuf);
+       }
+ #else
+       unsetenv(name);
+ #endif /* WIN32 */
+ }
+ 
+ #ifdef WIN32
+ /*
+  *    Convert Windows locale name to the IS formatted  one
+  *    if possible.
+  *
+  *    This function returns NULL if conversion is impossible,
+  *    otherwise returns the pointer to a static area which
+  *    contains the iso formatted locale name.
+  */
+ 
+ static
+ char *IsoLocaleName(const char *winlocname)
+ {
+ #if (_MSC_VER >= 1400) /* VC8.0 or later */
+ #include <shlwapi.h>
+ 
+       static char iso_lc_messages[32];
+       int             usecategory = LC_CTYPE;
+       _locale_t       loct = NULL;
+ 
+       if (0 == stricmp("c", winlocname) ||
+           0 == stricmp("posix", winlocname))
+       {
+               strncpy(iso_lc_messages, "C", sizeof(iso_lc_messages));
+               return iso_lc_messages;
+       }
+ 
+       loct = _create_locale(usecategory, winlocname);
+       if (NULL != loct)
+       {
+               char    isolang[32], isocrty[32];
+               LCID    lcid;
+ 
+               lcid = loct->locinfo->lc_handle[usecategory];
+               if (0 == lcid)
+                       lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, 
SUBLANG_ENGLISH_US), SORT_DEFAULT);
+               _free_locale(loct);
+ 
+ 
+               GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, isolang, 
sizeof(isolang));
+               GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, isocrty, 
sizeof(isocrty));
+               snprintf(iso_lc_messages, sizeof(iso_lc_messages) - 1, "%s_%s", 
isolang, isocrty);
+               return iso_lc_messages;
+       }
+       return NULL;
+ #else
+       return NULL; /* does nothing. */
+ #endif /* _MSC_VER >= 1400 */
+ }
+ #endif /* WIN32 */
+ 
  /* GUC assign hooks */
  
  /*
Index: include/utils/pg_locale.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/pg_locale.h,v
retrieving revision 1.26
diff -c -c -r1.26 pg_locale.h
*** include/utils/pg_locale.h   23 Sep 2008 09:20:39 -0000      1.26
--- include/utils/pg_locale.h   26 Dec 2008 11:54:34 -0000
***************
*** 53,56 ****
--- 53,58 ----
  
  extern void cache_locale_time(void);
  
+ extern void pg_unsetenv(const char *);
+ 
  #endif   /* _PG_LOCALE_ */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to