msvcirt: Implement ostream::operator<< for integers.

Signed-off-by: Iván Matellanes <matellanes.ivan@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-06-22 13:59:49 +01:00 committed by Alexandre Julliard
parent 65935c4c88
commit c969efcaf2
2 changed files with 84 additions and 10 deletions

View File

@ -2592,6 +2592,45 @@ ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char
return this; return this;
} }
static ostream* ostream_internal_print_integer(ostream *ostr, int n, BOOL unsig, BOOL shrt)
{
ios *base = ostream_get_ios(ostr);
char prefix_str[3] = {0}, number_str[12], sprintf_fmt[4] = {'%','d',0};
TRACE("(%p %d %d %d)\n", ostr, n, unsig, shrt);
if (ostream_opfx(ostr)) {
if (base->flags & FLAGS_hex) {
sprintf_fmt[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
if (base->flags & FLAGS_showbase) {
prefix_str[0] = '0';
prefix_str[1] = (base->flags & FLAGS_uppercase) ? 'X' : 'x';
}
} else if (base->flags & FLAGS_oct) {
sprintf_fmt[1] = 'o';
if (base->flags & FLAGS_showbase)
prefix_str[0] = '0';
} else { /* FLAGS_dec */
if (unsig)
sprintf_fmt[1] = 'u';
if ((base->flags & FLAGS_showpos) && n != 0 && (unsig || n > 0))
prefix_str[0] = '+';
}
if (shrt) {
sprintf_fmt[2] = sprintf_fmt[1];
sprintf_fmt[1] = 'h';
}
if (sprintf(number_str, sprintf_fmt, n) > 0)
ostream_writepad(ostr, prefix_str, number_str);
else
base->state |= IOSTATE_failbit;
ostream_osfx(ostr);
}
return ostr;
}
/* ??6ostream@@QAEAAV0@C@Z */ /* ??6ostream@@QAEAAV0@C@Z */
/* ??6ostream@@QEAAAEAV0@C@Z */ /* ??6ostream@@QEAAAEAV0@C@Z */
/* ??6ostream@@QAEAAV0@D@Z */ /* ??6ostream@@QAEAAV0@D@Z */
@ -2646,8 +2685,7 @@ ostream* __thiscall ostream_print_unsigned_str(ostream *this, const unsigned cha
DEFINE_THISCALL_WRAPPER(ostream_print_short, 8) DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
ostream* __thiscall ostream_print_short(ostream *this, short n) ostream* __thiscall ostream_print_short(ostream *this, short n)
{ {
FIXME("(%p %d) stub\n", this, n); return ostream_internal_print_integer(this, n, FALSE, TRUE);
return this;
} }
/* ??6ostream@@QAEAAV0@G@Z */ /* ??6ostream@@QAEAAV0@G@Z */
@ -2655,8 +2693,7 @@ ostream* __thiscall ostream_print_short(ostream *this, short n)
DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8) DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n) ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
{ {
FIXME("(%p %u) stub\n", this, n); return ostream_internal_print_integer(this, n, TRUE, TRUE);
return this;
} }
/* ??6ostream@@QAEAAV0@H@Z */ /* ??6ostream@@QAEAAV0@H@Z */
@ -2666,8 +2703,7 @@ ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n
DEFINE_THISCALL_WRAPPER(ostream_print_int, 8) DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
ostream* __thiscall ostream_print_int(ostream *this, int n) ostream* __thiscall ostream_print_int(ostream *this, int n)
{ {
FIXME("(%p %d) stub\n", this, n); return ostream_internal_print_integer(this, n, FALSE, FALSE);
return this;
} }
/* ??6ostream@@QAEAAV0@I@Z */ /* ??6ostream@@QAEAAV0@I@Z */
@ -2677,8 +2713,7 @@ ostream* __thiscall ostream_print_int(ostream *this, int n)
DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8) DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n) ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
{ {
FIXME("(%p %u) stub\n", this, n); return ostream_internal_print_integer(this, n, TRUE, FALSE);
return this;
} }
/* ??6ostream@@QAEAAV0@M@Z */ /* ??6ostream@@QAEAAV0@M@Z */

View File

@ -272,6 +272,7 @@ static streampos (*__thiscall p_ostream_tellp)(ostream*);
static ostream* (*__thiscall p_ostream_writepad)(ostream*, const char*, const char*); static ostream* (*__thiscall p_ostream_writepad)(ostream*, const char*, const char*);
static ostream* (*__thiscall p_ostream_print_char)(ostream*, char); static ostream* (*__thiscall p_ostream_print_char)(ostream*, char);
static ostream* (*__thiscall p_ostream_print_str)(ostream*, const char*); static ostream* (*__thiscall p_ostream_print_str)(ostream*, const char*);
static ostream* (*__thiscall p_ostream_print_int)(ostream*, int);
/* Emulate a __thiscall */ /* Emulate a __thiscall */
#ifdef __i386__ #ifdef __i386__
@ -448,6 +449,7 @@ static BOOL init(void)
SET(p_ostream_writepad, "?writepad@ostream@@AEAAAEAV1@PEBD0@Z"); SET(p_ostream_writepad, "?writepad@ostream@@AEAAAEAV1@PEBD0@Z");
SET(p_ostream_print_char, "??6ostream@@QEAAAEAV0@D@Z"); SET(p_ostream_print_char, "??6ostream@@QEAAAEAV0@D@Z");
SET(p_ostream_print_str, "??6ostream@@QEAAAEAV0@PEBD@Z"); SET(p_ostream_print_str, "??6ostream@@QEAAAEAV0@PEBD@Z");
SET(p_ostream_print_int, "??6ostream@@QEAAAEAV0@H@Z");
} else { } else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2@YAPAXI@Z"); p_operator_new = (void*)GetProcAddress(msvcrt, "??2@YAPAXI@Z");
p_operator_delete = (void*)GetProcAddress(msvcrt, "??3@YAXPAX@Z"); p_operator_delete = (void*)GetProcAddress(msvcrt, "??3@YAXPAX@Z");
@ -554,6 +556,7 @@ static BOOL init(void)
SET(p_ostream_writepad, "?writepad@ostream@@AAEAAV1@PBD0@Z"); SET(p_ostream_writepad, "?writepad@ostream@@AAEAAV1@PBD0@Z");
SET(p_ostream_print_char, "??6ostream@@QAEAAV0@D@Z"); SET(p_ostream_print_char, "??6ostream@@QAEAAV0@D@Z");
SET(p_ostream_print_str, "??6ostream@@QAEAAV0@PBD@Z"); SET(p_ostream_print_str, "??6ostream@@QAEAAV0@PBD@Z");
SET(p_ostream_print_int, "??6ostream@@QAEAAV0@H@Z");
} }
SET(p_ios_static_lock, "?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A"); SET(p_ios_static_lock, "?x_lockc@ios@@0U_CRT_CRITICAL_SECTION@@A");
SET(p_ios_lockc, "?lockc@ios@@KAXXZ"); SET(p_ios_lockc, "?lockc@ios@@KAXXZ");
@ -3017,8 +3020,9 @@ static void test_ostream_print(void)
char param_char[] = {'a', '9', 'e'}; char param_char[] = {'a', '9', 'e'};
const char* param_str[] = {"Test", "800", "3.14159", " Test"}; const char* param_str[] = {"Test", "800", "3.14159", " Test"};
int param_int[] = {0, 7, 10, 24 ,55, 1024, 1023, 65536, 2147483647, 2147483648u, 4294967295u, -20};
struct ostream_print_test { struct ostream_print_test {
enum { type_chr, type_str } type; enum { type_chr, type_str, type_int } type;
int param_index; int param_index;
ios_io_state state; ios_io_state state;
ios_flags flags; ios_flags flags;
@ -3050,7 +3054,40 @@ static void test_ostream_print(void)
{type_str, /* "Test" */ 0, IOSTATE_goodbit, FLAGS_left|FLAGS_hex|FLAGS_showpoint, 6, '?', 6, "Test??", IOSTATE_goodbit}, {type_str, /* "Test" */ 0, IOSTATE_goodbit, FLAGS_left|FLAGS_hex|FLAGS_showpoint, 6, '?', 6, "Test??", IOSTATE_goodbit},
{type_str, /* "800" */ 1, IOSTATE_goodbit, FLAGS_showbase|FLAGS_showpos, 6, ' ', 4, " 800", IOSTATE_goodbit}, {type_str, /* "800" */ 1, IOSTATE_goodbit, FLAGS_showbase|FLAGS_showpos, 6, ' ', 4, " 800", IOSTATE_goodbit},
{type_str, /* "3.14159" */ 2, IOSTATE_goodbit, FLAGS_scientific, 2, 'x', 2, "3.14159", IOSTATE_goodbit}, {type_str, /* "3.14159" */ 2, IOSTATE_goodbit, FLAGS_scientific, 2, 'x', 2, "3.14159", IOSTATE_goodbit},
{type_str, /* " Test" */ 3, IOSTATE_goodbit, FLAGS_skipws, 6, 'x', 2, " Test", IOSTATE_goodbit} {type_str, /* " Test" */ 3, IOSTATE_goodbit, FLAGS_skipws, 6, 'x', 2, " Test", IOSTATE_goodbit},
/* int */
{type_int, /* 0 */ 0, IOSTATE_badbit, 0, 6, ' ', 0, "", IOSTATE_badbit|IOSTATE_failbit},
{type_int, /* 0 */ 0, IOSTATE_eofbit, 0, 6, ' ', 0, "", IOSTATE_eofbit|IOSTATE_failbit},
{type_int, /* 0 */ 0, IOSTATE_goodbit, 0, 6, ' ', 4, " 0", IOSTATE_goodbit},
{type_int, /* 7 */ 1, IOSTATE_goodbit, 0, 6, '0', 3, "007", IOSTATE_goodbit},
{type_int, /* 10 */ 2, IOSTATE_goodbit, FLAGS_left, 6, ' ', 5, "10 ", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_left|FLAGS_hex, 6, ' ', 0, "18", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_left|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_internal|FLAGS_hex|FLAGS_showbase, 6, '*', 8, "0x****18", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_oct|FLAGS_showbase, 6, '*', 4, "*030", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_oct|FLAGS_dec|FLAGS_showbase, 6, ' ', 0, "030", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_oct|FLAGS_dec|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_left|FLAGS_oct|FLAGS_hex, 6, ' ', 5, "18 ", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_dec|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
{type_int, /* 24 */ 3, IOSTATE_goodbit, FLAGS_dec|FLAGS_showbase, 6, ' ', 0, "24", IOSTATE_goodbit},
{type_int, /* 55 */ 4, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_uppercase, 6, ' ', 0, "0X37", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_showpoint|FLAGS_uppercase, 6, ' ', 0, "0X400", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_showpos, 6, ' ', 0, "0x400", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_hex|FLAGS_showpos, 6, ' ', 0, "400", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_oct|FLAGS_showpos, 6, ' ', 0, "2000", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_internal|FLAGS_oct|FLAGS_showbase, 6, 'x', 8, "0xxx2000", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_showbase|FLAGS_showpoint|FLAGS_showpos, 6, ' ', 0, "+1024", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_dec|FLAGS_showbase|FLAGS_showpos, 6, 'a', 6, "a+1024", IOSTATE_goodbit},
{type_int, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_internal|FLAGS_showbase|FLAGS_showpos, 6, ' ', 8, "+ 1024", IOSTATE_goodbit},
{type_int, /* 1023 */ 6, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_uppercase, 6, ' ', 0, "0X3FF", IOSTATE_goodbit},
{type_int, /* 1023 */ 6, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_scientific, 6, ' ', 0, "0x3ff", IOSTATE_goodbit},
{type_int, /* 65536 */ 7, IOSTATE_goodbit, FLAGS_right|FLAGS_showpos|FLAGS_fixed, 6, ' ', 8, " +65536", IOSTATE_goodbit},
{type_int, /* 2147483647 */ 8, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x7fffffff", IOSTATE_goodbit},
{type_int, /* 2147483648 */ 9, IOSTATE_goodbit, FLAGS_dec, 6, ' ', 0, "-2147483648", IOSTATE_goodbit},
{type_int, /* 4294967295 */ 10, IOSTATE_goodbit, FLAGS_internal, 6, ' ', 8, " -1", IOSTATE_goodbit},
{type_int, /* -20 */ 11, IOSTATE_goodbit, FLAGS_internal|FLAGS_oct|FLAGS_showbase, 6, ' ', 8, "037777777754", IOSTATE_goodbit},
{type_int, /* -20 */ 11, IOSTATE_goodbit, FLAGS_dec|FLAGS_showpos, 6, ' ', 0, "-20", IOSTATE_goodbit},
{type_int, /* 0 */ 0, IOSTATE_goodbit, FLAGS_internal|FLAGS_showpos, 6, ' ', 8, " 0", IOSTATE_goodbit}
}; };
pssb = call_func1(p_strstreambuf_ctor, &ssb); pssb = call_func1(p_strstreambuf_ctor, &ssb);
@ -3071,6 +3108,8 @@ static void test_ostream_print(void)
pos = call_func2(p_ostream_print_char, &os, (int) param_char[tests[i].param_index]); break; pos = call_func2(p_ostream_print_char, &os, (int) param_char[tests[i].param_index]); break;
case type_str: case type_str:
pos = call_func2(p_ostream_print_str, &os, param_str[tests[i].param_index]); break; pos = call_func2(p_ostream_print_str, &os, param_str[tests[i].param_index]); break;
case type_int:
pos = call_func2(p_ostream_print_int, &os, param_int[tests[i].param_index]); break;
} }
length = ssb.base.pptr - ssb.base.pbase; length = ssb.base.pptr - ssb.base.pbase;