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 + + 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_ */