Index: backend/utils/adt/pg_locale.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v retrieving revision 1.43 diff -c -c -r1.43 pg_locale.c *** backend/utils/adt/pg_locale.c 1 Jan 2009 17:23:49 -0000 1.43 --- backend/utils/adt/pg_locale.c 8 Jan 2009 19:26:02 -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; + /* Refresh msgid pool maintained by gettext? */ + // textdomain(textdomain(NULL)); + #ifdef WIN32 + if (result = IsoLocaleName(locale), result == NULL) + return NULL; + #endif /* WIN32 */ break; #endif case LC_MONETARY: *************** *** 165,171 **** elog(FATAL, "unrecognized LC category: %d", category); envvar = NULL; /* keep compiler quiet */ envbuf = NULL; ! break; } snprintf(envbuf, LC_ENV_BUFSIZE - 1, "%s=%s", envvar, result); --- 180,186 ---- elog(FATAL, "unrecognized LC category: %d", category); envvar = NULL; /* keep compiler quiet */ envbuf = NULL; ! return NULL; } snprintf(envbuf, LC_ENV_BUFSIZE - 1, "%s=%s", envvar, result); *************** *** 181,189 **** */ if (!SetEnvironmentVariable(envvar, result)) return NULL; ! if (_putenv(envbuf)) ! return NULL; ! #endif return result; } --- 196,204 ---- */ if (!SetEnvironmentVariable(envvar, result)) return NULL; ! if (pg_putenv(envbuf)) ! result = NULL; ! #endif /* WIN32 */ return result; } *************** *** 214,219 **** --- 229,352 ---- 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 (putenvFunc == NULL) + { + if (hmodule = GetModuleHandle("msvcrt"), hmodule == NULL) + return 1; + putenvFunc = (PUTENVPROC) GetProcAddress(hmodule, "_putenv"); + if (putenvFunc == NULL) + return 1; + } + if (ret = putenvFunc(envval), ret != 0) + 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 ISO's one if possible. + * + * This function returns NULL if conversion is impossible + * and the format style isn't ISO, otherwise returns the + * ISO formatted locale name. + */ + static + char *IsoLocaleName(const char *winlocname) + { + #if (_MSC_VER >= 1400) /* VC8.0 or later */ + static char iso_lc_messages[32]; + int usecategory = LC_CTYPE; + _locale_t loct = NULL; + + if (stricmp("c", winlocname) == 0 || + stricmp("posix", winlocname) == 0) + { + strncpy(iso_lc_messages, "C", sizeof(iso_lc_messages)); + return iso_lc_messages; + } + + loct = _create_locale(usecategory, winlocname); + if (loct != NULL) + { + char isolang[32], isocrty[32]; + LCID lcid; + + lcid = loct->locinfo->lc_handle[usecategory]; + if (lcid == 0) + 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; + } + else /* ISO style check */ + { + int lclen; + char *dotp; + + if (dotp = strchr(winlocname, '.'), dotp != NULL) + lclen = dotp - winlocname; + else + lclen = strlen(winlocname); + switch (lclen) + { + case 2: + break; + case 5: + if (winlocname[2] != '_') + return NULL; + break; + default: + return NULL; + } + } + return winlocname; + #else + return winlocname; /* does nothing. */ + #endif /* _MSC_VER >= 1400 */ + } + #endif /* WIN32 */ + /* GUC assign hooks */ /* Index: backend/main/main.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/main/main.c,v retrieving revision 1.112 diff -c -c -r1.112 main.c *** backend/main/main.c 1 Jan 2009 17:23:43 -0000 1.112 --- backend/main/main.c 8 Jan 2009 19:26:03 -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: include/utils/pg_locale.h =================================================================== RCS file: /projects/cvsroot/pgsql/src/include/utils/pg_locale.h,v retrieving revision 1.27 diff -c -c -r1.27 pg_locale.h *** include/utils/pg_locale.h 1 Jan 2009 17:24:02 -0000 1.27 --- include/utils/pg_locale.h 8 Jan 2009 19:26:03 -0000 *************** *** 53,56 **** --- 53,58 ---- extern void cache_locale_time(void); + extern void pg_unsetenv(const char *); + #endif /* _PG_LOCALE_ */ Index: backend/utils/mb/mbutils.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/mb/mbutils.c,v retrieving revision 1.76 diff -c -c -r1.76 mbutils.c *** backend/utils/mb/mbutils.c 4 Jan 2009 18:37:35 -0000 1.76 --- backend/utils/mb/mbutils.c 8 Jan 2009 19:26:03 -0000 *************** *** 873,879 **** */ #ifdef ENABLE_NLS if (encoding == PG_UTF8) ! if (bind_textdomain_codeset("postgres", "UTF-8") == NULL) elog(LOG, "bind_textdomain_codeset failed"); #endif } --- 873,879 ---- */ #ifdef ENABLE_NLS if (encoding == PG_UTF8) ! if (bind_textdomain_codeset(textdomain(NULL), "UTF-8") == NULL) elog(LOG, "bind_textdomain_codeset failed"); #endif } Index: backend/utils/error/elog.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/error/elog.c,v retrieving revision 1.211 diff -c -c -r1.211 elog.c *** backend/utils/error/elog.c 7 Jan 2009 04:26:46 -0000 1.211 --- backend/utils/error/elog.c 8 Jan 2009 19:26:05 -0000 *************** *** 308,314 **** edata->lineno = lineno; edata->funcname = funcname; /* the default text domain is the backend's */ ! edata->domain = domain ? domain : "postgres"; /* Select default errcode based on elevel */ if (elevel >= ERROR) edata->sqlerrcode = ERRCODE_INTERNAL_ERROR; --- 308,314 ---- edata->lineno = lineno; edata->funcname = funcname; /* the default text domain is the backend's */ ! edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres"); /* Select default errcode based on elevel */ if (elevel >= ERROR) edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;