msvcirt: Add predefined streams.

Signed-off-by: Iván Matellanes <matellanesivan@gmail.com>
Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Iván Matellanes 2016-08-17 20:36:02 +01:00 committed by Alexandre Julliard
parent 4f545cb627
commit 5a2bac8d12
5 changed files with 143 additions and 19 deletions

View File

@ -59,8 +59,7 @@ const LONG ios_basefield = FLAGS_dec | FLAGS_oct | FLAGS_hex;
/* ?floatfield@ios@@2JB */
const LONG ios_floatfield = FLAGS_scientific | FLAGS_fixed;
/* ?fLockcInit@ios@@0HA */
/* FIXME: should be initialized to 0 and increased on construction of cin, cout, cerr and clog */
int ios_fLockcInit = 4;
int ios_fLockcInit = 0;
/* ?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A */
extern CRITICAL_SECTION ios_static_lock;
CRITICAL_SECTION_DEBUG ios_static_lock_debug =
@ -287,6 +286,21 @@ DEFINE_RTTI_DATA4(iostream, sizeof(iostream),
&istream_rtti_base_descriptor, &ios_rtti_base_descriptor,
&ostream_rtti_base_descriptor, &ios_rtti_base_descriptor, ".?AViostream@@")
/* ?cin@@3Vistream_withassign@@A */
struct {
istream is;
ios vbase;
} cin = { { 0 } };
/* ?cout@@3Vostream_withassign@@A */
/* ?cerr@@3Vostream_withassign@@A */
/* ?clog@@3Vostream_withassign@@A */
struct {
ostream os;
ios vbase;
} cout = { { 0 } }, cerr = { { 0 } }, clog = { { 0 } };
/* ??0streambuf@@IAE@PADH@Z */
/* ??0streambuf@@IEAA@PEADH@Z */
DEFINE_THISCALL_WRAPPER(streambuf_reserve_ctor, 12)
@ -4040,7 +4054,7 @@ void* __thiscall Iostream_init_ios_ctor(void *this, ios *obj, int n)
TRACE("(%p %p %d)\n", this, obj, n);
obj->delbuf = 1;
if (n >= 0) {
obj->tie = NULL; /* FIXME: tie to cout */
obj->tie = &cout.os;
if (n > 0)
ios_setf(obj, FLAGS_unitbuf);
}
@ -4141,6 +4155,8 @@ static void init_cxx_funcs(void)
static void init_io(void *base)
{
filebuf *fb;
#ifdef __x86_64__
init_streambuf_rtti(base);
init_filebuf_rtti(base);
@ -4153,6 +4169,43 @@ static void init_io(void *base)
init_istream_withassign_rtti(base);
init_iostream_rtti(base);
#endif
if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
filebuf_fd_ctor(fb, 0);
istream_withassign_sb_ctor(&cin.is, &fb->base, TRUE);
} else
istream_withassign_sb_ctor(&cin.is, NULL, TRUE);
Iostream_init_ios_ctor(NULL, &cin.vbase, 0);
if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
filebuf_fd_ctor(fb, 1);
ostream_withassign_sb_ctor(&cout.os, &fb->base, TRUE);
} else
ostream_withassign_sb_ctor(&cout.os, NULL, TRUE);
Iostream_init_ios_ctor(NULL, &cout.vbase, -1);
if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
filebuf_fd_ctor(fb, 2);
ostream_withassign_sb_ctor(&cerr.os, &fb->base, TRUE);
} else
ostream_withassign_sb_ctor(&cerr.os, NULL, TRUE);
Iostream_init_ios_ctor(NULL, &cerr.vbase, 1);
if ((fb = MSVCRT_operator_new(sizeof(filebuf)))) {
filebuf_fd_ctor(fb, 2);
ostream_withassign_sb_ctor(&clog.os, &fb->base, TRUE);
} else
ostream_withassign_sb_ctor(&clog.os, NULL, TRUE);
Iostream_init_ios_ctor(NULL, &clog.vbase, 0);
}
static void free_io(void)
{
/* destructors take care of deleting the buffers */
istream_vbase_dtor(&cin.is);
ostream_vbase_dtor(&cout.os);
ostream_vbase_dtor(&cerr.os);
ostream_vbase_dtor(&clog.os);
}
BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
@ -4167,6 +4220,10 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
init_io(inst);
DisableThreadLibraryCalls( inst );
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
free_io();
break;
}
return TRUE;
}

View File

@ -419,11 +419,11 @@
@ cdecl ?bitalloc@ios@@SAJXZ() ios_bitalloc
@ thiscall -arch=win32 ?blen@streambuf@@IBEHXZ(ptr) streambuf_blen
@ cdecl -arch=win64 ?blen@streambuf@@IEBAHXZ(ptr) streambuf_blen
@ stub ?cerr@@3Vostream_withassign@@A # class ostream_withassign cerr
@ stub ?cin@@3Vistream_withassign@@A # class istream_withassign cin
@ extern ?cerr@@3Vostream_withassign@@A cerr
@ extern ?cin@@3Vistream_withassign@@A cin
@ thiscall -arch=win32 ?clear@ios@@QAEXH@Z(ptr long) ios_clear
@ cdecl -arch=win64 ?clear@ios@@QEAAXH@Z(ptr long) ios_clear
@ stub ?clog@@3Vostream_withassign@@A # class ostream_withassign clog
@ extern ?clog@@3Vostream_withassign@@A clog
@ thiscall -arch=win32 ?close@filebuf@@QAEPAV1@XZ(ptr) filebuf_close
@ cdecl -arch=win64 ?close@filebuf@@QEAAPEAV1@XZ(ptr) filebuf_close
@ stub -arch=win32 ?close@fstream@@QAEXXZ # void __thiscall fstream::close(void)
@ -436,7 +436,7 @@
@ cdecl -arch=win64 ?clrlock@ios@@QEAAXXZ(ptr) ios_clrlock
@ thiscall -arch=win32 ?clrlock@streambuf@@QAEXXZ(ptr) streambuf_clrlock
@ cdecl -arch=win64 ?clrlock@streambuf@@QEAAXXZ(ptr) streambuf_clrlock
@ stub ?cout@@3Vostream_withassign@@A # class ostream_withassign cout
@ extern ?cout@@3Vostream_withassign@@A cout
@ thiscall -arch=win32 ?dbp@streambuf@@QAEXXZ(ptr) streambuf_dbp
@ cdecl -arch=win64 ?dbp@streambuf@@QEAAXXZ(ptr) streambuf_dbp
@ cdecl -arch=win32 ?dec@@YAAAVios@@AAV1@@Z(ptr) ios_dec

View File

