Hiroshi Inoue wrote:
Magnus Hagander wrote:

Do you want to send an updated patch for it, or do you want me to look
at it?

I would send a new patch to which I added a simple ISO style check for
 locale names.

Attached is a new patch.
I added a simple ISO style locale name check.
Avoided codings like *NULL == somthing*.
It also includes the changes to mbutils.c and elog.c which fix
recently introduced bug by the domain name change from "postgres"
to "postgres-8.4".

regards,
Hiroshi Inoue


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;
-- 
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