wincp.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:7k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * wincp.c: Guessing "local" ANSI code page on Microsoft Windows®
  3.  *****************************************************************************
  4.  *
  5.  * Copyright © 2006-2007 Rémi Denis-Courmont
  6.  * $Id: 7cbcd100cceebeafe4ccece94206a738198832ce $
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Lesser General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  * GNU General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Lesser General Public
  19.  * License along with this program; if not, write to the Free Software
  20.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  21.  *****************************************************************************/
  22. /*** We need your help to complete this file!! Look for FIXME ***/
  23. #ifdef HAVE_CONFIG_H
  24. # include "config.h"
  25. #endif
  26. #include <vlc_common.h>
  27. #ifndef WIN32
  28. # include <locale.h>
  29. #else
  30. # include <windows.h>
  31. #endif
  32. #ifdef __APPLE__
  33. #   include <errno.h>
  34. #   include <string.h>
  35. #endif
  36. #include <vlc_charset.h>
  37. #ifndef WIN32 /* should work on Win32, but useless */
  38. static inline int locale_match (const char *tab, const char *locale)
  39. {
  40.     for (;*tab; tab += 2)
  41.         if (memcmp (tab, locale, 2) == 0)
  42.             return 0;
  43.     return 1;
  44. }
  45. /**
  46.  * @return a fallback characters encoding to be used, given a locale.
  47.  */
  48. static const char *FindFallbackEncoding (const char *locale)
  49. {
  50.     if ((locale == NULL) || (strlen (locale) < 2)
  51.      || !strcasecmp (locale, "POSIX"))
  52.         return "CP1252"; /* Yeah, this is totally western-biased */
  53.     /*** The ISO-8859 series (anything but Asia) ***/
  54.     // Latin-1 Western-European languages (ISO-8859-1)
  55.     static const char western[] =
  56.         "aa" "af" "an" "br" "ca" "da" "de" "en" "es" "et" "eu" "fi" "fo" "fr"
  57.         "ga" "gd" "gl" "gv" "id" "is" "it" "kl" "kw" "mg" "ms" "nb" "nl" "nn"
  58.         "no" "oc" "om" "pt" "so" "sq" "st" "sv" "tl" "uz" "wa" "xh" "zu"
  59.         "eo" "mt" "cy";
  60.     if (!locale_match (western, locale))
  61.         return "CP1252"; // Compatible Microsoft superset
  62.     // Latin-2 Slavic languages (ISO-8859-2)
  63.     static const char slavic[] = "bs" "cs" "hr" "hu" "pl" "ro" "sk" "sl";
  64.     if (!locale_match (slavic, locale))
  65.         return "CP1250"; // CP1250 is more common, but incompatible
  66.     // Latin-3 Southern European languages (ISO-8859-3)
  67.     // "eo" and "mt" -> Latin-1 instead, I presume(?).
  68.     // "tr" -> ISO-8859-9 instead
  69.     // Latin-4 North-European languages (ISO-8859-4)
  70.     // -> Latin-1 instead
  71.     /* Cyrillic alphabet languages (ISO-8859-5) */
  72.     static const char cyrillic[] = "be" "bg" "mk" "ru" "sr";
  73.     if (!locale_match (cyrillic, locale))
  74.         return "CP1251"; // KOI8, ISO-8859-5 and CP1251 are incompatible(?)
  75.     /* Arabic (ISO-8859-6) */
  76.     if (!locale_match ("ar", locale))
  77.         // FIXME: someone check if we should return CP1256 or ISO-8859-6
  78.         return "CP1256"; // CP1256 is(?) more common, but incompatible(?)
  79.     /* Greek (ISO-8859-7) */
  80.     if (!locale_match ("el", locale))
  81.         // FIXME: someone check if we should return CP1253 or ISO-8859-7
  82.         return "CP1253"; // CP1253 is(?) more common and less incompatible
  83.     /* Hebrew (ISO-8859-8) */
  84.     if (!locale_match ("he" "iw" "yi", locale))
  85.         return "ISO-8859-8"; // CP1255 is reportedly screwed up
  86.     /* Latin-5 Turkish (ISO-8859-9) */
  87.     if (!locale_match ("tr" "ku", locale))
  88.         return "CP1254"; // Compatible Microsoft superset
  89.     /* Latin-6 “North-European” languages (ISO-8859-10) */
  90.     /* It is so much north European that glibc only uses that for Luganda
  91.      * which is spoken in Uganda... unless someone complains, I'm not
  92.      * using this one; let's fallback to CP1252 here. */
  93.     // ISO-8859-11 does arguably not exist. Thai is handled below.
  94.     // ISO-8859-12 really doesn't exist.
  95.     // Latin-7 Baltic languages (ISO-8859-13)
  96.     if (!locale_match ("lt" "lv" "mi", locale))
  97.         // FIXME: mi = New Zealand, doesn't sound baltic!
  98.         return "CP1257"; // Compatible Microsoft superset
  99.     // Latin-8 Celtic languages (ISO-8859-14)
  100.     // "cy" -> use Latin-1 instead (most likely English or French)
  101.     // Latin-9 (ISO-8859-15) -> see Latin-1
  102.     // Latin-10 (ISO-8859-16) does not seem to be used
  103.     /*** KOI series ***/
  104.     // For Russian, we use CP1251
  105.     if (!locale_match ("uk", locale))
  106.         return "KOI8-U";
  107.     if (!locale_match ("tg", locale))
  108.         return "KOI8-T";
  109.     /*** Asia ***/
  110.     // Japanese
  111.     if (!locale_match ("jp", locale))
  112.         return "SHIFT-JIS"; // Shift-JIS is way more common than EUC-JP
  113.     // Korean
  114.     if (!locale_match ("ko", locale))
  115.         return "CP949"; // Microsoft non-standard superset of EUC-KR
  116.     // Thai
  117.     if (!locale_match ("th", locale))
  118.         return "TIS-620";
  119.     // Vietnamese (FIXME: more infos needed)
  120.     if (!locale_match ("vt", locale))
  121.         /* VISCII is probably a bad idea as it is not extended ASCII */
  122.         /* glibc has TCVN5712-1 */
  123.         return "CP1258";
  124.     /* Kazakh (FIXME: more infos needed) */
  125.     if (!locale_match ("kk", locale))
  126.         return "PT154";
  127.     // Chinese. The politically incompatible character sets.
  128.     if (!locale_match ("zh", locale))
  129.     {
  130.         if ((strlen (locale) >= 5) && (locale[2] != '_'))
  131.             locale += 3;
  132.         // Hong Kong
  133.         if (!locale_match ("HK", locale))
  134.             return "BIG5-HKSCS"; /* FIXME: use something else? */
  135.         // Taiwan island
  136.         if (!locale_match ("TW", locale))
  137.             return "BIG5";
  138.         // People's Republic of China and Singapore
  139.         /*
  140.          * GB18030 can represent any Unicode code point
  141.          * (like UTF-8), while remaining compatible with GBK
  142.          * FIXME: is it compatible with GB2312? if not, should we
  143.          * use GB2312 instead?
  144.          */
  145.         return "GB18030";
  146.     }
  147.     return "ASCII";
  148. }
  149. #endif
  150. /**
  151.  * GetFallbackEncoding() suggests an encoding to be used for non UTF-8
  152.  * text files accord to the system's local settings. It is only a best
  153.  * guess.
  154.  */
  155. const char *GetFallbackEncoding( void )
  156. {
  157. #ifndef WIN32
  158.     const char *psz_lang;
  159.     psz_lang = getenv ("LC_ALL");
  160.     if ((psz_lang == NULL) || !*psz_lang)
  161.     {
  162.         psz_lang = getenv ("LC_CTYPE");
  163.         if ((psz_lang == NULL) || !*psz_lang)
  164.             psz_lang = getenv ("LANG");
  165.     }
  166.     return FindFallbackEncoding (psz_lang);
  167. #else
  168.     static char buf[16] = "";
  169.     if (buf[0] == 0)
  170.     {
  171.         int cp = GetACP ();
  172.         switch (cp)
  173.         {
  174.             case 1255: // Hebrew, CP1255 screws up somewhat
  175.                 strcpy (buf, "ISO-8859-8");
  176.                 break;
  177.             default:
  178.                 snprintf (buf, sizeof (buf), "CP%u", cp);
  179.         }
  180.     }
  181.     return buf;
  182. #endif
  183. }