Re: [BUGS] BUG #4186: set lc_messages does not work - Mailing list pgsql-hackers
From | Hiroshi Inoue |
---|---|
Subject | Re: [BUGS] BUG #4186: set lc_messages does not work |
Date | |
Msg-id | 4954F114.8010206@tpf.co.jp Whole thread Raw |
In response to | Re: [BUGS] BUG #4186: set lc_messages does not work (Hiroshi Inoue <inoue@tpf.co.jp>) |
Responses |
Re: [BUGS] BUG #4186: set lc_messages does not work
|
List | pgsql-hackers |
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 <magnus@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_ */
pgsql-hackers by date: