c_locale_win32.c
来自「stl的源码」· C语言 代码 · 共 1,787 行 · 第 1/4 页
C
1,787 行
/* * 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 <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, DS, S) strcpy_s(D, DS, S)# define _STLP_STRNCPY(D, DS, S, C) strncpy_s(D, DS, S, C)# define _STLP_STRCAT(D, DS, S) strcat_s(D, DS, S)#else# define _STLP_STRCPY(D, DS, S) strcpy(D, S)# define _STLP_STRNCPY(D, DS, S, C) strncpy(D, S, C)# define _STLP_STRCAT(D, DS, S) strcat(D, S)#endif#if defined (__cplusplus)extern "C" {#endif/* Framework functions *//* locale :: "lang[_country[.code_page]]" | ".code_page" | "" | NULL*/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 */#if !defined (LANG_INVARIANT)# define LANG_INVARIANT 0x7f# define _STLP_LANG_INVARIANT_DEFINED#endif#ifndef CP_UTF7# define CP_UTF7 65000#endif#ifndef CP_UTF8# define CP_UTF8 65001#endif#define INVARIANT_LCID MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)static const char *_C_name = "C";/* 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 short 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;/* 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, const char* category, char* buf);static char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint, int *__err_code);static void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size, wchar_t* wbuf, int wbuf_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) ? <ype->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) ? <ime->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(struct _Locale_messages* lmessages) { _STLP_MARK_PARAMETER_AS_UNUSED(lmessages) return 0;}#define MAP(x, y) if ((mask & x) != 0) ret |= (y)unsigned short MapCtypeMask(unsigned short mask) { unsigned short ret = 0; MAP(C1_UPPER, _Locale_UPPER | _Locale_PRINT); MAP(C1_LOWER, _Locale_LOWER | _Locale_PRINT); MAP(C1_DIGIT, _Locale_DIGIT | _Locale_PRINT); MAP(C1_SPACE, _Locale_SPACE | _Locale_PRINT); MAP(C1_PUNCT, _Locale_PUNCT | _Locale_PRINT); /* MAP(C1_BLANK, ?); */ MAP(C1_XDIGIT, _Locale_XDIGIT | _Locale_PRINT); MAP(C1_ALPHA, _Locale_ALPHA | _Locale_PRINT); if ((mask & C1_CNTRL) != 0) { ret |= _Locale_CNTRL; ret &= ~_Locale_PRINT; } return ret;}static void MapCtypeMasks(unsigned short *cur, unsigned short *end) { for (; cur != end; ++cur) { *cur = MapCtypeMask(*cur); }}_Locale_ctype_t* _Locale_ctype_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { char cp_name[MAX_CP_LEN + 1]; int NativeCP; unsigned char Buffer[256]; unsigned char *ptr; CPINFO CPInfo; int i; wchar_t *wbuffer; int BufferSize; _Locale_ctype_t *ltype = (_Locale_ctype_t*)malloc(sizeof(_Locale_ctype_t)); if (!ltype) { *__err_code = _STLP_LOC_NO_MEMORY; return ltype; } memset(ltype, 0, sizeof(_Locale_ctype_t)); if (__GetLCIDFromName(name, <ype->lc.id, cp_name, lc_hint) == -1) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }#if defined (__BORLANDC__) if ( ltype->lc.id == INVARIANT_LCID && name[0] == 'C' && name[1] == 0 ) { ltype->lc.id = 0x409; }#endif 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); if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t)); if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } MultiByteToWideChar(ltype->cp, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize); GetStringTypeW(CT_CTYPE1, wbuffer, 256, ltype->ctable); MapCtypeMasks(ltype->ctable, ltype->ctable + 256); free(wbuffer); } else { unsigned short ctable[256]; 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); if (!BufferSize) { free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } wbuffer = (wchar_t*)malloc(BufferSize * sizeof(wchar_t)); if (!wbuffer) { free(ltype); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } MultiByteToWideChar(NativeCP, MB_PRECOMPOSED, (const char*)Buffer, 256, wbuffer, BufferSize); if (!WideCharToMultiByte(ltype->cp, WC_COMPOSITECHECK | WC_SEPCHARS, wbuffer, BufferSize, (char*)TargetBuffer, 256, NULL, FALSE)) { free(wbuffer); free(ltype); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } free(wbuffer); /* Translate ctype table. */ for (i = 0; i < 256; ++i) { if (!TargetBuffer[i]) continue; ltype->ctable[TargetBuffer[i]] = MapCtypeMask(ctable[i]); } } } else { GetStringTypeA(ltype->lc.id, CT_CTYPE1, (const char*)Buffer, 256, ltype->ctable); MapCtypeMasks(ltype->ctable, ltype->ctable + 256); } return ltype;}_Locale_numeric_t* _Locale_numeric_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { wchar_t wbuf[4]; char *GroupingBuffer; int BufferSize; _Locale_numeric_t *lnum = (_Locale_numeric_t*)malloc(sizeof(_Locale_numeric_t)); if (!lnum) { *__err_code = _STLP_LOC_NO_MEMORY; return lnum; } memset(lnum, 0, sizeof(_Locale_numeric_t)); if (__GetLCIDFromName(name, &lnum->lc.id, lnum->cp, lc_hint) == -1) { free(lnum); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }#if defined (__BORLANDC__) if (lnum->lc.id != INVARIANT_LCID) {#endif __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_SDECIMAL, lnum->decimal_point, 4, wbuf, 4); __GetLocaleInfoUsingACP(lnum->lc.id, lnum->cp, LOCALE_STHOUSAND, lnum->thousands_sep, 4, wbuf, 4);#if defined (__BORLANDC__) } else lnum->decimal_point[0] = '.';#endif if (lnum->lc.id != INVARIANT_LCID) { BufferSize = GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, NULL, 0); GroupingBuffer = (char*)malloc(BufferSize); if (!GroupingBuffer) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } GetLocaleInfoA(lnum->lc.id, LOCALE_SGROUPING, GroupingBuffer, BufferSize); __FixGrouping(GroupingBuffer); lnum->grouping = GroupingBuffer; } else { lnum->grouping = (char*)malloc(1); if (!lnum->grouping) { free(lnum); *__err_code = _STLP_LOC_NO_MEMORY; return NULL; } lnum->grouping[0] = 0; } return lnum;}static int __ConvertDate(const char *NTDate, char *buffer, int buf_size) { /* This function will return an incomplete buffer if buffer is not long enough */ const char *cur_char; char *cur_output, *end_output; /* Correct time format. */ cur_char = NTDate; cur_output = buffer; end_output = cur_output + buf_size; buf_size = 0; while (*cur_char) { if (cur_output && (cur_output == end_output)) break; switch (*cur_char) { case 'd': { if (*(cur_char + 1) == 'd') { if (cur_output && (cur_output + 2 > end_output)) { *cur_output = 0; return ++buf_size; } if (*(cur_char + 2) == 'd') {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?