/********************************************************************* * wctomb (MSVCRT.@) */ INT CDECL wctomb( char *dst, wchar_t ch ) { BOOL error; INT size; size = WideCharToMultiByte(get_locinfo()->lc_codepage, 0, &ch, 1, dst, dst ? 6 : 0, NULL, &error); if(!size || error) { *_errno() = EINVAL; return EOF; } return size; }
/********************************************************************* * wcsrtombs_l (INTERNAL) */ static MSVCRT_size_t CDECL MSVCRT_wcsrtombs_l(char *mbstr, const MSVCRT_wchar_t **wcstr, MSVCRT_size_t count, MSVCRT__locale_t locale) { MSVCRT_pthreadlocinfo locinfo; MSVCRT_size_t tmp = 0; BOOL used_default; if(!locale) locinfo = get_locinfo(); else locinfo = locale->locinfo; if(!mbstr) { tmp = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS, *wcstr, -1, NULL, 0, NULL, &used_default)-1; if(used_default) return -1; return tmp; } while(**wcstr) { char buf[3]; MSVCRT_size_t i, size; size = WideCharToMultiByte(locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS, *wcstr, 1, buf, 3, NULL, &used_default); if(used_default) return -1; if(tmp+size > count) return tmp; for(i=0; i<size; i++) mbstr[tmp++] = buf[i]; (*wcstr)++; } if(tmp < count) { mbstr[tmp] = '\0'; *wcstr = NULL; } return tmp; }
size_t CDECL _strxfrm_l( char *dest, const char *src, size_t len, _locale_t locale ) { MSVCRT_pthreadlocinfo locinfo; int ret; if(!MSVCRT_CHECK_PMT(src)) return INT_MAX; if(!MSVCRT_CHECK_PMT(dest || !len)) return INT_MAX; if(len > INT_MAX) { FIXME("len > INT_MAX not supported\n"); len = INT_MAX; } if(!locale) locinfo = get_locinfo(); else locinfo = ((MSVCRT__locale_t)locale)->locinfo; if(!locinfo->lc_handle[MSVCRT_LC_COLLATE]) { strncpy(dest, src, len); return strlen(src); } ret = LCMapStringA(locinfo->lc_handle[MSVCRT_LC_COLLATE], LCMAP_SORTKEY, src, -1, NULL, 0); if(!ret) { if(len) dest[0] = 0; *_errno() = EILSEQ; return INT_MAX; } if(!len) return ret-1; if(ret > len) { dest[0] = 0; *_errno() = ERANGE; return ret-1; } return LCMapStringA(locinfo->lc_handle[MSVCRT_LC_COLLATE], LCMAP_SORTKEY, src, -1, dest, len) - 1; }
/********************************************************************* * _wcstod_l - not exported in native msvcrt */ double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end, MSVCRT__locale_t locale) { MSVCRT_pthreadlocinfo locinfo; unsigned __int64 d=0, hlp; unsigned fpcontrol; int exp=0, sign=1; const MSVCRT_wchar_t *p; double ret; BOOL found_digit = FALSE; if (!MSVCRT_CHECK_PMT(str != NULL)) return 0; if(!locale) locinfo = get_locinfo(); else locinfo = locale->locinfo; p = str; while(isspaceW(*p)) p++; if(*p == '-') { sign = -1; p++; } else if(*p == '+') p++; while(isdigitW(*p)) { found_digit = TRUE; hlp = d*10+*(p++)-'0'; if(d>MSVCRT_UI64_MAX/10 || hlp<d) { exp++; break; } else d = hlp; } while(isdigitW(*p)) { exp++; p++; } if(*p == *locinfo->lconv->decimal_point) p++; while(isdigitW(*p)) { found_digit = TRUE; hlp = d*10+*(p++)-'0'; if(d>MSVCRT_UI64_MAX/10 || hlp<d) break; d = hlp; exp--; } while(isdigitW(*p)) p++; if(!found_digit) { if(end) *end = (MSVCRT_wchar_t*)str; return 0.0; } if(*p=='e' || *p=='E' || *p=='d' || *p=='D') { int e=0, s=1; p++; if(*p == '-') { s = -1; p++; } else if(*p == '+') p++; if(isdigitW(*p)) { while(isdigitW(*p)) { if(e>INT_MAX/10 || (e=e*10+*p-'0')<0) e = INT_MAX; p++; } e *= s; if(exp<0 && e<0 && exp+e>=0) exp = INT_MIN; else if(exp>0 && e>0 && exp+e<0) exp = INT_MAX; else exp += e; } else { if(*p=='-' || *p=='+') p--; p--; } } fpcontrol = _control87(0, 0); _control87(MSVCRT__EM_DENORMAL|MSVCRT__EM_INVALID|MSVCRT__EM_ZERODIVIDE |MSVCRT__EM_OVERFLOW|MSVCRT__EM_UNDERFLOW|MSVCRT__EM_INEXACT, 0xffffffff); if(exp>0) ret = (double)sign*d*pow(10, exp); else ret = (double)sign*d/pow(10, -exp); _control87(fpcontrol, 0xffffffff); if((d && ret==0.0) || isinf(ret)) *MSVCRT__errno() = MSVCRT_ERANGE; if(end) *end = (MSVCRT_wchar_t*)p; return ret; }