[v3 1/4] msvcirt: Implement istream::operator>> for strings.

Iván Matellanes matellanesivan at gmail.com
Wed Aug 3 04:34:25 CDT 2016


v3: Check that str != NULL before entering the loop.

Signed-off-by: Iván Matellanes <matellanesivan at gmail.com>
---
 dlls/msvcirt/msvcirt.c       | 25 ++++++++++++++++++++++++-
 dlls/msvcirt/tests/msvcirt.c | 31 +++++++++++++++++++++++++++++--
 2 files changed, 53 insertions(+), 3 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 361285a..605072a 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -3514,7 +3514,30 @@ istream* __thiscall istream_read_char(istream *this, char *ch)
 DEFINE_THISCALL_WRAPPER(istream_read_str, 8)
 istream* __thiscall istream_read_str(istream *this, char *str)
 {
-    FIXME("(%p %p) stub\n", this, str);
+    ios *base = istream_get_ios(this);
+    int ch, count = 0;
+
+    TRACE("(%p %p)\n", this, str);
+
+    if (istream_ipfx(this, 0)) {
+        if (str) {
+            for (ch = streambuf_sgetc(base->sb);
+                count < (unsigned int) base->width - 1 && !isspace(ch);
+                ch = streambuf_snextc(base->sb)) {
+                if (ch == EOF) {
+                    base->state |= IOSTATE_eofbit;
+                    break;
+                }
+                str[count++] = ch;
+            }
+        }
+        if (!count) /* nothing to output */
+            base->state |= IOSTATE_failbit;
+        else /* append a null terminator */
+            str[count] = 0;
+        base->width = 0;
+        istream_isfx(this);
+    }
     return this;
 }
 
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index a706703..6d97566 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -328,6 +328,7 @@ static streampos (*__thiscall p_istream_tellg)(istream*);
 static int (*__thiscall p_istream_getint)(istream*, char*);
 static int (*__thiscall p_istream_getdouble)(istream*, char*, int);
 static istream* (*__thiscall p_istream_read_char)(istream*, char*);
+static istream* (*__thiscall p_istream_read_str)(istream*, char*);
 
 /* Emulate a __thiscall */
 #ifdef __i386__
@@ -544,6 +545,7 @@ static BOOL init(void)
         SET(p_istream_getint, "?getint at istream@@AEAAHPEAD at Z");
         SET(p_istream_getdouble, "?getdouble at istream@@AEAAHPEADH at Z");
         SET(p_istream_read_char, "??5istream@@QEAAAEAV0 at AEAD@Z");
+        SET(p_istream_read_str, "??5istream@@QEAAAEAV0 at PEAD@Z");
     } else {
         p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z");
         p_operator_delete = (void*)GetProcAddress(msvcrt, "??3 at YAXPAX@Z");
@@ -682,6 +684,7 @@ static BOOL init(void)
         SET(p_istream_getint, "?getint at istream@@AAEHPAD at Z");
         SET(p_istream_getdouble, "?getdouble at istream@@AAEHPADH at Z");
         SET(p_istream_read_char, "??5istream@@QAEAAV0 at AAD@Z");
+        SET(p_istream_read_str, "??5istream@@QAEAAV0 at PAD@Z");
     }
     SET(p_ios_static_lock, "?x_lockc at ios@@0U_CRT_CRITICAL_SECTION@@A");
     SET(p_ios_lockc, "?lockc at ios@@KAXXZ");
@@ -4863,9 +4866,10 @@ static void test_istream_read(void)
     /* makes tables narrower */
     const ios_io_state IOSTATE_faileof = IOSTATE_failbit|IOSTATE_eofbit;
 
-    char c, char_out[] = {-85, ' ', 'a', -50};
+    char c, st[8], char_out[] = {-85, ' ', 'a', -50};
+    const char *str_out[] = {"AAAAAAA", "abc", "a", "abc", "ab", "abcde"};
     struct istream_read_test {
-        enum { type_chr } type;
+        enum { type_chr, type_str } type;
         const char *stream_content;
         ios_flags flags;
         int width;
@@ -4882,6 +4886,22 @@ static void test_istream_read(void)
         {type_chr, " abc ", FLAGS_skipws, 6, /* 'a' */ 2, IOSTATE_goodbit, 6, 2, FALSE},
         {type_chr, " a",    FLAGS_skipws, 0, /* 'a' */ 2, IOSTATE_goodbit, 0, 2, FALSE},
         {type_chr, "\xce",  0,            6, /* -50 */ 3, IOSTATE_goodbit, 6, 1, FALSE},
+        /* str */
+        {type_str, "",        FLAGS_skipws, 6, /* "AAAAAAA" */ 0, IOSTATE_faileof, 6, 0, FALSE},
+        {type_str, " ",       FLAGS_skipws, 6, /* "AAAAAAA" */ 0, IOSTATE_faileof, 6, 1, FALSE},
+        {type_str, " abc",    FLAGS_skipws, 6, /* "abc" */     1, IOSTATE_eofbit,  0, 4, FALSE},
+        {type_str, " abc ",   FLAGS_skipws, 6, /* "abc" */     1, IOSTATE_goodbit, 0, 4, FALSE},
+        {type_str, " a\tc",   FLAGS_skipws, 6, /* "a" */       2, IOSTATE_goodbit, 0, 2, FALSE},
+        {type_str, " a\tc",   0,            6, /* "AAAAAAA" */ 0, IOSTATE_failbit, 0, 0, FALSE},
+        {type_str, "abcde\n", 0,            4, /* "abc" */     3, IOSTATE_goodbit, 0, 3, FALSE},
+        {type_str, "abc\n",   0,            4, /* "abc" */     3, IOSTATE_goodbit, 0, 3, FALSE},
+        {type_str, "ab\r\n",  0,            3, /* "ab" */      4, IOSTATE_goodbit, 0, 2, FALSE},
+        {type_str, "abc",     0,            4, /* "abc" */     3, IOSTATE_goodbit, 0, 3, FALSE},
+        {type_str, "abc",     0,            1, /* "AAAAAAA" */ 0, IOSTATE_failbit, 0, 0, FALSE},
+        {type_str, "\n",      0,            1, /* "AAAAAAA" */ 0, IOSTATE_failbit, 0, 0, FALSE},
+        {type_str, "abcde\n", 0,            0, /* "abcde" */   5, IOSTATE_goodbit, 0, 5, FALSE},
+        {type_str, "\n",      0,            0, /* "AAAAAAA" */ 0, IOSTATE_failbit, 0, 0, FALSE},
+        {type_str, "abcde",   0,           -1, /* "abcde" */   5, IOSTATE_eofbit,  0, 5, FALSE},
     };
 
     pssb = call_func2(p_strstreambuf_dynamic_ctor, &ssb, 64);
@@ -4907,6 +4927,13 @@ static void test_istream_read(void)
             ok(c == char_out[tests[i].expected_val], "Test %d: expected %d got %d\n", i,
                 char_out[tests[i].expected_val], c);
             break;
+        case type_str:
+            memset(st, 'A', sizeof(st));
+            st[7] = 0;
+            pis = call_func2(p_istream_read_str, &is, st);
+            ok(!strcmp(st, str_out[tests[i].expected_val]), "Test %d: expected %s got %s\n", i,
+                str_out[tests[i].expected_val], st);
+            break;
         }
 
         ok(pis == &is, "Test %d: wrong return, expected %p got %p\n", i, &is, pis);
-- 
2.7.4




More information about the wine-patches mailing list