Module: wine Branch: master Commit: 7fa823e5fa39b53180378613cca3b1351c395898 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7fa823e5fa39b53180378613cc...
Author: Daniel Lehman dlehman@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@DU?$char_traits@D@std@@@std@@QEAAHXZ"); SET(p_basic_istream_char_ipfx, "?ipfx@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAA_N_N@Z"); + SET(p_basic_istream_char_ignore, + "?ignore@?$basic_istream@DU?$char_traits@D@std@@@std@@QEAAAEAV12@_JH@Z");
SET(p_basic_istream_wchar_read_uint64, "??5?$basic_istream@_WU?$char_traits@_W@std@@@std@@QEAAAEAV01@AEA_K@Z"); @@ -527,6 +531,8 @@ static BOOL init(void) "?get@?$basic_istream@_WU?$char_traits@_W@std@@@std@@QEAAGXZ"); SET(p_basic_istream_wchar_ipfx, "?ipfx@?$basic_istream@_WU?$char_traits@_W@std@@@std@@QEAA_N_N@Z"); + SET(p_basic_istream_wchar_ignore, + "?ignore@?$basic_istream@_WU?$char_traits@_W@std@@@std@@QEAAAEAV12@_JG@Z");
SET(p_basic_ostream_char_print_double, "??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QEAAAEAV01@N@Z"); @@ -594,6 +600,8 @@ static BOOL init(void) "?get@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEHXZ"); SET(p_basic_istream_char_ipfx, "?ipfx@?$basic_istream@DU?$char_traits@D@std@@@std@@QAE_N_N@Z"); + SET(p_basic_istream_char_ignore, + "?ignore@?$basic_istream@DU?$char_traits@D@std@@@std@@QAEAAV12@HH@Z");
SET(p_basic_istream_wchar_read_uint64, "??5?$basic_istream@_WU?$char_traits@_W@std@@@std@@QAEAAV01@AA_K@Z"); @@ -603,6 +611,8 @@ static BOOL init(void) "?get@?$basic_istream@_WU?$char_traits@_W@std@@@std@@QAEGXZ"); SET(p_basic_istream_wchar_ipfx, "?ipfx@?$basic_istream@_WU?$char_traits@_W@std@@@std@@QAE_N_N@Z"); + SET(p_basic_istream_wchar_ignore, + "?ignore@?$basic_istream@_WU?$char_traits@_W@std@@@std@@QAEAAV12@HG@Z");
SET(p_basic_ostream_char_print_double, "??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@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"); }