Piotr Caban : msvcp90: Added ctype<char>::tolower functions implementation.

Alexandre Julliard julliard at winehq.org
Wed Dec 21 12:38:09 CST 2011


Module: wine
Branch: master
Commit: 283c07b8ceae3bec3816eaf38581d6fbe37c9434
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=283c07b8ceae3bec3816eaf38581d6fbe37c9434

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Dec 21 15:59:09 2011 +0100

msvcp90: Added ctype<char>::tolower functions implementation.

---

 dlls/msvcp90/locale.c     |   88 +++++++++++++++++++++++++++++++++++++++-----
 dlls/msvcp90/msvcp90.h    |    1 +
 dlls/msvcp90/msvcp90.spec |    2 +-
 dlls/msvcrt/locale.c      |    4 +-
 dlls/msvcrt/msvcrt.h      |    2 +-
 5 files changed, 83 insertions(+), 14 deletions(-)

diff --git a/dlls/msvcp90/locale.c b/dlls/msvcp90/locale.c
index 95b5407..39f01bf 100644
--- a/dlls/msvcp90/locale.c
+++ b/dlls/msvcp90/locale.c
@@ -26,12 +26,14 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winnls.h"
+#include "wine/unicode.h"
 #include "wine/debug.h"
 WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
 
 char* __cdecl _Getdays(void);
 char* __cdecl _Getmonths(void);
 void* __cdecl _Gettnames(void);
+unsigned int __cdecl ___lc_codepage_func(void);
 
 typedef int category;
 
@@ -1397,26 +1399,92 @@ const char* __thiscall ctype_char__Widen_s(const ctype_char *this,
 /* ?_Getcat@?$ctype at D@std@@SA_KPEAPEBVfacet at locale@2 at PEBV42@@Z */
 MSVCP_size_t __cdecl ctype_char__Getcat(const locale_facet **facet, const locale *loc)
 {
-    FIXME("(%p %p) stub\n", facet, loc);
-    return 0;
+    TRACE("(%p %p)\n", facet, loc);
+
+    if(facet && !*facet) {
+        _Locinfo locinfo;
+
+        *facet = MSVCRT_operator_new(sizeof(ctype_char));
+        if(!*facet) {
+            ERR("Out of memory\n");
+            throw_exception(EXCEPTION_BAD_ALLOC, NULL);
+            return 0;
+        }
+
+        _Locinfo_ctor_cstr(&locinfo, MSVCP_basic_string_char_c_str(&loc->ptr->name));
+        ctype_char_ctor_locinfo((ctype_char*)*facet, &locinfo, 0);
+        _Locinfo_dtor(&locinfo);
+    }
+
+    return LC_CTYPE;
+}
+
+/* _Tolower */
+int __cdecl _Tolower(int ch, const _Ctypevec *ctype)
+{
+    unsigned int cp;
+
+    TRACE("%d %p\n", ch, ctype);
+
+    if(ctype)
+        cp = ctype->page;
+    else
+        cp = ___lc_codepage_func();
+
+    /* Don't convert to unicode in case of C locale */
+    if(!cp) {
+        if(ch>='A' && ch<='Z')
+            ch = ch-'A'+'a';
+        return ch;
+    } else {
+        WCHAR wide, lower;
+        char str[2];
+        int size;
+
+        if(ch > 255) {
+            str[0] = (ch>>8) & 255;
+            str[1] = ch & 255;
+            size = 2;
+        } else {
+            str[0] = ch & 255;
+            size = 1;
+        }
+
+        if(!MultiByteToWideChar(cp, MB_ERR_INVALID_CHARS, str, size, &wide, 1))
+            return ch;
+
+        lower = tolowerW(wide);
+        if(lower == wide)
+            return ch;
+
+        WideCharToMultiByte(cp, 0, &lower, 1, str, 2, NULL, NULL);
+
+        return str[0] + (str[1]<<8);
+    }
 }
 
 /* ?do_tolower@?$ctype at D@std@@MBEDD at Z */
 /* ?do_tolower@?$ctype at D@std@@MEBADD at Z */
+#define call_ctype_char_do_tolower_ch(this, ch) CALL_VTBL_FUNC(this, 8, \
+        char, (const ctype_char*, char), (this, ch))
 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower_ch, 8)
 char __thiscall ctype_char_do_tolower_ch(const ctype_char *this, char ch)
 {
-    FIXME("(%p %c) stub\n", this, ch);
-    return 0;
+    TRACE("(%p %c)\n", this, ch);
+    return _Tolower(ch, &this->ctype);
 }
 
 /* ?do_tolower@?$ctype at D@std@@MBEPBDPADPBD at Z */
 /* ?do_tolower@?$ctype at D@std@@MEBAPEBDPEADPEBD at Z */
