⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c_locale_win32.c

📁 使用QT为linux 下的mplayer写的一个新的gui
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Copyright (c) 1999
 * Silicon Graphics Computer Systems, Inc.
 *
 * Copyright (c) 1999
 * Boris Fomitchev
 *
 * Written 2000
 * Anton Lapach
 *
 * This material is provided "as is", with absolutely no warranty expressed
 * or implied. Any use is at your own risk.
 *
 * Permission to use or copy this software for any purpose is hereby granted
 * without fee, provided the above notices are retained on all copies.
 * Permission to modify the code and to distribute modified code is granted,
 * provided the above notices are retained, and a notice that the code was
 * modified is included with the above copyright notice.
 *
 */

#include <windows.h>
#include <limits.h>
#if defined (_STLP_MSVC) || defined (__ICL)
#  include <memory.h>
#endif
#include <string.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>

#if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
#  define _STLP_STRCPY(D, S) strcpy_s(_STLP_ARRAY_AND_SIZE(D), S)
#  define _STLP_STRCPY2(D, DS, S) strcpy_s(D, DS, S)
#  define _STLP_RETURN_STRCPY2(D, DS, S) strcpy_s(D, DS, S); return D
#  define _STLP_STRNCPY(D, DS, S, C) strncpy_s(D, DS, S, C)
#  define _STLP_STRCAT(D, S) strcat_s(_STLP_ARRAY_AND_SIZE(D), S)
#  define _STLP_STRCAT2(D, DS, S) strcat_s(D, DS, S)
#  if !defined (_STLP_NO_WCHAR_T)
#    define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C)
#  endif
#else
#  define _STLP_STRCPY(D, S) strcpy(D, S)
#  define _STLP_STRCPY2(D, DS, S) strcpy(D, S)
#  define _STLP_RETURN_STRCPY2(D, DS, S) return strcpy(D, S)
#  define _STLP_STRNCPY(D, DS, S, C) strncpy(D, S, C)
#  define _STLP_STRCAT(D, S) strcat(D, S)
#  define _STLP_STRCAT2(D, DS, S) strcat(D, S)
#  if !defined (_STLP_NO_WCHAR_T)
#    define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C)
#  endif
#endif

