Piotr Caban : msvcrt: Fixed wcstombs(_s_l) implementation.
Alexandre Julliard
julliard at winehq.org
Thu May 6 11:13:23 CDT 2010
Module: wine
Branch: master
Commit: 335c9772ece4964c061526d8178348c6d1f61ac3
URL: http://source.winehq.org/git/wine.git/?a=commit;h=335c9772ece4964c061526d8178348c6d1f61ac3
Author: Piotr Caban <piotr at codeweavers.com>
Date: Thu May 6 14:27:57 2010 +0200
msvcrt: Fixed wcstombs(_s_l) implementation.
---
dlls/msvcrt/msvcrt.spec | 4 +-
dlls/msvcrt/wcs.c | 109 +++++++++++++++++++++++++++-------------------
2 files changed, 66 insertions(+), 47 deletions(-)
diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec
index 8655f6f..c7d6654 100644
--- a/dlls/msvcrt/msvcrt.spec
+++ b/dlls/msvcrt/msvcrt.spec
@@ -1040,7 +1040,7 @@
@ cdecl _wcstoi64(wstr ptr long) MSVCRT__wcstoi64
@ cdecl _wcstoi64_l(wstr ptr long ptr) MSVCRT__wcstoi64_l
# stub _wcstol_l
-# stub _wcstombs_l
+@ cdecl _wcstombs_l(ptr ptr long ptr) MSVCRT__wcstombs_l
@ cdecl _wcstombs_s_l(ptr ptr long wstr long ptr) MSVCRT__wcstombs_s_l
@ cdecl _wcstoui64(wstr ptr long) MSVCRT__wcstoui64
@ cdecl _wcstoui64_l(wstr ptr long ptr) MSVCRT__wcstoui64_l
@@ -1417,7 +1417,7 @@
@ cdecl wcstok(wstr wstr) MSVCRT_wcstok
# stub wcstok_s
@ cdecl wcstol(wstr ptr long) ntdll.wcstol
-@ cdecl wcstombs(ptr ptr long) ntdll.wcstombs
+@ cdecl wcstombs(ptr ptr long) MSVCRT_wcstombs
@ cdecl wcstombs_s(ptr ptr long wstr long) MSVCRT_wcstombs_s
@ cdecl wcstoul(wstr ptr long) ntdll.wcstoul
@ stub wcsxfrm #(ptr wstr long) MSVCRT_wcsxfrm
diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c
index 5334115..96a25e5 100644
--- a/dlls/msvcrt/wcs.c
+++ b/dlls/msvcrt/wcs.c
@@ -227,76 +227,95 @@ double CDECL MSVCRT__wcstod_l(const MSVCRT_wchar_t* str, MSVCRT_wchar_t** end,
}
/*********************************************************************
- * _wcstombs_s_l (MSVCRT.@)
+ * _wcstombs_l (MSVCRT.@)
*/
-int CDECL MSVCRT__wcstombs_s_l(MSVCRT_size_t *ret, char *mbstr,
- MSVCRT_size_t size, const MSVCRT_wchar_t *wcstr,
+MSVCRT_size_t CDECL MSVCRT__wcstombs_l(char *mbstr, const MSVCRT_wchar_t *wcstr,
MSVCRT_size_t count, MSVCRT__locale_t locale)
{
- char default_char = '\0', *p;
- int hlp, len;
-
- if(!size)
- return 0;
-
- if(!mbstr || !wcstr) {
- MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
- if(mbstr)
- *mbstr = '\0';
- *MSVCRT__errno() = MSVCRT_EINVAL;
- return MSVCRT_EINVAL;
- }
+ char default_char = '\0';
+ MSVCRT_size_t tmp;
+ BOOL used_default;
if(!locale)
locale = get_locale();
- if(size<=count)
- len = size;
- else if(count==_TRUNCATE)
- len = size-1;
- else
- len = count;
+ /* FIXME: Use wcslen here */
+ tmp = strlenW(wcstr);
+ if(tmp>count && mbstr)
+ tmp = count;
- p = mbstr;
- *ret = 0;
- while(1) {
- if(!len)
- break;
+ tmp = WideCharToMultiByte(locale->locinfo->lc_codepage, WC_NO_BEST_FIT_CHARS,
+ wcstr, tmp, mbstr, count, &default_char, &used_default);
- if(*wcstr == '\0') {
- *p = '\0';
- break;
- }
+ if(used_default)
+ return -1;
- hlp = WideCharToMultiByte(locale->locinfo->lc_codepage,
- WC_NO_BEST_FIT_CHARS, wcstr, 1, p, len, &default_char, NULL);
- if(!hlp || *p=='\0')
- break;
+ if(tmp<count && mbstr)
+ mbstr[tmp] = '\0';
- p += hlp;
- len -= hlp;
+ return tmp;
+}
- wcstr++;
- *ret += 1;
+/*********************************************************************
+ * wcstombs (MSVCRT.@)
+ */
+MSVCRT_size_t CDECL MSVCRT_wcstombs(char *mbstr, const MSVCRT_wchar_t *wcstr,
+ MSVCRT_size_t count)
+{
+ return MSVCRT__wcstombs_l(mbstr, wcstr, count, NULL);
+}
+
+/*********************************************************************
+ * _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)
+{
+ MSVCRT_size_t conv;
+
+ if(!mbstr && !size) {
+ conv = MSVCRT__wcstombs_l(NULL, wcstr, 0, locale);
+ if(ret)
+ *ret = conv;
+ return 0;
+ }
+
+ if(!wcstr || !mbstr) {
+ MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
+ if(mbstr && size)
+ mbstr[0] = '\0';
+ *MSVCRT__errno() = MSVCRT_EINVAL;
+ return MSVCRT_EINVAL;
}
- if(!len && size<=count) {
+ if(count==_TRUNCATE || size<count)
+ conv = size;
+ else
+ conv = count;
+
+ conv = MSVCRT__wcstombs_l(mbstr, wcstr, conv, locale);
+ if(conv<size)
+ mbstr[conv++] = '\0';
+ else if(conv==size && (count==_TRUNCATE || mbstr[conv-1]=='\0'))
+ mbstr[conv-1] = '\0';
+ else {
MSVCRT__invalid_parameter(NULL, NULL, NULL, 0, 0);
- *mbstr = '\0';
+ if(size)
+ mbstr[0] = '\0';
*MSVCRT__errno() = MSVCRT_ERANGE;
return MSVCRT_ERANGE;
}
- if(*wcstr == '\0')
- *ret += 1;
- *p = '\0';
+ if(ret)
+ *ret = conv;
return 0;
}
/*********************************************************************
* wcstombs_s (MSVCRT.@)
*/
-int 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)
{
return MSVCRT__wcstombs_s_l(ret, mbstr, size, wcstr, count, NULL);
More information about the wine-cvs
mailing list