Module: wine Branch: master Commit: b08d0bc75de8224b95d299b83290fcbc0b00c18f URL: http://source.winehq.org/git/wine.git/?a=commit;h=b08d0bc75de8224b95d299b832...
Author: Iván Matellanes matellanesivan@gmail.com Date: Tue Jun 16 11:32:19 2015 +0200
msvcirt: Add implementation of streambuf::sgetc.
---
dlls/msvcirt/msvcirt.c | 19 ++++++++++++++++-- dlls/msvcirt/msvcirt.spec | 4 ++-- dlls/msvcirt/tests/msvcirt.c | 46 +++++++++++++++++++++++++++++++++++++++++++- dlls/msvcrt20/msvcrt20.spec | 4 ++-- dlls/msvcrt40/msvcrt40.spec | 4 ++-- 5 files changed, 68 insertions(+), 9 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c index 8c05fe3..03db71c 100644 --- a/dlls/msvcirt/msvcirt.c +++ b/dlls/msvcirt/msvcirt.c @@ -36,7 +36,7 @@ typedef struct { const vtable_ptr *vtable; int allocated; int unbuffered; - int unknown; + int stored_char; char *base; char *ebuf; char *pbase; @@ -98,7 +98,7 @@ streambuf* __thiscall streambuf_reserve_ctor(streambuf *this, char *buffer, int TRACE("(%p %p %d)\n", this, buffer, length); this->vtable = &MSVCP_streambuf_vtable; this->allocated = 0; - this->unknown = -1; + this->stored_char = EOF; this->do_lock = -1; this->base = NULL; streambuf_setbuf(this, buffer, length); @@ -480,6 +480,7 @@ int __thiscall streambuf_unbuffered_get(const streambuf *this)
/* Unexported */ DEFINE_THISCALL_WRAPPER(streambuf_underflow, 4) +#define call_streambuf_underflow(this) CALL_VTBL_FUNC(this, 32, int, (streambuf*), (this)) int __thiscall streambuf_underflow(streambuf *this) { return EOF; @@ -513,6 +514,20 @@ int __thiscall streambuf_xsputn(streambuf *this, const char *data, int length) return 0; }
+/* ?sgetc@streambuf@@QAEHXZ */ +/* ?sgetc@streambuf@@QEAAHXZ */ +DEFINE_THISCALL_WRAPPER(streambuf_sgetc, 4) +int __thiscall streambuf_sgetc(streambuf *this) +{ + TRACE("(%p)\n", this); + if (this->unbuffered) { + if (this->stored_char == EOF) + this->stored_char = call_streambuf_underflow(this); + return this->stored_char; + } else + return call_streambuf_underflow(this); +} + /****************************************************************** * ??1ios@@UAE@XZ (MSVCRTI.@) * class ios & __thiscall ios::-ios<<(void) diff --git a/dlls/msvcirt/msvcirt.spec b/dlls/msvcirt/msvcirt.spec index c9f5c06..e879a7f 100644 --- a/dlls/msvcirt/msvcirt.spec +++ b/dlls/msvcirt/msvcirt.spec @@ -693,8 +693,8 @@ @ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) streambuf_setp @ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z # int __thiscall stdiobuf::setrwbuf(int,int) @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z -@ stub -arch=win32 ?sgetc@streambuf@@QAEHXZ # int __thiscall streambuf::sgetc(void) -@ stub -arch=win64 ?sgetc@streambuf@@QEAAHXZ +@ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) streambuf_sgetc +@ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) streambuf_sgetc @ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z # int __thiscall streambuf::sgetn(char *,int) @ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z # @ extern ?sh_none@filebuf@@2HB # static int const filebuf::sh_none diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c index 1a6ce5d..7155740 100644 --- a/dlls/msvcirt/tests/msvcirt.c +++ b/dlls/msvcirt/tests/msvcirt.c @@ -28,7 +28,7 @@ typedef struct { const vtable_ptr *vtable; int allocated; int unbuffered; - int unknown; + int stored_char; char *base; char *ebuf; char *pbase; @@ -61,6 +61,7 @@ static void (*__thiscall p_streambuf_pbump)(streambuf*, int); 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_sync)(streambuf*); static void (*__thiscall p_streambuf_unlock)(streambuf*);
@@ -145,6 +146,7 @@ static BOOL init(void) SET(p_streambuf_setb, "?setb@streambuf@@IEAAXPEAD0H@Z"); 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_sync, "?sync@streambuf@@UEAAHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QEAAXXZ"); } else { @@ -160,6 +162,7 @@ static BOOL init(void) SET(p_streambuf_setb, "?setb@streambuf@@IAEXPAD0H@Z"); 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_sync, "?sync@streambuf@@UAEHXZ"); SET(p_streambuf_unlock, "?unlock@streambuf@@QAEXXZ"); } @@ -168,6 +171,18 @@ static BOOL init(void) return TRUE; }
+static int underflow_count; + +#ifdef __i386__ +static int __thiscall test_streambuf_underflow(void) +#else +static int __thiscall test_streambuf_underflow(streambuf *this) +#endif +{ + underflow_count++; + return 'u'; +} + struct streambuf_lock_arg { streambuf *sb; @@ -197,6 +212,7 @@ static DWORD WINAPI lock_streambuf(void *arg) static void test_streambuf(void) { streambuf sb, sb2, sb3, *psb; + vtable_ptr test_streambuf_vtbl[11]; struct streambuf_lock_arg lock_arg; HANDLE thread; char reserve[16]; @@ -226,6 +242,12 @@ static void test_streambuf(void) ok(sb3.base == NULL, "wrong base pointer, expected %p got %p\n", NULL, sb3.base); 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[8] = (vtable_ptr)&test_streambuf_underflow; + sb2.vtable = test_streambuf_vtbl; + sb3.vtable = test_streambuf_vtbl; + underflow_count = 0; + /* setlock */ ok(sb.do_lock == -1, "expected do_lock value -1, got %d\n", sb.do_lock); call_func1(p_streambuf_setlock, &sb); @@ -386,6 +408,28 @@ static void test_streambuf(void) ret = (int) call_func1(p_streambuf_sync, &sb3); ok(ret == 0, "sync failed, expected 0 got %d\n", ret);
+ /* sgetc */ + ret = (int) call_func1(p_streambuf_sgetc, &sb2); + ok(ret == 'u', "expected 'u' got '%c'\n", ret); + ok(underflow_count == 1, "expected call to underflow\n"); + ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char); + sb2.gptr = sb2.eback; + *sb2.gptr = 'a'; + ret = (int) call_func1(p_streambuf_sgetc, &sb2); + ok(ret == 'u', "expected 'u' got '%c'\n", ret); + ok(underflow_count == 2, "expected call to underflow\n"); + ok(sb2.stored_char == EOF, "wrong stored character, expected EOF got %c\n", sb2.stored_char); + sb2.gptr = sb2.egptr; + ret = (int) call_func1(p_streambuf_sgetc, &sb3); + ok(ret == 'u', "expected 'u' got '%c'\n", ret); + ok(underflow_count == 3, "expected call to underflow\n"); + ok(sb3.stored_char == 'u', "wrong stored character, expected 'u' got %c\n", sb3.stored_char); + sb3.stored_char = 'b'; + ret = (int) call_func1(p_streambuf_sgetc, &sb3); + ok(ret == 'b', "expected 'b' got '%c'\n", ret); + 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); + SetEvent(lock_arg.test[3]); WaitForSingleObject(thread, INFINITE);
diff --git a/dlls/msvcrt20/msvcrt20.spec b/dlls/msvcrt20/msvcrt20.spec index 9d212fe..14846f3 100644 --- a/dlls/msvcrt20/msvcrt20.spec +++ b/dlls/msvcrt20/msvcrt20.spec @@ -681,8 +681,8 @@ @ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IEAAXPEAD0@Z @ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z -@ stub -arch=win32 ?sgetc@streambuf@@QAEHXZ -@ stub -arch=win64 ?sgetc@streambuf@@QEAAHXZ +@ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) msvcirt.?sgetc@streambuf@@QAEHXZ +@ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc@streambuf@@QEAAHXZ @ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z @ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z # @ extern ?sh_none@filebuf@@2HB diff --git a/dlls/msvcrt40/msvcrt40.spec b/dlls/msvcrt40/msvcrt40.spec index a1cabf9..c794b6e 100644 --- a/dlls/msvcrt40/msvcrt40.spec +++ b/dlls/msvcrt40/msvcrt40.spec @@ -753,8 +753,8 @@ @ cdecl -arch=win64 ?setp@streambuf@@IEAAXPEAD0@Z(ptr ptr ptr) msvcirt.?setp@streambuf@@IEAAXPEAD0@Z @ stub -arch=win32 ?setrwbuf@stdiobuf@@QAEHHH@Z @ stub -arch=win64 ?setrwbuf@stdiobuf@@QEAAHHH@Z -@ stub -arch=win32 ?sgetc@streambuf@@QAEHXZ -@ stub -arch=win64 ?sgetc@streambuf@@QEAAHXZ +@ thiscall -arch=win32 ?sgetc@streambuf@@QAEHXZ(ptr) msvcirt.?sgetc@streambuf@@QAEHXZ +@ cdecl -arch=win64 ?sgetc@streambuf@@QEAAHXZ(ptr) msvcirt.?sgetc@streambuf@@QEAAHXZ @ stub -arch=win32 ?sgetn@streambuf@@QAEHPADH@Z @ stub -arch=win64 ?sgetn@streambuf@@QEAAHPEADH@Z # @ extern ?sh_none@filebuf@@2HB