#if defined (__cplusplus)
extern "C" {
#endif

/* Framework functions */
/*
  locale :: "lang[_country[.code_page]]"
  | ".code_page"
  | ""
  | NULL

*/

#if !defined (_LEADBYTE)
/* multibyte leadbyte */
#  define _LEADBYTE 0x8000
#endif

typedef struct _LOCALECONV {
  const char* name;
  const char* abbrev;
} LOCALECONV;

#define MAX_LANG_LEN        64  /* max language name length */
#define MAX_CTRY_LEN        64  /* max country name length */
#define MAX_MODIFIER_LEN    0   /* max modifier name length - n/a */
#define MAX_LC_LEN          (MAX_LANG_LEN+MAX_CTRY_LEN+MAX_MODIFIER_LEN+3)
                                /* max entire locale string length */
#define MAX_CP_LEN          5   /* max code page name length */


/* Metrowerks has different define here */
#if !defined (LC_MAX)
#  if defined (LC_LAST)
#    define LC_MAX LC_LAST
#  endif
#endif

/*  non-NLS language string table */
static LOCALECONV __rg_language[] = {
  {"american",                    "ENU"},
  {"american english",            "ENU"},
  {"american-english",            "ENU"},
  {"australian",                  "ENA"},
  {"belgian",                     "NLB"},
  {"canadian",                    "ENC"},
  {"chh",                         "ZHH"},
  {"chi",                         "ZHI"},
  {"chinese",                     "CHS"},
  {"chinese-hongkong",            "ZHH"},
  {"chinese-simplified",          "CHS"},
  {"chinese-singapore",           "ZHI"},
  {"chinese-traditional",         "CHT"},
  {"dutch-belgian",               "NLB"},
  {"english-american",            "ENU"},
  {"english-aus",                 "ENA"},
  {"english-belize",              "ENL"},
  {"english-can",                 "ENC"},
  {"english-caribbean",           "ENB"},
  {"english-ire",                 "ENI"},
  {"english-jamaica",             "ENJ"},
  {"english-nz",                  "ENZ"},
  {"english-south africa",        "ENS"},
  {"english-trinidad y tobago",   "ENT"},
  {"english-uk",                  "ENG"},
  {"english-us",                  "ENU"},
  {"english-usa",                 "ENU"},
  {"french-belgian",              "FRB"},
  {"french-canadian",             "FRC"},
  {"french-luxembourg",           "FRL"},
  {"french-swiss",                "FRS"},
  {"german-austrian",             "DEA"},
  {"german-lichtenstein",         "DEC"},
  {"german-luxembourg",           "DEL"},
  {"german-swiss",                "DES"},
  {"irish-english",               "ENI"},
  {"italian-swiss",               "ITS"},
  {"norwegian",                   "NOR"},
  {"norwegian-bokmal",            "NOR"},
  {"norwegian-nynorsk",           "NON"},
  {"portuguese-brazilian",        "PTB"},
  {"spanish-argentina",           "ESS"},
  {"spanish-bolivia",             "ESB"},
  {"spanish-chile",               "ESL"},
  {"spanish-colombia",            "ESO"},
  {"spanish-costa rica",          "ESC"},
  {"spanish-dominican republic",  "ESD"},
  {"spanish-ecuador",             "ESF"},
  {"spanish-el salvador",         "ESE"},
  {"spanish-guatemala",           "ESG"},
  {"spanish-honduras",            "ESH"},
  {"spanish-mexican",             "ESM"},
  {"spanish-modern",              "ESN"},
  {"spanish-nicaragua",           "ESI"},
  {"spanish-panama",              "ESA"},
  {"spanish-paraguay",            "ESZ"},
  {"spanish-peru",                "ESR"},
  {"spanish-puerto rico",         "ESU"},
  {"spanish-uruguay",             "ESY"},
  {"spanish-venezuela",           "ESV"},
  {"swedish-finland",             "SVF"},
  {"swiss",                       "DES"},
  {"uk",                          "ENG"},
  {"us",                          "ENU"},
  {"usa",                         "ENU"}
};

/*  non-NLS country string table */
static LOCALECONV __rg_country[] = {
  {"america",                     "USA"},
  {"britain",                     "GBR"},
  {"china",                       "CHN"},
  {"czech",                       "CZE"},
  {"england",                     "GBR"},
  {"great britain",               "GBR"},
  {"holland",                     "NLD"},
  {"hong-kong",                   "HKG"},
  {"new-zealand",                 "NZL"},
  {"nz",                          "NZL"},
  {"pr china",                    "CHN"},
  {"pr-china",                    "CHN"},
  {"puerto-rico",                 "PRI"},
  {"slovak",                      "SVK"},
  {"south africa",                "ZAF"},
  {"south korea",                 "KOR"},
  {"south-africa",                "ZAF"},
  {"south-korea",                 "KOR"},
  {"trinidad & tobago",           "TTO"},
  {"uk",                          "GBR"},
  {"united-kingdom",              "GBR"},
  {"united-states",               "USA"},
  {"us",                          "USA"},
};

typedef struct _Locale_name_hint {
  LCID id;
} _Locale_lcid_t;

typedef struct _Locale_ctype {
  _Locale_lcid_t lc;
  UINT cp;
  unsigned int ctable[256];
} _Locale_ctype_t;

typedef struct _Locale_numeric {
  _Locale_lcid_t lc;
  char cp[MAX_CP_LEN + 1];
  char decimal_point[4];
  char thousands_sep[4];
  char *grouping;
} _Locale_numeric_t;

typedef struct _Locale_time {
  _Locale_lcid_t lc;
  char cp[MAX_CP_LEN + 1];
  char *month[12];
  char *abbrev_month[12];
  char *dayofweek[7];
  char *abbrev_dayofweek[7];
  char *date_time_format;
  char *long_date_time_format;
  char *date_format;
  char *long_date_format;
  char *time_format;
  char am[9];
  char pm[9];
} _Locale_time_t;

typedef struct _Locale_collate {
  _Locale_lcid_t lc;
  char cp[MAX_CP_LEN + 1];
} _Locale_collate_t;

typedef struct _Locale_monetary {
  _Locale_lcid_t lc;
  char cp[MAX_CP_LEN + 1];
  char decimal_point[4];
  char thousands_sep[4];
  char *grouping;
  char int_curr_symbol[5]; /* 3 + 1 + 1 */
  char curr_symbol[6];
  char negative_sign[5];
  char positive_sign[5];
  int frac_digits;
  int int_frac_digits;
} _Locale_monetary_t;

typedef struct _Locale_messages {
  _Locale_lcid_t lc;
  char cp[MAX_CP_LEN + 1];
} _Locale_messages_t;

/* Internal function */
static void __FixGrouping(char *grouping);
static const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize);
static int __ParseLocaleString(const char* lname, char* lang, char* ctry, char* page);
static int __GetLCID(const char* lang, const char* ctry, LCID* lcid);
static int __GetLCIDFromName(const char* lname, LCID* lcid, char *cp, _Locale_lcid_t *hint);
static char const* __GetLocaleName(LCID lcid, const char* cp, char* buf);
static char const* __Extract_locale_name(const char* loc, int category, char* buf);
static char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint);
static void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size);
static int __intGetACP(LCID lcid);
static int __intGetOCP(LCID lcid);
static int __GetDefaultCP(LCID lcid);
static char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size);
static void my_ltoa(long __x, char* buf);

void my_ltoa(long __x, char* buf) {
  char rbuf[64];
  char* ptr = rbuf;

  if (__x == 0)
    *ptr++ = '0';
  else {
    for (; __x != 0; __x /= 10)
      *ptr++ = (char)(__x % 10) + '0';
  }
  while(ptr > rbuf) *buf++ = *--ptr;
  /* psw */
  *buf = '\0';
}