@ -387,7 +387,8 @@ static iostream* (*__thiscall p_iostream_assign)(iostream*, const iostream*);
static void* (*__thiscall p_Iostream_init_ios_ctor)(void*, ios*, int);
/* Predefined streams */
static ostream *p_cout;
static istream *p_cin;
static ostream *p_cout, *p_cerr, *p_clog;
/* Emulate a __thiscall */
#ifdef __i386__
@ -830,7 +831,10 @@ static BOOL init(void)
SET(p_ios_statebuf, "?x_statebuf@ios@@0PAJA");
SET(p_ios_xalloc, "?xalloc@ios@@SAHXZ");
SET(p_ios_fLockcInit, "?fLockcInit@ios@@0HA");
SET(p_cin, "?cin@@3Vistream_withassign@@A");
SET(p_cout, "?cout@@3Vostream_withassign@@A");
SET(p_cerr, "?cerr@@3Vostream_withassign@@A");
SET(p_clog, "?clog@@3Vostream_withassign@@A");
init_thiscall_thunk();
return TRUE;
@ -6059,7 +6063,6 @@ static void test_Iostream_init(void)
ok(ios_obj.special[0] == 0xabababab, "expected %d got %d\n", 0xabababab, ios_obj.special[0]);
ok(ios_obj.special[1] == 0xabababab, "expected %d got %d\n", 0xabababab, ios_obj.special[1]);
ok(ios_obj.delbuf == 1, "expected 1 got %d\n", ios_obj.delbuf);
todo_wine
ok(ios_obj.tie == p_cout, "expected %p got %p\n", p_cout, ios_obj.tie);
ok(ios_obj.flags == 0xabababab, "expected %d got %x\n", 0xabababab, ios_obj.flags);
ok(ios_obj.precision == 0xabababab, "expected %d got %d\n", 0xabababab, ios_obj.precision);
@ -6111,7 +6114,6 @@ todo_wine
ok(ios_obj.special[0] == 0xabababab, "expected %d got %d\n", 0xabababab, ios_obj.special[0]);
ok(ios_obj.special[1] == 0xabababab, "expected %d got %d\n", 0xabababab, ios_obj.special[1]);
ok(ios_obj.delbuf == 1, "expected 1 got %d\n", ios_obj.delbuf);
todo_wine
ok(ios_obj.tie == p_cout, "expected %p got %p\n", p_cout, ios_obj.tie);
ok(ios_obj.flags == (0xcdcdcdcd|FLAGS_unitbuf), "expected %d got %x\n",
0xcdcdcdcd|FLAGS_unitbuf, ios_obj.flags);
@ -6130,7 +6132,6 @@ todo_wine
ok(ios_obj.special[0] == 0xabababab, "expected %d got %d\n", 0xabababab, ios_obj.special[0]);
ok(ios_obj.special[1] == 0xabababab, "expected %d got %d\n", 0xabababab, ios_obj.special[1]);
ok(ios_obj.delbuf == 1, "expected 1 got %d\n", ios_obj.delbuf);
todo_wine
ok(ios_obj.tie == p_cout, "expected %p got %p\n", p_cout, ios_obj.tie);
ok(ios_obj.flags == (0xcdcdcdcd|FLAGS_unitbuf), "expected %d got %x\n",
0xcdcdcdcd|FLAGS_unitbuf, ios_obj.flags);
@ -6140,6 +6141,71 @@ todo_wine
ok(ios_obj.do_lock == 0x34343434, "expected %d got %d\n", 0x34343434, ios_obj.do_lock);
}
static void test_std_streams(void)
{
filebuf *pfb_cin = (filebuf*) p_cin->base_ios.sb;
filebuf *pfb_cout = (filebuf*) p_cout->base_ios.sb;
filebuf *pfb_cerr = (filebuf*) p_cerr->base_ios.sb;
filebuf *pfb_clog = (filebuf*) p_clog->base_ios.sb;
ok(p_cin->extract_delim == 0, "expected 0 got %d\n", p_cin->extract_delim);
ok(p_cin->count == 0, "expected 0 got %d\n", p_cin->count);
ok(p_cin->base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, p_cin->base_ios.state);
ok(p_cin->base_ios.delbuf == 1, "expected 1 got %d\n", p_cin->base_ios.delbuf);
ok(p_cin->base_ios.tie == p_cout, "expected %p got %p\n", p_cout, p_cin->base_ios.tie);
ok(p_cin->base_ios.flags == FLAGS_skipws, "expected %x got %x\n", FLAGS_skipws, p_cin->base_ios.flags);
ok(p_cin->base_ios.precision == 6, "expected 6 got %d\n", p_cin->base_ios.precision);
ok(p_cin->base_ios.fill == ' ', "expected 32 got %d\n", p_cin->base_ios.fill);
ok(p_cin->base_ios.width == 0, "expected 0 got %d\n", p_cin->base_ios.width);
ok(p_cin->base_ios.do_lock == -1, "expected -1 got %d\n", p_cin->base_ios.do_lock);
ok(pfb_cin->fd == 0, "wrong fd, expected 0 got %d\n", pfb_cin->fd);
ok(pfb_cin->close == 0, "wrong value, expected 0 got %d\n", pfb_cin->close);
ok(pfb_cin->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb_cin->base.allocated);
ok(pfb_cin->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb_cin->base.unbuffered);
ok(p_cout->unknown == 0, "expected 0 got %d\n", p_cout->unknown);
ok(p_cout->base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, p_cout->base_ios.state);
ok(p_cout->base_ios.delbuf == 1, "expected 1 got %d\n", p_cout->base_ios.delbuf);
ok(p_cout->base_ios.tie == NULL, "expected %p got %p\n", NULL, p_cout->base_ios.tie);
ok(p_cout->base_ios.flags == 0, "expected 0 got %x\n", p_cout->base_ios.flags);
ok(p_cout->base_ios.precision == 6, "expected 6 got %d\n", p_cout->base_ios.precision);
ok(p_cout->base_ios.fill == ' ', "expected 32 got %d\n", p_cout->base_ios.fill);
ok(p_cout->base_ios.width == 0, "expected 0 got %d\n", p_cout->base_ios.width);
ok(p_cout->base_ios.do_lock == -1, "expected -1 got %d\n", p_cout->base_ios.do_lock);
ok(pfb_cout->fd == 1, "wrong fd, expected 1 got %d\n", pfb_cout->fd);
ok(pfb_cout->close == 0, "wrong value, expected 0 got %d\n", pfb_cout->close);
ok(pfb_cout->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb_cout->base.allocated);
ok(pfb_cout->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb_cout->base.unbuffered);
ok(p_cerr->unknown == 0, "expected 0 got %d\n", p_cerr->unknown);
ok(p_cerr->base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, p_cerr->base_ios.state);
ok(p_cerr->base_ios.delbuf == 1, "expected 1 got %d\n", p_cerr->base_ios.delbuf);
ok(p_cerr->base_ios.tie == p_cout, "expected %p got %p\n", p_cout, p_cerr->base_ios.tie);
ok(p_cerr->base_ios.flags == FLAGS_unitbuf, "expected %x got %x\n", FLAGS_unitbuf, p_cerr->base_ios.flags);
ok(p_cerr->base_ios.precision == 6, "expected 6 got %d\n", p_cerr->base_ios.precision);
ok(p_cerr->base_ios.fill == ' ', "expected 32 got %d\n", p_cerr->base_ios.fill);
ok(p_cerr->base_ios.width == 0, "expected 0 got %d\n", p_cerr->base_ios.width);
ok(p_cerr->base_ios.do_lock == -1, "expected -1 got %d\n", p_cerr->base_ios.do_lock);
ok(pfb_cerr->fd == 2, "wrong fd, expected 2 got %d\n", pfb_cerr->fd);
ok(pfb_cerr->close == 0, "wrong value, expected 0 got %d\n", pfb_cerr->close);
ok(pfb_cerr->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb_cerr->base.allocated);
ok(pfb_cerr->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb_cerr->base.unbuffered);
ok(p_clog->unknown == 0, "expected 0 got %d\n", p_clog->unknown);
ok(p_clog->base_ios.state == IOSTATE_goodbit, "expected %d got %d\n", IOSTATE_goodbit, p_clog->base_ios.state);
ok(p_clog->base_ios.delbuf == 1, "expected 1 got %d\n", p_clog->base_ios.delbuf);
ok(p_clog->base_ios.tie == p_cout, "expected %p got %p\n", p_cout, p_clog->base_ios.tie);
ok(p_clog->base_ios.flags == 0, "expected 0 got %x\n", p_clog->base_ios.flags);
ok(p_clog->base_ios.precision == 6, "expected 6 got %d\n", p_clog->base_ios.precision);
ok(p_clog->base_ios.fill == ' ', "expected 32 got %d\n", p_clog->base_ios.fill);
ok(p_clog->base_ios.width == 0, "expected 0 got %d\n", p_clog->base_ios.width);
ok(p_clog->base_ios.do_lock == -1, "expected -1 got %d\n", p_clog->base_ios.do_lock);
ok(pfb_clog->fd == 2, "wrong fd, expected 2 got %d\n", pfb_clog->fd);
ok(pfb_clog->close == 0, "wrong value, expected 0 got %d\n", pfb_clog->close);
ok(pfb_clog->base.allocated == 0, "wrong allocate value, expected 0 got %d\n", pfb_clog->base.allocated);
ok(pfb_clog->base.unbuffered == 0, "wrong unbuffered value, expected 0 got %d\n", pfb_clog->base.unbuffered);
}
START_TEST(msvcirt)
{
if(!init())
@ -6160,6 +6226,7 @@ START_TEST(msvcirt)
test_istream_withassign();
test_iostream();
test_Iostream_init();
test_std_streams();
FreeLibrary(msvcrt);
FreeLibrary(msvcirt);

View File

@ -407,11 +407,11 @@
@ cdecl ?bitalloc@ios@@SAJXZ() msvcirt.?bitalloc@ios@@SAJXZ
@ thiscall -arch=win32 ?blen@streambuf@@IBEHXZ(ptr) msvcirt.?blen@streambuf@@IBEHXZ
@ cdecl -arch=win64 ?blen@streambuf@@IEBAHXZ(ptr) msvcirt.?blen@streambuf@@IEBAHXZ
@ stub ?cerr@@3Vostream_withassign@@A
@ stub ?cin@@3Vistream_withassign@@A
@ extern ?cerr@@3Vostream_withassign@@A msvcirt.?cerr@@3Vostream_withassign@@A
@ extern ?cin@@3Vistream_withassign@@A msvcirt.?cin@@3Vistream_withassign@@A
@ thiscall -arch=win32 ?clear@ios@@QAEXH@Z(ptr long) msvcirt.?clear@ios@@QAEXH@Z
@ cdecl -arch=win64 ?clear@ios@@QEAAXH@Z(ptr long) msvcirt.?clear@ios@@QEAAXH@Z
@ stub ?clog@@3Vostream_withassign@@A
@ extern ?clog@@3Vostream_withassign@@A msvcirt.?clog@@3Vostream_withassign@@A
@ thiscall -arch=win32 ?close@filebuf@@QAEPAV1@XZ(ptr) msvcirt.?close@filebuf@@QAEPAV1@XZ
@ cdecl -arch=win64 ?close@filebuf@@QEAAPEAV1@XZ(ptr) msvcirt.?close@filebuf@@QEAAPEAV1@XZ
@ stub -arch=win32 ?close@fstream@@QAEXXZ
@ -424,7 +424,7 @@
@ cdecl -arch=win64 ?clrlock@ios@@QEAAXXZ(ptr) msvcirt.?clrlock@ios@@QEAAXXZ
@ thiscall -arch=win32 ?clrlock@streambuf@@QAEXXZ(ptr) msvcirt.?clrlock@streambuf@@QAEXXZ
@ cdecl -arch=win64 ?clrlock@streambuf@@QEAAXXZ(ptr) msvcirt.?clrlock@streambuf@@QEAAXXZ
@ stub ?cout@@3Vostream_withassign@@A
@ extern ?cout@@3Vostream_withassign@@A msvcirt.?cout@@3Vostream_withassign@@A
@ thiscall -arch=win32 ?dbp@streambuf@@QAEXXZ(ptr) msvcirt.?dbp@streambuf@@QAEXXZ
@ cdecl -arch=win64 ?dbp@streambuf@@QEAAXXZ(ptr) msvcirt.?dbp@streambuf@@QEAAXXZ
@ cdecl -arch=win32 ?dec@@YAAAVios@@AAV1@@Z(ptr) msvcirt.?dec@@YAAAVios@@AAV1@@Z

View File

@ -472,11 +472,11 @@
@ cdecl ?bitalloc@ios@@SAJXZ() msvcirt.?bitalloc@ios@@SAJXZ
@ thiscall -arch=win32 ?blen@streambuf@@IBEHXZ(ptr) msvcirt.?blen@streambuf@@IBEHXZ
@ cdecl -arch=win64 ?blen@streambuf@@IEBAHXZ(ptr) msvcirt.?blen@streambuf@@IEBAHXZ
@ stub ?cerr@@3Vostream_withassign@@A
@ stub ?cin@@3Vistream_withassign@@A
@ extern ?cerr@@3Vostream_withassign@@A msvcirt.?cerr@@3Vostream_withassign@@A
@ extern ?cin@@3Vistream_withassign@@A msvcirt.?cin@@3Vistream_withassign@@A
@ thiscall -arch=win32 ?clear@ios@@QAEXH@Z(ptr long) msvcirt.?clear@ios@@QAEXH@Z
@ cdecl -arch=win64 ?clear@ios@@QEAAXH@Z(ptr long) msvcirt.?clear@ios@@QEAAXH@Z
@ stub ?clog@@3Vostream_withassign@@A
@ extern ?clog@@3Vostream_withassign@@A msvcirt.?clog@@3Vostream_withassign@@A
@ thiscall -arch=win32 ?close@filebuf@@QAEPAV1@XZ(ptr) msvcirt.?close@filebuf@@QAEPAV1@XZ
@ cdecl -arch=win64 ?close@filebuf@@QEAAPEAV1@XZ(ptr) msvcirt.?close@filebuf@@QEAAPEAV1@XZ
@ stub -arch=win32 ?close@fstream@@QAEXXZ
@ -489,7 +489,7 @@
@ cdecl -arch=win64 ?clrlock@ios@@QEAAXXZ(ptr) msvcirt.?clrlock@ios@@QEAAXXZ
@ thiscall -arch=win32 ?clrlock@streambuf@@QAEXXZ(ptr) msvcirt.?clrlock@streambuf@@QAEXXZ
@ cdecl -arch=win64 ?clrlock@streambuf@@QEAAXXZ(ptr) msvcirt.?clrlock@streambuf@@QEAAXXZ
@ stub ?cout@@3Vostream_withassign@@A
@ extern ?cout@@3Vostream_withassign@@A msvcirt.?cout@@3Vostream_withassign@@A
@ thiscall -arch=win32 ?dbp@streambuf@@QAEXXZ(ptr) msvcirt.?dbp@streambuf@@QAEXXZ
@ cdecl -arch=win64 ?dbp@streambuf@@QEAAXXZ(ptr) msvcirt.?dbp@streambuf@@QEAAXXZ
@ cdecl -arch=win32 ?dec@@YAAAVios@@AAV1@@Z(ptr) msvcirt.?dec@@YAAAVios@@AAV1@@Z