📄 c_locale_win32.c
字号:
int _Locale_catopen(_Locale_messages_t* __DUMMY_PAR1, const char* __DUMMY_PAR) {
(void*)__DUMMY_PAR1;
(void*)__DUMMY_PAR;
return -1;
}
void _Locale_catclose(_Locale_messages_t* __DUMMY_PAR1, int __DUMMY_PAR) {
(void*)__DUMMY_PAR1;
(void*)&__DUMMY_PAR;
}
const char* _Locale_catgets(_Locale_messages_t* __DUMMY_PAR1, int __DUMMY_PAR2,
int __DUMMY_PAR3, int __DUMMY_PAR4,
const char *dfault) {
(void*)__DUMMY_PAR1;
(void*)&__DUMMY_PAR2;
(void*)&__DUMMY_PAR3;
(void*)&__DUMMY_PAR4;
return dfault;
}
#ifdef __cplusplus
} /* extern C */
_STLP_END_NAMESPACE
#endif
void __FixGrouping(char *grouping) {
/* This converts NT version which uses '0' instead of 0, etc ; to ANSI */
while (*grouping) {
if (*grouping >= '0' && *grouping <= '9') {
*grouping = *grouping - '0';
++grouping;
}
else if (*grouping == ';') {
/* remove ';' */
char *tmp = grouping;
for (; *tmp; ++tmp)
*tmp = *(tmp + 1);
}
else
++grouping;
}
}
const char* __ConvertName(const char* lname, LOCALECONV* ConvTable, int TableSize) {
int i;
int cmp;
int low = 0;
int high = TableSize - 1;
/* typical binary search - do until no more to search or match */
while (low <= high) {
i = (low + high) / 2;
if ((cmp = lstrcmpiA(lname, (*(ConvTable + i)).name)) == 0)
return (*(ConvTable + i)).abbrev;
else if (cmp < 0)
high = i - 1;
else
low = i + 1;
}
return lname;
}
int __ParseLocaleString(const char* lname,
char* lang, char* ctry, char* page) {
int param = 0;
size_t len;
size_t tmpLen;
if (lname[0] == 0)
return 0;
/* We look for the first country separator '_' */
len = strcspn(lname, "_");
if (lname[len] == '_') {
if (len == 0 || len > MAX_LANG_LEN) return -1; /* empty lang is invalid*/
_STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len);
lname += len + 1;
++param;
}
/* We look for the last code page separator '.' */
len = -1;
tmpLen = strcspn(lname, ".");
while (lname[tmpLen] == '.') {
len = tmpLen; ++tmpLen;
tmpLen += strcspn(lname + tmpLen, ".");
}
if (len != -1) { /* Means that we found a '.' */
if (param == 0) {
/* We have no lang yet so we have to fill it first, no country */
if (len > MAX_LANG_LEN) return -1;
if (len == 0) {
/* No language nor country, only code page */
++param;
}
else
{ _STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len); }
++param;
}
else {
/* We already have a lang so we are now looking for the country: */
if (len == 0) return -1; /* We forbid locale name with the "_." motif in it */
if (len > MAX_CTRY_LEN) return -1;
_STLP_STRNCPY(ctry, MAX_CTRY_LEN + 1, lname, len);
}
++param;
lname += len + 1;
}
/* We look for ',' for compatibility with POSIX */
len = strcspn(lname, ",");
switch (param) {
case 0:
if (len > MAX_LANG_LEN) return -1;
_STLP_STRNCPY(lang, MAX_LANG_LEN + 1, lname, len);
break;
case 1:
if (len > MAX_CTRY_LEN) return -1;
_STLP_STRNCPY(ctry, MAX_CTRY_LEN + 1, lname, len);
break;
default:
if (len > MAX_CP_LEN) return -1;
_STLP_STRNCPY(page, MAX_CP_LEN + 1, lname, len);
break;
}
/* ',' POSIX modifier is not used in NT */
return 0;
}
/* Data necessary for find LCID*/
static CRITICAL_SECTION __criticalSection;
static int __FindFlag;
static LCID __FndLCID;
static const char* __FndLang;
static const char* __FndCtry;
void _Locale_init()
{ InitializeCriticalSection(&__criticalSection); }
void _Locale_final()
{ DeleteCriticalSection(&__criticalSection); }
static LCID LocaleFromHex(const char* locale) {
unsigned long result = 0;
int digit;
while (*locale) {
result <<= 4;
digit = (*locale >= '0' && *locale <= '9') ? *locale - '0':
(*locale >= 'A' && *locale <= 'F') ? (*locale - 'A') + 10
: (*locale - 'a') + 10;
result += digit;
++locale;
}
return (LCID)result;
}
static BOOL CALLBACK EnumLocalesProcA(LPSTR locale) {
LCID lcid = LocaleFromHex(locale);
int LangFlag = 0, CtryFlag = !__FndCtry;
static char Lang[MAX_LANG_LEN], Ctry[MAX_CTRY_LEN];
GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, Lang, MAX_LANG_LEN);
if (lstrcmpiA(Lang, __FndLang) != 0) {
GetLocaleInfoA(lcid, LOCALE_SABBREVLANGNAME, Lang, MAX_LANG_LEN);
if (lstrcmpiA(Lang, __FndLang) != 0) {
GetLocaleInfoA(lcid, LOCALE_SISO639LANGNAME, Lang, MAX_LANG_LEN);
if (lstrcmpiA(Lang, __FndLang) == 0) LangFlag = 1;
}
else LangFlag = 1;
}
else LangFlag = 1;
if (__FndCtry) {
GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, Ctry, MAX_CTRY_LEN);
if (lstrcmpiA(Ctry, __FndCtry) != 0) {
GetLocaleInfoA(lcid, LOCALE_SABBREVCTRYNAME, Ctry, MAX_CTRY_LEN);
if (lstrcmpiA(Ctry, __FndCtry) != 0) {
GetLocaleInfoA(lcid, LOCALE_SISO3166CTRYNAME, Ctry, MAX_CTRY_LEN);
if (lstrcmpiA(Ctry, __FndCtry) == 0) CtryFlag = 1;
}
else CtryFlag = 1;
}
else
CtryFlag = 1;
}
if (LangFlag && CtryFlag) {
__FindFlag = 1;
__FndLCID = lcid;
return FALSE;
}
return TRUE;
}
int __GetLCID(const char* lang, const char* ctry, LCID* lcid) {
int ret;
EnterCriticalSection(&__criticalSection);
__FindFlag = 0;
__FndLang = lang;
__FndCtry = ctry;
EnumSystemLocalesA(EnumLocalesProcA, LCID_INSTALLED);
if (__FindFlag != 0) *lcid = __FndLCID;
ret = __FindFlag != 0 ? 0 : -1;
LeaveCriticalSection(&__criticalSection);
return ret;
}
int __GetLCIDFromName(const char* lname, LCID* lcid, char* cp, _Locale_lcid_t *hint) {
char lang[MAX_LANG_LEN + 1], ctry[MAX_CTRY_LEN + 1], page[MAX_CP_LEN + 1];
int result = 0;
if (lname == NULL || lname[0] == 0) {
*lcid = LOCALE_USER_DEFAULT;
return 0;
}
memset(lang, 0, MAX_LANG_LEN + 1);
memset(ctry, 0, MAX_CTRY_LEN + 1);
memset(page, 0, MAX_CP_LEN + 1);
if (__ParseLocaleString(lname, lang, ctry, page) == -1) return -1;
if (hint != 0) {
*lcid = hint->id;
}
else {
if (lang[0] == 0 && ctry[0] == 0)
*lcid = LOCALE_USER_DEFAULT; /* Only code page given. */
else {
if (ctry[0] == 0)
result = __GetLCID(__ConvertName(lang, __rg_language, sizeof(__rg_language) / sizeof(LOCALECONV)), NULL, lcid);
else {
result = __GetLCID(__ConvertName(lang, __rg_language, sizeof(__rg_language) / sizeof(LOCALECONV)),
__ConvertName(ctry, __rg_country, sizeof(__rg_country) / sizeof(LOCALECONV)),
lcid);
if (result != 0) {
/* Non NLS mapping might introduce problem with some locales when only one entry is mapped,
* the lang or the country (example: chinese locales like 'chinese_taiwan' gives 'CHS_taiwan'
* that do not exists in system). This is why we are giving this locale an other chance by
* calling __GetLCID without the mapping. */
result = __GetLCID(lang, ctry, lcid);
}
}
}
}
if (result == 0) {
/* Handling code page */
if (lstrcmpiA(page, "ACP") == 0 || page[0] == 0)
my_ltoa(__intGetACP(*lcid), cp);
else if (lstrcmpiA(page, "OCP") == 0)
my_ltoa(__intGetOCP(*lcid), cp);
else
_STLP_STRNCPY(cp, MAX_CP_LEN + 1, page, 5);
/* Code page must be an integer value,
* 0 returned by __intGetACP and 1 returned by __intGetOCP are invalid
* values.
*/
if (cp[1] == 0 && (cp[0] == '0' || cp[1] == '1'))
return -1;
else if (atoi(cp) == 0)
return -1;
}
return result;
}
char const* __GetLocaleName(LCID lcid, const char* cp, char* buf) {
char lang[MAX_LANG_LEN + 1], ctry[MAX_CTRY_LEN + 1];
GetLocaleInfoA(lcid, LOCALE_SENGLANGUAGE, lang, MAX_LANG_LEN);
GetLocaleInfoA(lcid, LOCALE_SENGCOUNTRY, ctry, MAX_CTRY_LEN);
_STLP_STRCPY2(buf, _Locale_MAX_SIMPLE_NAME, lang);
_STLP_STRCAT2(buf, _Locale_MAX_SIMPLE_NAME, "_");
_STLP_STRCAT2(buf, _Locale_MAX_SIMPLE_NAME, ctry);
_STLP_STRCAT2(buf, _Locale_MAX_SIMPLE_NAME, ".");
_STLP_STRCAT2(buf, _Locale_MAX_SIMPLE_NAME, cp);
return buf;
}
static const char* __loc_categories[]= {
"LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME"
};
char const* __Extract_locale_name(const char* loc, int category, char* buf) {
char *expr;
size_t len_name;
buf[0] = 0;
#if defined (__BORLANDC__)
if (category < LC_MIN || category > LC_MAX) return NULL;
switch (category) {
case 0xFF: category = 0; break;
case 0x01: category = 1; break;
case 0x02: category = 2; break;
case 0x04: category = 3; break;
case 0x10: category = 4; break;
case 0x20: category = 5; break;
default : category = 0;
}
#else
if (category < LC_ALL || category > LC_MAX) return NULL;
#endif
if (loc[0] == 'L' && loc[1] == 'C' && loc[2] == '_') {
expr = strstr((char*)loc, __loc_categories[category]);
if (expr == NULL) return NULL; /* Category not found. */
expr = strchr(expr, '=');
if (expr == NULL) return NULL;
++expr;
len_name = strcspn(expr, ";");
len_name = len_name > _Locale_MAX_SIMPLE_NAME ? _Locale_MAX_SIMPLE_NAME
: len_name;
_STLP_STRNCPY(buf, _Locale_MAX_SIMPLE_NAME, expr, len_name); buf[len_name] = 0;
return buf;
}
else {
_STLP_STRNCPY(buf, _Locale_MAX_SIMPLE_NAME, loc, _Locale_MAX_SIMPLE_NAME);
return buf;
}
}
char const* __TranslateToSystem(const char* lname, char* buf, _Locale_lcid_t* hint) {
LCID lcid;
char cp[MAX_CP_LEN + 1];
if (__GetLCIDFromName(lname, &lcid, cp, hint) != 0) return NULL;
return __GetLocaleName(lcid, cp, buf);
}
void __GetLocaleInfoUsingACP(LCID lcid, const char* cp, LCTYPE lctype, char* buf, int buf_size) {
wchar_t *Buffer;
int BufferSize;
GetLocaleInfoA(lcid, lctype, buf, buf_size);
BufferSize = MultiByteToWideChar(CP_ACP, 0, buf, -1, NULL, 0);
Buffer = (wchar_t*)malloc(sizeof(wchar_t) * (BufferSize + 1));
MultiByteToWideChar(CP_ACP, 0, buf, -1, Buffer, BufferSize);
WideCharToMultiByte(atoi(cp), 0, Buffer, -1, buf, buf_size, NULL, NULL);
free(Buffer);
}
/* Return 0 if ANSI code page not used */
int __intGetACP(LCID lcid) {
char cp[6];
GetLocaleInfoA(lcid, LOCALE_IDEFAULTANSICODEPAGE, cp, 6);
return atoi(cp);
}
/* Return 1 if OEM code page not used */
int __intGetOCP(LCID lcid) {
char cp[6];
GetLocaleInfoA(lcid, LOCALE_IDEFAULTCODEPAGE, cp, 6);
return atoi(cp);
}
int __GetDefaultCP(LCID lcid) {
int cp = __intGetACP(lcid);
if (cp == 0) return __intGetOCP(lcid);
else return cp;
}
static int trim_size_t_to_int(size_t n) { return n < (size_t)INT_MAX ? (int)n : INT_MAX; }
char* __ConvertToCP(int from_cp, int to_cp, const char *from, size_t size, size_t *ret_buf_size) {
size_t wbuffer_size, buffer_size, from_offset, wbuf_offset;
int from_size, to_size, wbuf_size;
wchar_t *wbuffer;
char* buffer;
size_t orig_size = size;
wbuffer_size = 0;
from_offset = 0;
while (size > 0) {
from_size = trim_size_t_to_int(size);
wbuffer_size += MultiByteToWideChar(from_cp, MB_PRECOMPOSED,
from + from_offset, from_size, NULL, 0);
from_offset += from_size;
size
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -