Piotr Caban : msvcrt: Fixed fgetwc behavior on multibyte characters and Unicode files.

Alexandre Julliard julliard at winehq.org
Mon Mar 25 14:19:39 CDT 2013


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

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Wed Mar 20 10:40:45 2013 +0100

msvcrt: Fixed fgetwc behavior on multibyte characters and Unicode files.

---

 dlls/msvcrt/file.c   |   80 ++++++++++++++++++++++----------------------------
 dlls/msvcrt/msvcrt.h |    1 +
 2 files changed, 36 insertions(+), 45 deletions(-)

diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c
index 6e8b324..28dd132 100644
--- a/dlls/msvcrt/file.c
+++ b/dlls/msvcrt/file.c
@@ -3205,60 +3205,50 @@ char * CDECL MSVCRT_fgets(char *s, int size, MSVCRT_FILE* file)
 
 /*********************************************************************
  *		fgetwc (MSVCRT.@)
- *
- * In MSVCRT__O_TEXT mode, multibyte characters are read from the file, dropping
- * the CR from CR/LF combinations
  */
 MSVCRT_wint_t CDECL MSVCRT_fgetwc(MSVCRT_FILE* file)
 {
-  int c;
+    MSVCRT_wint_t ret;
+    int ch;
 
-  MSVCRT__lock_file(file);
-  if (!(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT))
-    {
-      MSVCRT_wchar_t wc;
-      unsigned int i;
-      int j;
-      char *chp, *wcp;
-      wcp = (char *)&wc;
-      for(i=0; i<sizeof(wc); i++)
-      {
-        if (file->_cnt>0) 
-        {
-          file->_cnt--;
-          chp = file->_ptr++;
-          wcp[i] = *chp;
-        } 
-        else
-        {
-          j = MSVCRT__filbuf(file);
-          if(file->_cnt<=0)
-          {
-            file->_flag |= (file->_cnt == 0) ? MSVCRT__IOEOF : MSVCRT__IOERR;
-            file->_cnt = 0;
+    MSVCRT__lock_file(file);
 
-            MSVCRT__unlock_file(file);
-            return MSVCRT_WEOF;
-          }
-          wcp[i] = j;
+    if((msvcrt_get_ioinfo(file->_file)->exflag & (EF_UTF8 | EF_UTF16))
+            || !(msvcrt_get_ioinfo(file->_file)->wxflag & WX_TEXT)) {
+        char *p;
+
+        for(p=(char*)&ret; (MSVCRT_wint_t*)p<&ret+1; p++) {
+            ch = MSVCRT_fgetc(file);
+            if(ch == MSVCRT_EOF) {
+                ret = MSVCRT_WEOF;
+                break;
+            }
+            *p = (char)ch;
+        }
+    }else {
+        char mbs[MSVCRT_MB_LEN_MAX];
+        int len = 0;
+
+        ch = MSVCRT_fgetc(file);
+        if(ch != MSVCRT_EOF) {
+            mbs[0] = (char)ch;
+            if(MSVCRT_isleadbyte((unsigned char)mbs[0])) {
+                ch = MSVCRT_fgetc(file);
+                if(ch != MSVCRT_EOF) {
+                    mbs[1] = (char)ch;
+                    len = 2;
+                }
+            }else {
+                len = 1;
+            }
         }
-      }
 
-      MSVCRT__unlock_file(file);
-      return wc;
-    }
-    
-  c = MSVCRT_fgetc(file);
-  if ((get_locinfo()->mb_cur_max > 1) && MSVCRT_isleadbyte(c))
-    {
-      FIXME("Treat Multibyte characters\n");
+        if(!len || MSVCRT_mbtowc(&ret, mbs, len)==-1)
+            ret = MSVCRT_WEOF;
     }
 
-  MSVCRT__unlock_file(file);
-  if (c == MSVCRT_EOF)
-    return MSVCRT_WEOF;
-  else
-    return (MSVCRT_wint_t)c;
+    MSVCRT__unlock_file(file);
+    return ret;
 }
 
 /*********************************************************************
diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h
index e2ff7a0..3bbbe93 100644
--- a/dlls/msvcrt/msvcrt.h
+++ b/dlls/msvcrt/msvcrt.h
@@ -945,6 +945,7 @@ int            __cdecl _getch(void);
 int            __cdecl _ismbblead(unsigned int);
 int            __cdecl _ismbclegal(unsigned int c);
 int            __cdecl _ismbstrail(const unsigned char* start, const unsigned char* str);
+int            __cdecl MSVCRT_mbtowc(MSVCRT_wchar_t*,const char*,MSVCRT_size_t);
 MSVCRT_size_t  __cdecl MSVCRT_mbstowcs(MSVCRT_wchar_t*,const char*,MSVCRT_size_t);
 MSVCRT_intptr_t __cdecl MSVCRT__spawnve(int,const char*,const char* const *,const char* const *);
 MSVCRT_intptr_t __cdecl MSVRT__spawnvpe(int,const char*,const char* const *,const char* const *);




More information about the wine-cvs mailing list