Re: [BUGS] BUG #4186: set lc_messages does not work

Поиск
Список
Период
Сортировка
От Hiroshi Inoue
Тема Re: [BUGS] BUG #4186: set lc_messages does not work
Дата
Msg-id 4954F114.8010206@tpf.co.jp
обсуждение исходный текст
Ответ на Re: [BUGS] BUG #4186: set lc_messages does not work  (Hiroshi Inoue <inoue@tpf.co.jp>)
Ответы Re: [BUGS] BUG #4186: set lc_messages does not work  (Magnus Hagander <magnus@hagander.net>)
Список 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 по дате отправления:

Предыдущее
От: Hiroshi Inoue
Дата:
Сообщение: Re: [BUGS] BUG #4186: set lc_messages does not work
Следующее
От: "Kevin Grittner"
Дата:
Сообщение: Re: incoherent view of serializable transactions