msvcrt: Added wcsrtombs implementation.
This commit is contained in:
parent
7810e231a8
commit
168909283c
|
@ -1647,8 +1647,8 @@
|
||||||
@ cdecl wcsnlen(wstr long) msvcrt.wcsnlen
|
@ cdecl wcsnlen(wstr long) msvcrt.wcsnlen
|
||||||
@ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk
|
@ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk
|
||||||
@ cdecl wcsrchr(wstr long) msvcrt.wcsrchr
|
@ cdecl wcsrchr(wstr long) msvcrt.wcsrchr
|
||||||
@ stub wcsrtombs
|
@ cdecl wcsrtombs(ptr ptr long ptr) msvcrt.wcsrtombs
|
||||||
@ stub wcsrtombs_s
|
@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) msvcrt.wcsrtombs_s
|
||||||
@ cdecl wcsspn(wstr wstr) msvcrt.wcsspn
|
@ cdecl wcsspn(wstr wstr) msvcrt.wcsspn
|
||||||
@ cdecl wcsstr(wstr wstr) msvcrt.wcsstr
|
@ cdecl wcsstr(wstr wstr) msvcrt.wcsstr
|
||||||
@ cdecl wcstod(wstr ptr) msvcrt.wcstod
|
@ cdecl wcstod(wstr ptr) msvcrt.wcstod
|
||||||
|
|
|
@ -1501,8 +1501,8 @@
|
||||||
@ cdecl wcsnlen(wstr long) msvcrt.wcsnlen
|
@ cdecl wcsnlen(wstr long) msvcrt.wcsnlen
|
||||||
@ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk
|
@ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk
|
||||||
@ cdecl wcsrchr(wstr long) msvcrt.wcsrchr
|
@ cdecl wcsrchr(wstr long) msvcrt.wcsrchr
|
||||||
@ stub wcsrtombs
|
@ cdecl wcsrtombs(ptr ptr long ptr) msvcrt.wcsrtombs
|
||||||
@ stub wcsrtombs_s
|
@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) msvcrt.wcsrtombs_s
|
||||||
@ cdecl wcsspn(wstr wstr) msvcrt.wcsspn
|
@ cdecl wcsspn(wstr wstr) msvcrt.wcsspn
|
||||||
@ cdecl wcsstr(wstr wstr) msvcrt.wcsstr
|
@ cdecl wcsstr(wstr wstr) msvcrt.wcsstr
|
||||||
@ cdecl wcstod(wstr ptr) msvcrt.wcstod
|
@ cdecl wcstod(wstr ptr) msvcrt.wcstod
|
||||||
|
|
|
@ -1485,8 +1485,8 @@
|
||||||
@ cdecl wcsnlen(wstr long) msvcrt.wcsnlen
|
@ cdecl wcsnlen(wstr long) msvcrt.wcsnlen
|
||||||
@ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk
|
@ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk
|
||||||
@ cdecl wcsrchr(wstr long) msvcrt.wcsrchr
|
@ cdecl wcsrchr(wstr long) msvcrt.wcsrchr
|
||||||
@ stub wcsrtombs
|
@ cdecl wcsrtombs(ptr ptr long ptr) msvcrt.wcsrtombs
|
||||||
@ stub wcsrtombs_s
|
@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) msvcrt.wcsrtombs_s
|
||||||
@ cdecl wcsspn(wstr wstr) msvcrt.wcsspn
|
@ cdecl wcsspn(wstr wstr) msvcrt.wcsspn
|
||||||
@ cdecl wcsstr(wstr wstr) msvcrt.wcsstr
|
@ cdecl wcsstr(wstr wstr) msvcrt.wcsstr
|
||||||
@ cdecl wcstod(wstr ptr) msvcrt.wcstod
|
@ cdecl wcstod(wstr ptr) msvcrt.wcstod
|
||||||
|
|
|
@ -74,6 +74,7 @@ typedef int MSVCRT_clock_t;
|
||||||
typedef int MSVCRT___time32_t;
|
typedef int MSVCRT___time32_t;
|
||||||
typedef __int64 DECLSPEC_ALIGN(8) MSVCRT___time64_t;
|
typedef __int64 DECLSPEC_ALIGN(8) MSVCRT___time64_t;
|
||||||
typedef __int64 DECLSPEC_ALIGN(8) MSVCRT_fpos_t;
|
typedef __int64 DECLSPEC_ALIGN(8) MSVCRT_fpos_t;
|
||||||
|
typedef int MSVCRT_mbstate_t;
|
||||||
|
|
||||||
typedef void (*__cdecl MSVCRT_terminate_handler)(void);
|
typedef void (*__cdecl MSVCRT_terminate_handler)(void);
|
||||||
typedef void (*__cdecl MSVCRT_terminate_function)(void);
|
typedef void (*__cdecl MSVCRT_terminate_function)(void);
|
||||||
|
|
|
@ -1456,8 +1456,8 @@
|
||||||
@ cdecl wcsnlen(wstr long) MSVCRT_wcsnlen
|
@ cdecl wcsnlen(wstr long) MSVCRT_wcsnlen
|
||||||
@ cdecl wcspbrk(wstr wstr) MSVCRT_wcspbrk
|
@ cdecl wcspbrk(wstr wstr) MSVCRT_wcspbrk
|
||||||
@ cdecl wcsrchr(wstr long) ntdll.wcsrchr
|
@ cdecl wcsrchr(wstr long) ntdll.wcsrchr
|
||||||
# stub wcsrtombs
|
@ cdecl wcsrtombs(ptr ptr long ptr) MSVCRT_wcsrtombs
|
||||||
# stub wcsrtombs_s
|
@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) MSVCRT_wcsrtombs_s
|
||||||
@ cdecl wcsspn(wstr wstr) ntdll.wcsspn
|
@ cdecl wcsspn(wstr wstr) ntdll.wcsspn
|
||||||
@ cdecl wcsstr(wstr wstr) ntdll.wcsstr
|
@ cdecl wcsstr(wstr wstr) ntdll.wcsstr
|
||||||
@ cdecl wcstod(wstr ptr) MSVCRT_wcstod
|
@ cdecl wcstod(wstr ptr) MSVCRT_wcstod
|
||||||
|
|
|
@ -68,6 +68,7 @@ static __int64 (__cdecl *p_strtoi64)(const char *, char **, int);
|
||||||
static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
|
static unsigned __int64 (__cdecl *p_strtoui64)(const char *, char **, int);
|
||||||
static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t);
|
static int (__cdecl *pwcstombs_s)(size_t*,char*,size_t,const wchar_t*,size_t);
|
||||||
static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t);
|
static int (__cdecl *pmbstowcs_s)(size_t*,wchar_t*,size_t,const char*,size_t);
|
||||||
|
static size_t (__cdecl *pwcsrtombs)(char*, const wchar_t**, size_t, int*);
|
||||||
static errno_t (__cdecl *p_gcvt_s)(char*,size_t,double,int);
|
static errno_t (__cdecl *p_gcvt_s)(char*,size_t,double,int);
|
||||||
static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
|
static errno_t (__cdecl *p_itoa_s)(int,char*,size_t,int);
|
||||||
static errno_t (__cdecl *p_strlwr_s)(char*,size_t);
|
static errno_t (__cdecl *p_strlwr_s)(char*,size_t);
|
||||||
|
@ -1283,6 +1284,7 @@ static void test_mbstowcs(void)
|
||||||
static const char mSimple[] = "text";
|
static const char mSimple[] = "text";
|
||||||
static const char mHiragana[] = { 0x82,0xa0,0x82,0xa1,0 };
|
static const char mHiragana[] = { 0x82,0xa0,0x82,0xa1,0 };
|
||||||
|
|
||||||
|
const wchar_t *pwstr;
|
||||||
wchar_t wOut[6];
|
wchar_t wOut[6];
|
||||||
char mOut[6];
|
char mOut[6];
|
||||||
size_t ret;
|
size_t ret;
|
||||||
|
@ -1355,6 +1357,25 @@ static void test_mbstowcs(void)
|
||||||
err = pwcstombs_s(&ret, NULL, 0, wHiragana, 1);
|
err = pwcstombs_s(&ret, NULL, 0, wHiragana, 1);
|
||||||
ok(err == 0, "err = %d\n", err);
|
ok(err == 0, "err = %d\n", err);
|
||||||
ok(ret == 5, "ret = %d\n", (int)ret);
|
ok(ret == 5, "ret = %d\n", (int)ret);
|
||||||
|
|
||||||
|
if(!pwcsrtombs) {
|
||||||
|
win_skip("wcsrtombs not available\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwstr = wSimple;
|
||||||
|
err = -3;
|
||||||
|
ret = pwcsrtombs(mOut, &pwstr, 4, &err);
|
||||||
|
ok(ret == 4, "ret = %d\n", ret);
|
||||||
|
ok(err == 0, "err = %d\n", err);
|
||||||
|
ok(pwstr == wSimple+4, "pwstr = %p (wszSimple = %p)\n", pwstr, wSimple);
|
||||||
|
ok(!memcmp(mOut, mSimple, ret), "mOut = %s\n", mOut);
|
||||||
|
|
||||||
|
pwstr = wSimple;
|
||||||
|
ret = pwcsrtombs(mOut, &pwstr, 5, NULL);
|
||||||
|
ok(ret == 4, "ret = %d\n", ret);
|
||||||
|
ok(pwstr == NULL, "pwstr != NULL\n");
|
||||||
|
ok(!memcmp(mOut, mSimple, sizeof(mSimple)), "mOut = %s\n", mOut);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_gcvt(void)
|
static void test_gcvt(void)
|
||||||
|
@ -1974,6 +1995,7 @@ START_TEST(string)
|
||||||
p_strtoui64 = (void *)GetProcAddress(hMsvcrt, "_strtoui64");
|
p_strtoui64 = (void *)GetProcAddress(hMsvcrt, "_strtoui64");
|
||||||
pmbstowcs_s = (void *)GetProcAddress(hMsvcrt, "mbstowcs_s");
|
pmbstowcs_s = (void *)GetProcAddress(hMsvcrt, "mbstowcs_s");
|
||||||
pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s");
|
pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s");
|
||||||
|
pwcsrtombs = (void *)GetProcAddress(hMsvcrt, "wcsrtombs");
|
||||||
p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s");
|
p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s");
|
||||||
p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s");
|
p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s");
|
||||||
p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s");
|
p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s");
|
||||||
|
|
|
@ -288,9 +288,9 @@ double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end,
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _wcstombs_l (MSVCRT.@)
|
* wcsrtombs_l (INTERNAL)
|
||||||
*/
|
*/
|
||||||
MSVCRT_size_t CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr,
|
static MSVCRT_size_t CDECL MSVCRT_wcsrtombs_l(char *mbstr, const MSVCRT_wchar_t **wcstr,
|
||||||
MSVCRT_size_t count, MSVCRT__locale_t locale)
|
MSVCRT_size_t count, MSVCRT__locale_t locale)
|
||||||
{
|
{
|
||||||
char default_char = '\0';
|
char default_char = '\0';
|
||||||
|
@ -302,14 +302,14 @@ MSVCRT_size_t CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr,
|
||||||
|
|
||||||
if(!mbstr)
|
if(!mbstr)
|
||||||
return WideCharToMultiByte(locale->locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
|
return WideCharToMultiByte(locale->locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
|
||||||
wcstr, -1, NULL, 0, &default_char, &used_default)-1;
|
*wcstr, -1, NULL, 0, &default_char, &used_default)-1;
|
||||||
|
|
||||||
while(*wcstr) {
|
while(**wcstr) {
|
||||||
char buf[3];
|
char buf[3];
|
||||||
MSVCRT_size_t i, size;
|
MSVCRT_size_t i, size;
|
||||||
|
|
||||||
size = WideCharToMultiByte(locale->locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
|
size = WideCharToMultiByte(locale->locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
|
||||||
wcstr, 1, buf, 3, &default_char, &used_default);
|
*wcstr, 1, buf, 3, &default_char, &used_default);
|
||||||
if(used_default)
|
if(used_default)
|
||||||
return -1;
|
return -1;
|
||||||
if(tmp+size > count)
|
if(tmp+size > count)
|
||||||
|
@ -317,40 +317,64 @@ MSVCRT_size_t CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr,
|
||||||
|
|
||||||
for(i=0; i<size; i++)
|
for(i=0; i<size; i++)
|
||||||
mbstr[tmp++] = buf[i];
|
mbstr[tmp++] = buf[i];
|
||||||
wcstr++;
|
(*wcstr)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tmp < count)
|
if(tmp < count) {
|
||||||
mbstr[tmp] = '\0';
|
mbstr[tmp] = '\0';
|
||||||
|
*wcstr = NULL;
|
||||||
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _wcstombs_l (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
MSVCRT_size_t CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr,
|
||||||
|
MSVCRT_size_t count, MSVCRT__locale_t locale)
|
||||||
|
{
|
||||||
|
return MSVCRT_wcsrtombs_l(mbstr, &wcstr, count, locale);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* wcstombs (MSVCRT.@)
|
* wcstombs (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
MSVCRT_size_t CDECL MSVCRT_wcstombs(char *mbstr, const MSVCRT_wchar_t *wcstr,
|
MSVCRT_size_t CDECL MSVCRT_wcstombs(char *mbstr, const MSVCRT_wchar_t *wcstr,
|
||||||
MSVCRT_size_t count)
|
MSVCRT_size_t count)
|
||||||
{
|
{
|
||||||
return MSVCRT__wcstombs_l(mbstr, wcstr, count, NULL);
|
return MSVCRT_wcsrtombs_l(mbstr, &wcstr, count, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _wcstombs_s_l (MSVCRT.@)
|
* wcsrtombs (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
MSVCRT_size_t CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr,
|
MSVCRT_size_t CDECL MSVCRT_wcsrtombs(char *mbstr, const MSVCRT_wchar_t **wcstr,
|
||||||
MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr,
|
MSVCRT_size_t count, MSVCRT_mbstate_t *mbstate)
|
||||||
|
{
|
||||||
|
if(mbstate)
|
||||||
|
*mbstate = 0;
|
||||||
|
|
||||||
|
return MSVCRT_wcsrtombs_l(mbstr, wcstr, count, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* MSVCRT_wcsrtombs_s_l (INTERNAL)
|
||||||
|
*/
|
||||||
|
MSVCRT_size_t CDECL MSVCRT_wcsrtombs_s_l(MSVCRT_size_t *ret, char *mbstr,
|
||||||
|
MSVCRT_size_t size, const MSVCRT_wchar_t **wcstr,
|
||||||
MSVCRT_size_t count, MSVCRT__locale_t locale)
|
MSVCRT_size_t count, MSVCRT__locale_t locale)
|
||||||
{
|
{
|
||||||
MSVCRT_size_t conv;
|
MSVCRT_size_t conv;
|
||||||
|
|
||||||
if(!mbstr && !size) {
|
if(!mbstr && !size && wcstr) {
|
||||||
conv = MSVCRT__wcstombs_l(NULL, wcstr, 0, locale);
|
conv = MSVCRT_wcsrtombs_l(NULL, wcstr, 0, locale);
|
||||||
if(ret)
|
if(ret)
|
||||||
*ret = conv+1;
|
*ret = conv+1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!MSVCRT_CHECK_PMT(wcstr != NULL) || !MSVCRT_CHECK_PMT(mbstr != NULL)) {
|
if (!MSVCRT_CHECK_PMT(wcstr != NULL) || !MSVCRT_CHECK_PMT(*wcstr != NULL)
|
||||||
|
|| !MSVCRT_CHECK_PMT(mbstr != NULL)) {
|
||||||
if(mbstr && size)
|
if(mbstr && size)
|
||||||
mbstr[0] = '\0';
|
mbstr[0] = '\0';
|
||||||
*MSVCRT__errno() = MSVCRT_EINVAL;
|
*MSVCRT__errno() = MSVCRT_EINVAL;
|
||||||
|
@ -362,7 +386,7 @@ MSVCRT_size_t CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr,
|
||||||
else
|
else
|
||||||
conv = count;
|
conv = count;
|
||||||
|
|
||||||
conv = MSVCRT__wcstombs_l(mbstr, wcstr, conv, locale);
|
conv = MSVCRT_wcsrtombs_l(mbstr, wcstr, conv, locale);
|
||||||
if(conv<size)
|
if(conv<size)
|
||||||
mbstr[conv++] = '\0';
|
mbstr[conv++] = '\0';
|
||||||
else if(conv==size && (count==MSVCRT__TRUNCATE || mbstr[conv-1]=='\0'))
|
else if(conv==size && (count==MSVCRT__TRUNCATE || mbstr[conv-1]=='\0'))
|
||||||
|
@ -380,13 +404,35 @@ MSVCRT_size_t CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* _wcstombs_s_l (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
MSVCRT_size_t CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr,
|
||||||
|
MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr,
|
||||||
|
MSVCRT_size_t count, MSVCRT__locale_t locale)
|
||||||
|
{
|
||||||
|
return MSVCRT_wcsrtombs_s_l(ret, mbstr, size, &wcstr,count, locale);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* wcstombs_s (MSVCRT.@)
|
* wcstombs_s (MSVCRT.@)
|
||||||
*/
|
*/
|
||||||
MSVCRT_size_t CDECL MSVCRT_wcstombs_s(MSVCRT_size_t *ret, char *mbstr,
|
MSVCRT_size_t CDECL MSVCRT_wcstombs_s(MSVCRT_size_t *ret, char *mbstr,
|
||||||
MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr, MSVCRT_size_t count)
|
MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr, MSVCRT_size_t count)
|
||||||
{
|
{
|
||||||
return MSVCRT__wcstombs_s_l(ret, mbstr, size, wcstr, count, NULL);
|
return MSVCRT_wcsrtombs_s_l(ret, mbstr, size, &wcstr, count, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************
|
||||||
|
* wcsrtombs_s (MSVCRT.@)
|
||||||
|
*/
|
||||||
|
MSVCRT_size_t CDECL MSVCRT_wcsrtombs_s(MSVCRT_size_t *ret, char *mbstr, MSVCRT_size_t size,
|
||||||
|
const MSVCRT_wchar_t **wcstr, MSVCRT_size_t count, MSVCRT_mbstate_t *mbstate)
|
||||||
|
{
|
||||||
|
if(mbstate)
|
||||||
|
*mbstate = 0;
|
||||||
|
|
||||||
|
return MSVCRT_wcsrtombs_s_l(ret, mbstr, size, wcstr, count, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
|
|
Loading…
Reference in New Issue