Module: wine Branch: master Commit: 540f644ceb2d9b54b62c79d48ce1c4e6135051d6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=540f644ceb2d9b54b62c79d48c...
Author: Iván Matellanes matellanesivan@gmail.com Date: Tue Jun 16 11:32:29 2015 +0200
msvcirt: Add implementation of streambuf::sputc.
---
dlls/msvcirt/msvcirt.c | 10 ++++++++++ dlls/msvcirt/msvcirt.spec | 4 ++-- dlls/msvcirt/tests/msvcirt.c | 45 ++++++++++++++++++++++++++++++++++++++++++-- dlls/msvcrt20/msvcrt20.spec | 4 ++-- dlls/msvcrt40/msvcrt40.spec | 4 ++-- 5 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 03db71c..c2e6c14 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -355,6 +355,7 @@ int __thiscall streambuf_out_waiting(const streambuf *this)
/* Unexported */ DEFINE_THISCALL_WRAPPER(streambuf_overflow, 8) +#define call_streambuf_overflow(this, c) CALL_VTBL_FUNC(this, 28, int, (streambuf*, int), (this, c)) int __thiscall streambuf_overflow(streambuf *this, int c) { return EOF; @@ -528,6 +529,15 @@ int __thiscall streambuf_sgetc(streambuf *this) return call_streambuf_underflow(this); }
+/* ?sputc@streambuf@@QAEHH@Z */ +/* ?sputc@streambuf@@QEAAHH@Z */ +DEFINE_THISCALL_WRAPPER(streambuf_sputc, 8) +int __thiscall streambuf_sputc(streambuf *this, int ch) +{ + TRACE("(%p %d)\n", this, ch); + return (this->pptr < this->epptr) ? *this->pptr++ = ch : call_streambuf_overflow(this, ch); +} + /****************************************************************** * ??1ios@@UAE@XZ (MSVCRTI.@) * class ios & __thiscall ios::-ios<<(void) diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec index e879a7f..7d6df5f 100644 --- a/dlls/msvcirt/msvcirt.spec +++ b/dlls/msvcirt/msvcirt.spec @@ -704,8 +704,8 @@ @ stub -arch=win64 ?snextc@streambuf@@QEAAHXZ @ stub -arch=win32 ?sputbackc@streambuf@@QAEHD@Z # int __thiscall streambuf::sputbackc(char) @ stub -arch=win64 ?sputbackc@streambuf@@QEAAHD@Z -@ stub -arch=win32 ?sputc@streambuf@@QAEHH@Z # int __thiscall streambuf::sputc(int) -@ stub -arch=win64 ?sputc@streambuf@@QEAAHH@Z +@ thiscall -arch=win32 ?sputc@streambuf@@QAEHH@Z(ptr long) streambuf_sputc +@ cdecl -arch=win64 ?sputc@streambuf@@QEAAHH@Z(ptr long) streambuf_sputc @ stub -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z # int __thiscall streambuf::sputn(char const *,int) @ stub -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z @ stub -arch=win32 ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ # struct _iobuf * __thiscall stdiobuf::stdiofile(void) diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 7155740..6c60dd0 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -62,6 +62,7 @@ static void (*__thiscall p_streambuf_setb)(streambuf*, char*, char*, int); static void (*__thiscall p_streambuf_setlock)(streambuf*); static streambuf* (*__thiscall p_streambuf_setbuf)(streambuf*, char*, int); static int (*__thiscall p_streambuf_sgetc)(streambuf*); +static int (*__thiscall p_streambuf_sputc)(streambuf*, int); static int (*__thiscall p_streambuf_sync)(streambuf*); static void (*__thiscall p_streambuf_unlock)(streambuf*);
@@ -147,6 +148,7 @@ static BOOL init(void) SET(p_streambuf_setbuf, "?setbuf@streambuf@@UEAAPEAV1@PEADH@Z"); SET(p_streambuf_setlock, "?setlock@streambuf@@QEAAXXZ"); SET(p_streambuf_sgetc, "?sgetc@streambuf@@QEAAHXZ"); + SET(p_streambuf_sputc, "?sputc@streambuf@@QEAAHH@Z"); SET(p_streambuf_sync, "?sync@streambuf@@UEAAHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QEAAXXZ"); } else { @@ -163,6 +165,7 @@ static BOOL init(void) SET(p_streambuf_setbuf, "?setbuf@streambuf@@UAEPAV1@PADH@Z"); SET(p_streambuf_setlock, "?setlock@streambuf@@QAEXXZ"); SET(p_streambuf_sgetc, "?sgetc@streambuf@@QAEHXZ"); + SET(p_streambuf_sputc, "?sputc@streambuf@@QAEHH@Z"); SET(p_streambuf_sync, "?sync@streambuf@@UAEHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QAEXXZ"); } @@ -171,7 +174,20 @@ static BOOL init(void) return TRUE; }
-static int underflow_count; +static int overflow_count, underflow_count; +static streambuf *test_overflow_this; + +#ifdef __i386__ +static int __thiscall test_streambuf_overflow(int ch) +#else +static int __thiscall test_streambuf_overflow(streambuf *this, int ch) +#endif +{ + overflow_count++; + if (!test_overflow_this->unbuffered) + test_overflow_this->pptr = test_overflow_this->pbase + 5; + return ch; +}
#ifdef __i386__ static int __thiscall test_streambuf_underflow(void) @@ -243,10 +259,11 @@ static void test_streambuf(void) ok(sb3.ebuf == NULL, "wrong ebuf pointer, expected %p got %p\n", NULL, sb3.ebuf);
memcpy(test_streambuf_vtbl, sb.vtable, sizeof(test_streambuf_vtbl)); + test_streambuf_vtbl[7] = (vtable_ptr)&test_streambuf_overflow; test_streambuf_vtbl[8] = (vtable_ptr)&test_streambuf_underflow; sb2.vtable = test_streambuf_vtbl; sb3.vtable = test_streambuf_vtbl; - underflow_count = 0; + overflow_count = underflow_count = 0;
/* setlock */ ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock); @@ -430,6 +447,30 @@ static void test_streambuf(void) ok(underflow_count == 3, "no call to underflow expected\n"); ok(sb3.stored_char == 'b', "wrong stored character, expected 'b' got %c\n", sb3.stored_char);
+ /* sputc */ + *sb.pbase = 'a'; + ret = (int) call_func2(p_streambuf_sputc, &sb, 'c'); + ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret); + ok(overflow_count == 0, "no call to overflow expected\n"); + ok(*sb.pbase == 'c', "expected 'c' in the put area, got %c\n", *sb.pbase); + ok(sb.pptr == sb.pbase + 1, "wrong put pointer, expected %p got %p\n", sb.pbase + 1, sb.pptr); + test_overflow_this = &sb2; + ret = (int) call_func2(p_streambuf_sputc, &sb2, 'c'); + ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret); + ok(overflow_count == 1, "expected call to overflow\n"); + ok(sb2.pptr == sb2.pbase + 5, "wrong put pointer, expected %p got %p\n", sb2.pbase + 5, sb2.pptr); + test_overflow_this = &sb3; + ret = (int) call_func2(p_streambuf_sputc, &sb3, 'c'); + ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret); + ok(overflow_count == 2, "expected call to overflow\n"); + sb3.pbase = sb3.pptr = sb3.base; + sb3.epptr = sb3.ebuf; + ret = (int) call_func2(p_streambuf_sputc, &sb3, 'c'); + ok(ret == 'c', "wrong return value, expected 'c' got %d\n", ret); + ok(overflow_count == 2, "no call to overflow expected\n"); + ok(*sb3.pbase == 'c', "expected 'c' in the put area, got %c\n", *sb3.pbase); + sb3.pbase = sb3.pptr = sb3.epptr = NULL; + SetEvent(lock_arg.test[3]); WaitForSingleObject(thread, INFINITE);
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec index 14846f3..79f5902 100644 --- a/dlls/msvcrt20/msvcrt20.spec +++ b/dlls/msvcrt20/msvcrt20.spec @@ -692,8 +692,8 @@ @ stub -arch=win64 ?snextc@streambuf@@QEAAHXZ @ stub -arch=win32 ?sputbackc@streambuf@@QAEHD@Z @ stub -arch=win64 ?sputbackc@streambuf@@QEAAHD@Z -@ stub -arch=win32 ?sputc@streambuf@@QAEHH@Z -@ stub -arch=win64 ?sputc@streambuf@@QEAAHH@Z +@ thiscall -arch=win32 ?sputc@streambuf@@QAEHH@Z(ptr long) msvcirt.?sputc@streambuf@@QAEHH@Z +@ cdecl -arch=win64 ?sputc@streambuf@@QEAAHH@Z(ptr long) msvcirt.?sputc@streambuf@@QEAAHH@Z @ stub -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z @ stub -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z @ stub -arch=win32 ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index c794b6e..86d3985 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -764,8 +764,8 @@ @ stub -arch=win64 ?snextc@streambuf@@QEAAHXZ @ stub -arch=win32 ?sputbackc@streambuf@@QAEHD@Z @ stub -arch=win64 ?sputbackc@streambuf@@QEAAHD@Z -@ stub -arch=win32 ?sputc@streambuf@@QAEHH@Z -@ stub -arch=win64 ?sputc@streambuf@@QEAAHH@Z +@ thiscall -arch=win32 ?sputc@streambuf@@QAEHH@Z(ptr long) msvcirt.?sputc@streambuf@@QAEHH@Z +@ cdecl -arch=win64 ?sputc@streambuf@@QEAAHH@Z(ptr long) msvcirt.?sputc@streambuf@@QEAAHH@Z @ stub -arch=win32 ?sputn@streambuf@@QAEHPBDH@Z @ stub -arch=win64 ?sputn@streambuf@@QEAAHPEBDH@Z @ stub -arch=win32 ?stdiofile@stdiobuf@@QAEPAU_iobuf@@XZ