+#define call_ctype_char_do_tolower(this, first, last) CALL_VTBL_FUNC(this, 4, \
+        const char*, (const ctype_char*, char*, const char*), (this, first, last))
 DEFINE_THISCALL_WRAPPER(ctype_char_do_tolower, 12)
 const char* __thiscall ctype_char_do_tolower(const ctype_char *this, char *first, const char *last)
 {
-    FIXME("(%p %p %p) stub\n", this, first, last);
-    return NULL;
+    TRACE("(%p %p %p)\n", this, first, last);
+    for(; first<last; first++)
+        *first = _Tolower(*first, &this->ctype);
+    return last;
 }
 
 /* ?tolower@?$ctype at D@std@@QBEDD at Z */
@@ -1424,8 +1492,8 @@ const char* __thiscall ctype_char_do_tolower(const ctype_char *this, char *first
 DEFINE_THISCALL_WRAPPER(ctype_char_tolower_ch, 8)
 char __thiscall ctype_char_tolower_ch(const ctype_char *this, char ch)
 {
-    FIXME("(%p %c) stub\n", this, ch);
-    return 0;
+    TRACE("(%p %c)\n", this, ch);
+    return call_ctype_char_do_tolower_ch(this, ch);
 }
 
 /* ?tolower@?$ctype at D@std@@QBEPBDPADPBD at Z */
@@ -1433,8 +1501,8 @@ char __thiscall ctype_char_tolower_ch(const ctype_char *this, char ch)
 DEFINE_THISCALL_WRAPPER(ctype_char_tolower, 12)
 const char* __thiscall ctype_char_tolower(const ctype_char *this, char *first, const char *last)
 {
-    FIXME("(%p %p %p) stub\n", this, first, last);
-    return NULL;
+    TRACE("(%p %p %p)\n", this, first, last);
+    return call_ctype_char_do_tolower(this, first, last);
 }
 
 /* ?do_toupper@?$ctype at D@std@@MBEDD at Z */
diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h
index 63350fc..61567e8 100644
--- a/dlls/msvcp90/msvcp90.h
+++ b/dlls/msvcp90/msvcp90.h
@@ -136,6 +136,7 @@ const rtti_object_locator name ## _rtti = { \
 
 extern void *vtbl_wrapper_0;
 extern void *vtbl_wrapper_4;
+extern void *vtbl_wrapper_8;
 extern void *vtbl_wrapper_12;
 extern void *vtbl_wrapper_16;
 extern void *vtbl_wrapper_20;
diff --git a/dlls/msvcp90/msvcp90.spec b/dlls/msvcp90/msvcp90.spec
index f53b579..b7599ef 100644
--- a/dlls/msvcp90/msvcp90.spec
+++ b/dlls/msvcp90/msvcp90.spec
@@ -5798,7 +5798,7 @@
 @ stub _Stoulx
 @ cdecl _Strcoll(ptr ptr ptr ptr ptr)
 @ stub _Strxfrm
-@ stub _Tolower
+@ cdecl _Tolower(long ptr)
 @ stub _Toupper
 @ stub _Towlower
 @ stub _Towupper
diff --git a/dlls/msvcrt/locale.c b/dlls/msvcrt/locale.c
index c3a1c4b..60ea424 100644
--- a/dlls/msvcrt/locale.c
+++ b/dlls/msvcrt/locale.c
@@ -42,7 +42,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
 #define MAX_LOCALE_LENGTH 256
 MSVCRT__locale_t MSVCRT_locale = NULL;
 unsigned short *MSVCRT__pctype = NULL;
-int MSVCRT___lc_codepage = 0;
+unsigned int MSVCRT___lc_codepage = 0;
 int MSVCRT___lc_collate_cp = 0;
 LCID MSVCRT___lc_handle[MSVCRT_LC_MAX - MSVCRT_LC_MIN + 1] = { 0 };
 int MSVCRT___mb_cur_max = 1;
@@ -640,7 +640,7 @@ LCID* CDECL ___lc_handle_func(void)
 /*********************************************************************
  *      ___lc_codepage_func (MSVCRT.@)
  */
-int CDECL ___lc_codepage_func(void)
+unsigned int CDECL ___lc_codepage_func(void)
 {
     return MSVCRT___lc_codepage;
 }
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index 0695e6f..7ea0067 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -218,7 +218,7 @@ extern thread_data_t *msvcrt_get_thread_data(void);
 
 LCID MSVCRT_locale_to_LCID(const char *);
 extern MSVCRT__locale_t MSVCRT_locale;
-extern int MSVCRT___lc_codepage;
+extern unsigned int MSVCRT___lc_codepage;
 extern int MSVCRT___lc_collate_cp;
 extern WORD MSVCRT__ctype [257];
 




More information about the wine-cvs mailing list