#if defined (__cplusplus)
_STLP_BEGIN_NAMESPACE
extern "C" {
#endif

  _Locale_lcid_t* _Locale_get_ctype_hint(_Locale_ctype_t* ltype)
  { return (ltype != 0) ? &ltype->lc : 0; }
  _Locale_lcid_t* _Locale_get_numeric_hint(_Locale_numeric_t* lnumeric)
  { return (lnumeric != 0) ? &lnumeric->lc : 0; }
  _Locale_lcid_t* _Locale_get_time_hint(_Locale_time_t* ltime)
  { return (ltime != 0) ? &ltime->lc : 0; }
  _Locale_lcid_t* _Locale_get_collate_hint(_Locale_collate_t* lcollate)
  { return (lcollate != 0) ? &lcollate->lc : 0; }
  _Locale_lcid_t* _Locale_get_monetary_hint(_Locale_monetary_t* lmonetary)
  { return (lmonetary != 0) ? &lmonetary->lc : 0; }
  _Locale_lcid_t* _Locale_get_messages_hint(_Locale_messages_t* lmessages)
  { return (lmessages != 0) ? &lmessages->lc : 0; }

  void* _Locale_ctype_create(const char * name, _Locale_lcid_t* lc_hint) {
    char cname[_Locale_MAX_SIMPLE_NAME];
    char cp_name[MAX_CP_LEN + 1];
    int NativeCP;
    unsigned char Buffer[256];
    unsigned char *ptr;
    unsigned short ctable[256];
    CPINFO CPInfo;
    int i;
    wchar_t *wbuffer;
    int BufferSize;

    _Locale_ctype_t *ltype = (_Locale_ctype_t*)malloc(sizeof(_Locale_ctype_t));
    if (!ltype) return ltype;
    memset(ltype, 0, sizeof(_Locale_ctype_t));

    __Extract_locale_name(name, LC_CTYPE, cname);

    if (__GetLCIDFromName(cname, &ltype->lc.id, cp_name, lc_hint) == -1)
    { free(ltype); return NULL; }

    ltype->cp = atoi(cp_name);

    NativeCP = __GetDefaultCP(ltype->lc.id);

    /* Make table with all characters. */
    for (i = 0; i < 256; ++i) Buffer[i] = (unsigned char)i;

    if (!GetCPInfo(NativeCP, &CPInfo)) { free(ltype); return NULL; }

    if (CPInfo.MaxCharSize > 1) {
      for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr+=2)
        for (i = *ptr; i <= *(ptr + 1); ++i) Buffer[i] = 0;
    }

    if ((UINT)NativeCP != ltype->cp) {
      OSVERSIONINFO ver_info;
      ver_info.dwOSVersionInfoSize = sizeof(ver_info);
      GetVersionEx(&ver_info);
      if (ver_info.dwPlatformId == VER_PLATFORM_WIN32_NT) {
        /* Convert character sequence to Unicode. */
        BufferSize = MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
        wbuffer = (wchar_t*)malloc(BufferSize*sizeof(wchar_t));
        if (!MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize))
        { free(wbuffer); free(ltype); return NULL; }

        GetStringTypeW(CT_CTYPE1, wbuffer, 256, ctable);

        for (i = 0; i < 256; ++i)
          ltype->ctable[i]=(unsigned int)ctable[i];

        if (CPInfo.MaxCharSize > 1) {
          for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr+=2)
            for (i = *ptr; i <= *(ptr + 1); i++) ltype->ctable[i] = _LEADBYTE;
        }

        free(wbuffer);
      }
      else {
        unsigned char TargetBuffer[256];
        GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ctable);

        /* Convert character sequence to target code page. */
        BufferSize = MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, NULL, 0);
        wbuffer = (wchar_t*)malloc(BufferSize*sizeof(wchar_t));
        if (!MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize))
        { free(wbuffer); free(ltype); return NULL; }
        if (!WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, BufferSize, (char*)TargetBuffer, 256, NULL, FALSE))
        { free(wbuffer); free(ltype); return NULL; }

        free(wbuffer);

        /* Translate ctype table. */
        for (i = 0; i < 256; ++i) {
          if (!TargetBuffer[i]) continue;
          ltype->ctable[TargetBuffer[i]] = ctable[i];
        }

        /* Mark lead byte. */
        if (!GetCPInfo(ltype->cp, &CPInfo)) { free(ltype); return NULL; }

        if (CPInfo.MaxCharSize > 1) {
          for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr+=2)
            for (i = *ptr; i <= *(ptr + 1); ++i) ltype->ctable[i] = _LEADBYTE;
        }
      }
    }
    else {
      GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ctable);
      for (i = 0; i < 256; ++i)
        ltype->ctable[i]=(unsigned int)ctable[i];

      if (CPInfo.MaxCharSize > 1) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -