Daniel Lehman : msvcp90: Set state at end of istream<>::ignore.

Alexandre Julliard julliard at winehq.org
Thu Oct 25 13:50:45 CDT 2012


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

Author: Daniel Lehman <dlehman at esri.com>
Date:   Thu Sep 27 08:18:14 2012 -0700

msvcp90: Set state at end of istream<>::ignore.

---

 dlls/msvcp90/ios.c       |   32 +++++++++++++-----
 dlls/msvcp90/tests/ios.c |   79 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+), 9 deletions(-)

diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c
index 173ef84..9b0cb24 100644
--- a/dlls/msvcp90/ios.c
+++ b/dlls/msvcp90/ios.c
@@ -7500,7 +7500,8 @@ DEFINE_THISCALL_WRAPPER(basic_istream_char_ignore, 12)
 basic_istream_char* __thiscall basic_istream_char_ignore(basic_istream_char *this, streamsize count, int delim)
 {
     basic_ios_char *base = basic_istream_char_get_basic_ios(this);
-    int ch = delim;
+    int ch = (unsigned char)delim;
+    unsigned int state;
 
     TRACE("(%p %ld %d)\n", this, count, delim);
 
@@ -7508,22 +7509,28 @@ basic_istream_char* __thiscall basic_istream_char_ignore(basic_istream_char *thi
 
     if(basic_istream_char_sentry_create(this, TRUE)) {
         basic_streambuf_char *strbuf = basic_ios_char_rdbuf_get(base);
+        state = IOSTATE_goodbit;
 
         while(count > 0) {
             ch = basic_streambuf_char_sbumpc(strbuf);
 
-            if(ch==EOF || ch==delim)
+            if(ch==EOF) {
+                state = IOSTATE_eofbit;
+                break;
+            }
+
+            if(ch==(unsigned char)delim)
                 break;
 
             this->count++;
             if(count != INT_MAX)
                 count--;
         }
-    }
+    }else
+        state = IOSTATE_failbit;
     basic_istream_char_sentry_destroy(this);
 
-    if(ch == EOF)
-        basic_ios_char_setstate(base, IOSTATE_eofbit);
+    basic_ios_char_setstate(base, state);
     return this;
 }
 
@@ -8759,6 +8766,7 @@ basic_istream_wchar* __thiscall basic_istream_wchar_ignore(basic_istream_wchar *
 {
     basic_ios_wchar *base = basic_istream_wchar_get_basic_ios(this);
     unsigned short ch = delim;
+    unsigned int state;
 
     TRACE("(%p %ld %d)\n", this, count, delim);
 
@@ -8766,22 +8774,28 @@ basic_istream_wchar* __thiscall basic_istream_wchar_ignore(basic_istream_wchar *
 
     if(basic_istream_wchar_sentry_create(this, TRUE)) {
         basic_streambuf_wchar *strbuf = basic_ios_wchar_rdbuf_get(base);
+        state = IOSTATE_goodbit;
 
         while(count > 0) {
             ch = basic_streambuf_wchar_sbumpc(strbuf);
 
-            if(ch==WEOF || ch==delim)
+            if(ch==WEOF) {
+                state = IOSTATE_eofbit;
+                break;
+            }
+
+            if(ch==delim)
                 break;
 
             this->count++;
             if(count != INT_MAX)
                 count--;
         }
-    }
+    }else
+        state = IOSTATE_failbit;
     basic_istream_wchar_sentry_destroy(this);
 
-    if(ch == WEOF)
-        basic_ios_wchar_setstate(base, IOSTATE_eofbit);
+    basic_ios_wchar_setstate(base, state);
     return this;
 }
 
diff --git a/dlls/msvcp90/tests/ios.c b/dlls/msvcp90/tests/ios.c
index dadc63d..b85662f 100644
--- a/dlls/msvcp90/tests/ios.c
+++ b/dlls/msvcp90/tests/ios.c
@@ -355,11 +355,13 @@ static basic_istream_char* (*__thiscall p_basic_istream_char_read_uint64)(basic_
 static basic_istream_char* (*__thiscall p_basic_istream_char_read_double)(basic_istream_char*, double*);
 static int (*__thiscall p_basic_istream_char_get)(basic_istream_char*);
 static MSVCP_bool (*__thiscall p_basic_istream_char_ipfx)(basic_istream_char*, MSVCP_bool);
+static basic_istream_char* (*__thiscall p_basic_istream_char_ignore)(basic_istream_char*, streamsize, int);
 
 static basic_istream_wchar* (*__thiscall p_basic_istream_wchar_read_uint64)(basic_istream_wchar*, unsigned __int64*);
 static basic_istream_wchar* (*__thiscall p_basic_istream_wchar_read_double)(basic_istream_wchar*, double *);
 static int (*__thiscall p_basic_istream_wchar_get)(basic_istream_wchar*);
 static MSVCP_bool (*__thiscall p_basic_istream_wchar_ipfx)(basic_istream_wchar*, MSVCP_bool);
+static basic_istream_wchar* (*__thiscall p_basic_istream_wchar_ignore)(basic_istream_wchar*, streamsize, unsigned short);
 
 /* ostream */
 static basic_ostream_char* (*__thiscall p_basic_ostream_char_print_double)(basic_ostream_char*, double);
@@ -518,6 +520,8 @@ static BOOL init(void)
             "?get@?$basic_istream at DU?$char_traits at D@std@@@std@@QEAAHXZ");
         SET(p_basic_istream_char_ipfx,
             "?ipfx@?$basic_istream at DU?$char_traits at D@std@@@std@@QEAA_N_N at Z");
+        SET(p_basic_istream_char_ignore,
+            "?ignore@?$basic_istream at DU?$char_traits at D@std@@@std@@QEAAAEAV12 at _JH@Z");
 
         SET(p_basic_istream_wchar_read_uint64,
             "??5?$basic_istream at _WU?$char_traits at _W@std@@@std@@QEAAAEAV01 at AEA_K@Z");
@@ -527,6 +531,8 @@ static BOOL init(void)
             "?get@?$basic_istream at _WU?$char_traits at _W@std@@@std@@QEAAGXZ");
         SET(p_basic_istream_wchar_ipfx,
             "?ipfx@?$basic_istream at _WU?$char_traits at _W@std@@@std@@QEAA_N_N at Z");
+        SET(p_basic_istream_wchar_ignore,
+            "?ignore@?$basic_istream at _WU?$char_traits at _W@std@@@std@@QEAAAEAV12 at _JG@Z");
 
         SET(p_basic_ostream_char_print_double,
             "??6?$basic_ostream at DU?$char_traits at D@std@@@std@@QEAAAEAV01 at N@Z");
@@ -594,6 +600,8 @@ static BOOL init(void)
             "?get@?$basic_istream at DU?$char_traits at D@std@@@std@@QAEHXZ");
         SET(p_basic_istream_char_ipfx,
             "?ipfx@?$basic_istream at DU?$char_traits at D@std@@@std@@QAE_N_N at Z");
+        SET(p_basic_istream_char_ignore,
+            "?ignore@?$basic_istream at DU?$char_traits at D@std@@@std@@QAEAAV12 at HH@Z");
 
         SET(p_basic_istream_wchar_read_uint64,
             "??5?$basic_istream at _WU?$char_traits at _W@std@@@std@@QAEAAV01 at AA_K@Z");
@@ -603,6 +611,8 @@ static BOOL init(void)
             "?get@?$basic_istream at _WU?$char_traits at _W@std@@@std@@QAEGXZ");
         SET(p_basic_istream_wchar_ipfx,
             "?ipfx@?$basic_istream at _WU?$char_traits at _W@std@@@std@@QAE_N_N at Z");
+        SET(p_basic_istream_wchar_ignore,
+            "?ignore@?$basic_istream at _WU?$char_traits at _W@std@@@std@@QAEAAV12 at HG@Z");
 
         SET(p_basic_ostream_char_print_double,
             "??6?$basic_ostream at DU?$char_traits at D@std@@@std@@QAEAAV01 at N@Z");
@@ -1124,6 +1134,74 @@ static void test_istream_ipfx(void)
 }
 
 
