c_locale_win32.c

来自「symbian 上的stl_port进过编译的。」· C语言 代码 · 共 1,983 行 · 第 1/5 页

C
1,983
字号
/* * 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#endiftypedef 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_NAMESPACEextern "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) {        for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr+=2)          for (i = *ptr; i <= *(ptr + 1); ++i) ltype->ctable[i] = _LEADBYTE;      }    }    return ltype;  }  void* _Locale_numeric_create(const char * name, _Locale_lcid_t* lc_hint) {    char *GroupingBuffer;    char cname[_Locale_MAX_SIMPLE_NAME];

⌨️ 快捷键说明

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