diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 0a4fa936bf2..4a724bc70b1 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -1647,8 +1647,8 @@ @ cdecl wcsnlen(wstr long) msvcrt.wcsnlen @ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk @ cdecl wcsrchr(wstr long) msvcrt.wcsrchr -@ stub wcsrtombs -@ stub wcsrtombs_s +@ cdecl wcsrtombs(ptr ptr long ptr) msvcrt.wcsrtombs +@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) msvcrt.wcsrtombs_s @ cdecl wcsspn(wstr wstr) msvcrt.wcsspn @ cdecl wcsstr(wstr wstr) msvcrt.wcsstr @ cdecl wcstod(wstr ptr) msvcrt.wcstod diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index d8a5ca36684..3f5bd041a93 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -1501,8 +1501,8 @@ @ cdecl wcsnlen(wstr long) msvcrt.wcsnlen @ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk @ cdecl wcsrchr(wstr long) msvcrt.wcsrchr -@ stub wcsrtombs -@ stub wcsrtombs_s +@ cdecl wcsrtombs(ptr ptr long ptr) msvcrt.wcsrtombs +@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) msvcrt.wcsrtombs_s @ cdecl wcsspn(wstr wstr) msvcrt.wcsspn @ cdecl wcsstr(wstr wstr) msvcrt.wcsstr @ cdecl wcstod(wstr ptr) msvcrt.wcstod diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 56d8c2dd8b5..c7efd3a6f09 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -1485,8 +1485,8 @@ @ cdecl wcsnlen(wstr long) msvcrt.wcsnlen @ cdecl wcspbrk(wstr wstr) msvcrt.wcspbrk @ cdecl wcsrchr(wstr long) msvcrt.wcsrchr -@ stub wcsrtombs -@ stub wcsrtombs_s +@ cdecl wcsrtombs(ptr ptr long ptr) msvcrt.wcsrtombs +@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) msvcrt.wcsrtombs_s @ cdecl wcsspn(wstr wstr) msvcrt.wcsspn @ cdecl wcsstr(wstr wstr) msvcrt.wcsstr @ cdecl wcstod(wstr ptr) msvcrt.wcstod diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 852fe9279ad..40d72616c9a 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -74,6 +74,7 @@ typedef int MSVCRT_clock_t; typedef int MSVCRT___time32_t; typedef __int64 DECLSPEC_ALIGN(8) MSVCRT___time64_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_function)(void); diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index c1e7b75e556..94064fe0d27 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -1456,8 +1456,8 @@ @ cdecl wcsnlen(wstr long) MSVCRT_wcsnlen @ cdecl wcspbrk(wstr wstr) MSVCRT_wcspbrk @ cdecl wcsrchr(wstr long) ntdll.wcsrchr -# stub wcsrtombs -# stub wcsrtombs_s +@ cdecl wcsrtombs(ptr ptr long ptr) MSVCRT_wcsrtombs +@ cdecl wcsrtombs_s(ptr ptr long ptr long ptr) MSVCRT_wcsrtombs_s @ cdecl wcsspn(wstr wstr) ntdll.wcsspn @ cdecl wcsstr(wstr wstr) ntdll.wcsstr @ cdecl wcstod(wstr ptr) MSVCRT_wcstod diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 8b0494b11dc..b72e001c38c 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -68,6 +68,7 @@ static __int64 (__cdecl *p_strtoi64)(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 *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_itoa_s)(int,char*,size_t,int); 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 mHiragana[] = { 0x82,0xa0,0x82,0xa1,0 }; + const wchar_t *pwstr; wchar_t wOut[6]; char mOut[6]; size_t ret; @@ -1355,6 +1357,25 @@ static void test_mbstowcs(void) err = pwcstombs_s(&ret, NULL, 0, wHiragana, 1); ok(err == 0, "err = %d\n", err); 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) @@ -1974,6 +1995,7 @@ START_TEST(string) p_strtoui64 = (void *)GetProcAddress(hMsvcrt, "_strtoui64"); pmbstowcs_s = (void *)GetProcAddress(hMsvcrt, "mbstowcs_s"); pwcstombs_s = (void *)GetProcAddress(hMsvcrt, "wcstombs_s"); + pwcsrtombs = (void *)GetProcAddress(hMsvcrt, "wcsrtombs"); p_gcvt_s = (void *)GetProcAddress(hMsvcrt, "_gcvt_s"); p_itoa_s = (void *)GetProcAddress(hMsvcrt, "_itoa_s"); p_strlwr_s = (void *)GetProcAddress(hMsvcrt, "_strlwr_s"); diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index c0cdde16a35..5a7a43cfb93 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -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) { char default_char = '\0'; @@ -302,14 +302,14 @@ MSVCRT_size_t CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr, if(!mbstr) 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]; MSVCRT_size_t i, size; 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) return -1; 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