+static void test_istream_ignore(void)
+{
+    unsigned short testus, nextus;
+    basic_stringstream_wchar wss;
+    basic_stringstream_char ss;
+    basic_string_wchar wstr;
+    basic_string_char str;
+    IOSB_iostate state;
+    wchar_t wide[64];
+    int i, next;
+
+    struct _test_istream_ignore {
+        const char  *str;
+        streamsize   count;
+        int          delim;
+        IOSB_iostate state;
+        int          next;
+    } tests[] = {
+        /* string       count delim state            next */
+        { "",           0,    '\n', IOSTATE_goodbit, EOF }, /* empty string */
+
+        /* different counts */
+        { "ABCDEF",     2,    '\n', IOSTATE_goodbit, 'C' }, /* easy case */
+        { "ABCDEF",     42,   '\n', IOSTATE_eofbit,  EOF }, /* ignore too much */
+        { "ABCDEF",    -2,    '\n', IOSTATE_goodbit, 'A' }, /* negative count */
+        { "ABCDEF",     6,    '\n', IOSTATE_goodbit, EOF }, /* is eof not set at end */
+        { "ABCDEF",     7,    '\n', IOSTATE_eofbit,  EOF }, /* eof is set just after end */
+
+        /* different delimiters */
+        { "ABCDEF",       42, '\0', IOSTATE_eofbit,  EOF }, /* null as delim */
+        { "ABC DEF GHI",  0,  ' ',  IOSTATE_goodbit, 'A' },
+        { "ABC DEF GHI",  42, ' ',  IOSTATE_goodbit, 'D' },
+        { "ABC DEF\tGHI", 42, '\t', IOSTATE_goodbit, 'G' },
+        { "ABC ",         42, ' ',  IOSTATE_goodbit, EOF }, /* delim at end */
+    };
+
+    for(i=0; i<sizeof(tests)/sizeof(tests[0]); i++) {
+        /* char version */
+        call_func2(p_basic_string_char_ctor_cstr, &str, tests[i].str);
+        call_func4(p_basic_stringstream_char_ctor_str, &ss, &str, OPENMODE_out|OPENMODE_in, TRUE);
+
+        call_func3(p_basic_istream_char_ignore, &ss.base.base1, tests[i].count, tests[i].delim);
+        state = (IOSB_iostate)call_func1(p_ios_base_rdstate, &ss.basic_ios.base);
+        next  = (int)call_func1(p_basic_istream_char_get, &ss.base.base1);
+
+        ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
+        ok(tests[i].next  == next,  "wrong next, expected = %c (%i) found = %c (%i)\n", tests[i].next, tests[i].next, next, next);
+
+        call_func1(p_basic_stringstream_char_vbase_dtor, &ss);
+
+        /* wchar_t version */
+        AtoW(wide, tests[i].str, strlen(tests[i].str));
+        call_func2(p_basic_string_wchar_ctor_cstr, &wstr, wide);
+        call_func4(p_basic_stringstream_wchar_ctor_str, &wss, &wstr, OPENMODE_out|OPENMODE_in, TRUE);
+
+        call_func3(p_basic_istream_wchar_ignore, &wss.base.base1, tests[i].count, tests[i].delim);
+        state  = (IOSB_iostate)call_func1(p_ios_base_rdstate, &wss.basic_ios.base);
+        nextus = (unsigned short)(int)call_func1(p_basic_istream_wchar_get, &wss.base.base1);
+
+        ok(tests[i].state == state, "wrong state, expected = %x found = %x\n", tests[i].state, state);
+        testus = tests[i].next == EOF ? WEOF : (unsigned short)tests[i].next;
+        ok(testus == nextus, "wrong next, expected = %c (%i) found = %c (%i)\n", testus, testus, nextus, nextus);
+
+        call_func1(p_basic_stringstream_wchar_vbase_dtor, &wss);
+    }
+}
+
+
 START_TEST(ios)
 {
     if(!init())
@@ -1133,6 +1211,7 @@ START_TEST(ios)
     test_num_get_get_double();
     test_num_put_put_double();
     test_istream_ipfx();
+    test_istream_ignore();
 
     ok(!invalid_parameter, "invalid_parameter_handler was invoked too many times\n");
 }




More information about the wine-cvs mailing list