]> granicus.if.org Git - postgresql/blobdiff - src/port/chklocale.c
Fix whitespace
[postgresql] / src / port / chklocale.c
index 6866353977ea6200c93d002d7d3b28c5c9df7099..3c9d7abcbd7fd580b5efa33ab602a89521c327a5 100644 (file)
@@ -4,11 +4,11 @@
  *             Functions for handling locale-related info
  *
  *
- * Copyright (c) 1996-2010, PostgreSQL Global Development Group
+ * Copyright (c) 1996-2013, PostgreSQL Global Development Group
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/port/chklocale.c,v 1.15 2010/02/26 02:01:38 momjian Exp $
+ *       src/port/chklocale.c
  *
  *-------------------------------------------------------------------------
  */
@@ -62,7 +62,7 @@ static const struct encoding_match encoding_match_list[] = {
        {PG_EUC_KR, "IBM-eucKR"},
        {PG_EUC_KR, "deckorean"},
        {PG_EUC_KR, "5601"},
-       {PG_EUC_KR, "CP51949"},         /* or 20949 ? */
+       {PG_EUC_KR, "CP51949"},
 
        {PG_EUC_TW, "EUC-TW"},
        {PG_EUC_TW, "eucTW"},
@@ -162,6 +162,7 @@ static const struct encoding_match encoding_match_list[] = {
        {PG_SJIS, "SJIS"},
        {PG_SJIS, "PCK"},
        {PG_SJIS, "CP932"},
+       {PG_SJIS, "SHIFT_JIS"},
 
        {PG_BIG5, "BIG5"},
        {PG_BIG5, "BIG5HKSCS"},
@@ -172,6 +173,7 @@ static const struct encoding_match encoding_match_list[] = {
        {PG_GBK, "CP936"},
 
        {PG_UHC, "UHC"},
+       {PG_UHC, "CP949"},
 
        {PG_JOHAB, "JOHAB"},
        {PG_JOHAB, "CP1361"},
@@ -188,29 +190,78 @@ static const struct encoding_match encoding_match_list[] = {
 
 #ifdef WIN32
 /*
- * On Windows, use CP<codepage number> instead of the nl_langinfo() result
+ * On Windows, use CP<code page number> instead of the nl_langinfo() result
+ *
+ * Visual Studio 2012 expanded the set of valid LC_CTYPE values, so have its
+ * locale machinery determine the code page.  See comments at IsoLocaleName().
+ * For other compilers, follow the locale's predictable format.
+ *
+ * Returns a malloc()'d string for the caller to free.
  */
 static char *
 win32_langinfo(const char *ctype)
 {
-       char       *r;
+       char       *r = NULL;
+
+#if (_MSC_VER >= 1700)
+       _locale_t       loct = NULL;
+
+       loct = _create_locale(LC_CTYPE, ctype);
+       if (loct != NULL)
+       {
+               r = malloc(16);                 /* excess */
+               if (r != NULL)
+                       sprintf(r, "CP%u", loct->locinfo->lc_codepage);
+               _free_locale(loct);
+       }
+#else
        char       *codepage;
-       int                     ln;
 
        /*
         * Locale format on Win32 is <Language>_<Country>.<CodePage> . For
-        * example, English_USA.1252.
+        * example, English_United States.1252.
         */
        codepage = strrchr(ctype, '.');
-       if (!codepage)
-               return NULL;
-       codepage++;
-       ln = strlen(codepage);
-       r = malloc(ln + 3);
-       sprintf(r, "CP%s", codepage);
+       if (codepage != NULL)
+       {
+               int                     ln;
+
+               codepage++;
+               ln = strlen(codepage);
+               r = malloc(ln + 3);
+               if (r != NULL)
+                       sprintf(r, "CP%s", codepage);
+       }
+#endif
 
        return r;
 }
+
+#ifndef FRONTEND
+/*
+ * Given a Windows code page identifier, find the corresponding PostgreSQL
+ * encoding.  Issue a warning and return -1 if none found.
+ */
+int
+pg_codepage_to_encoding(UINT cp)
+{
+       char            sys[16];
+       int                     i;
+
+       sprintf(sys, "CP%u", cp);
+
+       /* Check the table */
+       for (i = 0; encoding_match_list[i].system_enc_name; i++)
+               if (pg_strcasecmp(sys, encoding_match_list[i].system_enc_name) == 0)
+                       return encoding_match_list[i].pg_enc_code;
+
+       ereport(WARNING,
+                       (errmsg("could not determine encoding for codeset \"%s\"", sys),
+                  errdetail("Please report this to <pgsql-bugs@postgresql.org>.")));
+
+       return -1;
+}
+#endif
 #endif   /* WIN32 */
 
 #if (defined(HAVE_LANGINFO_H) && defined(CODESET)) || defined(WIN32)
@@ -224,9 +275,12 @@ win32_langinfo(const char *ctype)
  *
  * If the result is PG_SQL_ASCII, callers should treat it as being compatible
  * with any desired encoding.
+ *
+ * If running in the backend and write_message is false, this function must
+ * cope with the possibility that elog() and palloc() are not yet usable.
  */
 int
-pg_get_encoding_from_locale(const char *ctype)
+pg_get_encoding_from_locale(const char *ctype, bool write_message)
 {
        char       *sys;
        int                     i;
@@ -321,17 +375,20 @@ pg_get_encoding_from_locale(const char *ctype)
         * We print a warning if we got a CODESET string but couldn't recognize
         * it.  This means we need another entry in the table.
         */
+       if (write_message)
+       {
 #ifdef FRONTEND
-       fprintf(stderr, _("could not determine encoding for locale \"%s\": codeset is \"%s\""),
-                       ctype, sys);
-       /* keep newline separate so there's only one translatable string */
-       fputc('\n', stderr);
+               fprintf(stderr, _("could not determine encoding for locale \"%s\": codeset is \"%s\""),
+                               ctype, sys);
+               /* keep newline separate so there's only one translatable string */
+               fputc('\n', stderr);
 #else
-       ereport(WARNING,
-                       (errmsg("could not determine encoding for locale \"%s\": codeset is \"%s\"",
-                                       ctype, sys),
+               ereport(WARNING,
+                               (errmsg("could not determine encoding for locale \"%s\": codeset is \"%s\"",
+                                               ctype, sys),
                   errdetail("Please report this to <pgsql-bugs@postgresql.org>.")));
 #endif
+       }
 
        free(sys);
        return -1;
@@ -339,14 +396,14 @@ pg_get_encoding_from_locale(const char *ctype)
 #else                                                  /* (HAVE_LANGINFO_H && CODESET) || WIN32 */
 
 /*
- * stub if no platform support
+ * stub if no multi-language platform support
  *
  * Note: we could return -1 here, but that would have the effect of
  * forcing users to specify an encoding to initdb on such platforms.
  * It seems better to silently default to SQL_ASCII.
  */
 int
-pg_get_encoding_from_locale(const char *ctype)
+pg_get_encoding_from_locale(const char *ctype, bool write_message)
 {
        return PG_SQL_ASCII;
 }