=?UTF-8?Q?Iv=C3=A1n=20Matellanes=20?=: msvcirt: Implement stdiobuf::sync.

Alexandre Julliard julliard at wine.codeweavers.com
Wed Oct 7 10:00:47 CDT 2015


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

Author: Iván Matellanes <matellanesivan at gmail.com>
Date:   Fri Oct  2 15:03:23 2015 +0200

msvcirt: Implement stdiobuf::sync.

Signed-off-by: Iván Matellanes <matellanesivan at gmail.com>
Signed-off-by: Piotr Caban <piotr at codeweavers.com>

---

 dlls/msvcirt/msvcirt.c       | 27 +++++++++++++++++++--
 dlls/msvcirt/tests/msvcirt.c | 56 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 81 insertions(+), 2 deletions(-)

diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index 2b54f5b..602ab77 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -1598,8 +1598,31 @@ FILE* __thiscall stdiobuf_stdiofile(stdiobuf *this)
 DEFINE_THISCALL_WRAPPER(stdiobuf_sync, 4)
 int __thiscall stdiobuf_sync(stdiobuf *this)
 {
-    FIXME("(%p) stub\n", this);
-    return EOF;
+    TRACE("(%p)\n", this);
+    if (this->base.unbuffered)
+        return 0;
+    /* flush the put area */
+    if (call_streambuf_overflow(&this->base, EOF) == EOF)
+        return EOF;
+    /* flush the get area */
+    if (this->base.gptr < this->base.egptr) {
+        char *ptr;
+        int fd, mode, offset = this->base.egptr - this->base.gptr;
+        if ((fd = fileno(this->file)) < 0)
+            return EOF;
+        mode = _setmode(fd, _O_TEXT);
+        _setmode(fd, mode);
+        if (mode & _O_TEXT) {
+            /* in text mode, '\n' in the buffer means '\r\n' in the file */
+            for (ptr = this->base.gptr; ptr < this->base.egptr; ptr++)
+                if (*ptr == '\n')
+                    offset++;
+        }
+        if (fseek(this->file, -offset, SEEK_CUR))
+            return EOF;
+        this->base.gptr = this->base.egptr;
+    }
+    return 0;
 }
 
 /* ?underflow at stdiobuf@@UAEHXZ */
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 1f85186..8bc45c1 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -210,6 +210,7 @@ static int (*__thiscall p_strstreambuf_underflow)(strstreambuf*);
 static stdiobuf* (*__thiscall p_stdiobuf_file_ctor)(stdiobuf*, FILE*);
 static void (*__thiscall p_stdiobuf_dtor)(stdiobuf*);
 static int (*__thiscall p_stdiobuf_overflow)(stdiobuf*, int);
+static int (*__thiscall p_stdiobuf_sync)(stdiobuf*);
 static int (*__thiscall p_stdiobuf_underflow)(stdiobuf*);
 
 /* ios */
@@ -373,6 +374,7 @@ static BOOL init(void)
         SET(p_stdiobuf_file_ctor, "??0stdiobuf@@QEAA at PEAU_iobuf@@@Z");
         SET(p_stdiobuf_dtor, "??1stdiobuf@@UEAA at XZ");
         SET(p_stdiobuf_overflow, "?overflow at stdiobuf@@UEAAHH at Z");
+        SET(p_stdiobuf_sync, "?sync at stdiobuf@@UEAAHXZ");
         SET(p_stdiobuf_underflow, "?underflow at stdiobuf@@UEAAHXZ");
 
         SET(p_ios_copy_ctor, "??0ios@@IEAA at AEBV0@@Z");
@@ -456,6 +458,7 @@ static BOOL init(void)
         SET(p_stdiobuf_file_ctor, "??0stdiobuf@@QAE at PAU_iobuf@@@Z");
         SET(p_stdiobuf_dtor, "??1stdiobuf@@UAE at XZ");
         SET(p_stdiobuf_overflow, "?overflow at stdiobuf@@UAEHH at Z");
+        SET(p_stdiobuf_sync, "?sync at stdiobuf@@UAEHXZ");
         SET(p_stdiobuf_underflow, "?underflow at stdiobuf@@UAEHXZ");
 
         SET(p_ios_copy_ctor, "??0ios@@IAE at ABV0@@Z");
@@ -1960,6 +1963,59 @@ static void test_stdiobuf(void)
     ret = (int) call_func1(p_stdiobuf_underflow, &stb2);
     ok(ret == EOF, "expected EOF got %d\n", ret);
 
+    /* sync */
+    ret = (int) call_func1(p_stdiobuf_sync, &stb1);
+    ok(ret == 0, "expected 0 got %d\n", ret);
+    stb1.base.gptr = stb1.base.eback;
+    ret = (int) call_func1(p_stdiobuf_sync, &stb1);
+    ok(ret == 0, "expected 0 got %d\n", ret);
+    stb1.base.unbuffered = 0;
+    ret = (int) call_func1(p_stdiobuf_sync, &stb1);
+    ok(ret == EOF, "expected EOF got %d\n", ret);
+    ok(stb1.base.pbase == stb1.base.base + 256, "wrong put base, expected %p got %p\n", stb1.base.base + 256, stb1.base.pbase);
+    ok(stb1.base.pptr == stb1.base.base + 256, "wrong put pointer, expected %p got %p\n", stb1.base.base + 256, stb1.base.pptr);
+    ok(stb1.base.epptr == stb1.base.base + 512, "wrong put end, expected %p got %p\n", stb1.base.base + 512, stb1.base.epptr);
+    stb1.base.gptr = stb1.base.egptr;
+    ret = (int) call_func1(p_stdiobuf_sync, &stb1);
+    ok(ret == 0, "expected 0 got %d\n", ret);
+    stb1.base.eback = stb1.base.gptr = stb1.base.egptr = NULL;
+    stb1.base.pptr = stb1.base.epptr;
+    ret = (int) call_func1(p_stdiobuf_sync, &stb1);
+    ok(ret == EOF, "expected EOF got %d\n", ret);
+    ok(stb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, stb1.base.gptr);
+    stb1.base.pptr = stb1.base.pbase;
+    ret = (int) call_func1(p_stdiobuf_sync, &stb1);
+    ok(ret == 0, "expected 0 got %d\n", ret);
+    ok(stb1.base.gptr == NULL, "wrong get pointer, expected %p got %p\n", NULL, stb1.base.gptr);
+    stb1.base.unbuffered = 1;
+    stb2.base.unbuffered = 0;
+    stb2.base.egptr = stb2.base.ebuf;
+    ret = (int) call_func1(p_stdiobuf_sync, &stb2);
+    ok(ret == EOF, "expected EOF got %d\n", ret);
+    ok(stb2.base.pbase == stb2.base.base + 32, "wrong put base, expected %p got %p\n", stb2.base.base + 32, stb2.base.pbase);
+    ok(stb2.base.pptr == stb2.base.base + 32, "wrong put pointer, expected %p got %p\n", stb2.base.base + 32, stb2.base.pptr);
+    ok(stb2.base.epptr == stb2.base.base + 64, "wrong put end, expected %p got %p\n", stb2.base.base + 64, stb2.base.epptr);
+    stb2.base.egptr = stb2.base.pbase;
+    stb2.base.gptr = stb2.base.egptr - 25;
+    ret = (int) call_func1(p_stdiobuf_sync, &stb2);
+    ok(ret == EOF, "expected EOF got %d\n", ret);
+    ret = (int) call_func3(p_streambuf_xsputn, &stb2.base, "Never gonna make you cry", 24);
+    ok(ret == 24, "expected 24 got %d\n", ret);
+    ret = (int) call_func1(p_stdiobuf_sync, &stb2);
+    ok(ret == 0, "expected 0 got %d\n", ret);
+    ok(ftell(stb2.file) == 23, "ftell failed\n");
+    ok(fseek(stb2.file, 3, SEEK_SET) == 0, "fseek failed\n");
+    stb2.base.gptr = stb2.base.egptr - 3;
+    strcpy(stb2.base.gptr, "a\nc");
+    ret = (int) call_func1(p_stdiobuf_sync, &stb2);
+    ok(ret == EOF, "expected EOF got %d\n", ret);
+    ok(stb2.base.gptr == stb2.base.egptr - 3, "wrong get pointer, expected %p got %p\n", stb2.base.egptr - 3, stb2.base.gptr);
+    *(stb2.base.gptr+1) = 'b';
+    ret = (int) call_func1(p_stdiobuf_sync, &stb2);
+    ok(ret == 0, "expected 0 got %d\n", ret);
+    ok(stb2.base.gptr == stb2.base.egptr, "wrong get pointer, expected %p got %p\n", stb2.base.egptr, stb2.base.gptr);
+    stb2.base.unbuffered = 1;
+
     call_func1(p_stdiobuf_dtor, &stb1);
     call_func1(p_stdiobuf_dtor, &stb2);
     fclose(file1);




More information about the wine-cvs mailing list