[4/8] msvcirt: Implement ostream::operator<< for integers
Iván Matellanes
matellanesivan at gmail.com
Tue Jun 21 04:54:23 CDT 2016
Signed-off-by: Iván Matellanes <matellanes.ivan at gmail.com>
---
dlls/msvcirt/msvcirt.c | 51 +++++++++++++++++++++++++++++++++++++-------
dlls/msvcirt/tests/msvcirt.c | 43 +++++++++++++++++++++++++++++++++++--
2 files changed, 84 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcirt/msvcirt.c b/dlls/msvcirt/msvcirt.c
index df6f514..e44dbbb 100644
--- a/dlls/msvcirt/msvcirt.c
+++ b/dlls/msvcirt/msvcirt.c
@@ -2592,6 +2592,45 @@ ostream* __thiscall ostream_writepad(ostream *this, const char *str1, const char
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 at C@Z */
/* ??6ostream@@QEAAAEAV0 at C@Z */
/* ??6ostream@@QAEAAV0 at D@Z */
@@ -2646,8 +2685,7 @@ ostream* __thiscall ostream_print_unsigned_str(ostream *this, const unsigned cha
DEFINE_THISCALL_WRAPPER(ostream_print_short, 8)
ostream* __thiscall ostream_print_short(ostream *this, short n)
{
- FIXME("(%p %d) stub\n", this, n);
- return this;
+ return ostream_internal_print_integer(this, n, FALSE, TRUE);
}
/* ??6ostream@@QAEAAV0 at G@Z */
@@ -2655,8 +2693,7 @@ ostream* __thiscall ostream_print_short(ostream *this, short n)
DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_short, 8)
ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n)
{
- FIXME("(%p %u) stub\n", this, n);
- return this;
+ return ostream_internal_print_integer(this, n, TRUE, TRUE);
}
/* ??6ostream@@QAEAAV0 at H@Z */
@@ -2666,8 +2703,7 @@ ostream* __thiscall ostream_print_unsigned_short(ostream *this, unsigned short n
DEFINE_THISCALL_WRAPPER(ostream_print_int, 8)
ostream* __thiscall ostream_print_int(ostream *this, int n)
{
- FIXME("(%p %d) stub\n", this, n);
- return this;
+ return ostream_internal_print_integer(this, n, FALSE, FALSE);
}
/* ??6ostream@@QAEAAV0 at I@Z */
@@ -2677,8 +2713,7 @@ ostream* __thiscall ostream_print_int(ostream *this, int n)
DEFINE_THISCALL_WRAPPER(ostream_print_unsigned_int, 8)
ostream* __thiscall ostream_print_unsigned_int(ostream *this, unsigned int n)
{
- FIXME("(%p %u) stub\n", this, n);
- return this;
+ return ostream_internal_print_integer(this, n, TRUE, FALSE);
}
/* ??6ostream@@QAEAAV0 at M@Z */
diff --git a/dlls/msvcirt/tests/msvcirt.c b/dlls/msvcirt/tests/msvcirt.c
index 11f680b..fc28dd1 100644
--- a/dlls/msvcirt/tests/msvcirt.c
+++ b/dlls/msvcirt/tests/msvcirt.c
@@ -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_print_char)(ostream*, char);
static ostream* (*__thiscall p_ostream_print_str)(ostream*, const char*);
+static ostream* (*__thiscall p_ostream_print_int)(ostream*, int);
/* Emulate a __thiscall */
#ifdef __i386__
@@ -448,6 +449,7 @@ static BOOL init(void)
SET(p_ostream_writepad, "?writepad at ostream@@AEAAAEAV1 at PEBD0@Z");
SET(p_ostream_print_char, "??6ostream@@QEAAAEAV0 at D@Z");
SET(p_ostream_print_str, "??6ostream@@QEAAAEAV0 at PEBD@Z");
+ SET(p_ostream_print_int, "??6ostream@@QEAAAEAV0 at H@Z");
} else {
p_operator_new = (void*)GetProcAddress(msvcrt, "??2 at YAPAXI@Z");
p_operator_delete = (void*)GetProcAddress(msvcrt, "??3 at YAXPAX@Z");
@@ -554,6 +556,7 @@ static BOOL init(void)
SET(p_ostream_writepad, "?writepad at ostream@@AAEAAV1 at PBD0@Z");
SET(p_ostream_print_char, "??6ostream@@QAEAAV0 at D@Z");
SET(p_ostream_print_str, "??6ostream@@QAEAAV0 at PBD@Z");
+ SET(p_ostream_print_int, "??6ostream@@QAEAAV0 at H@Z");
}
SET(p_ios_static_lock, "?x_lockc at ios@@0U_CRT_CRITICAL_SECTION@@A");
SET(p_ios_lockc, "?lockc at ios@@KAXXZ");
@@ -3016,10 +3019,11 @@ static void test_ostream_print(void)
int i;
struct ostream_print_test {
- enum { CHAR, STR } type;
+ enum { CHAR, STR, INT } type;
union {
char c;
const char *str;
+ int i;
} param;
ios_io_state state;
ios_flags flags;
@@ -3051,7 +3055,40 @@ static void test_ostream_print(void)
{STR, {.str = "Test"}, IOSTATE_goodbit, FLAGS_left|FLAGS_hex|FLAGS_showpoint, 6, '?', 6, "Test??", IOSTATE_goodbit},
{STR, {.str = "800"}, IOSTATE_goodbit, FLAGS_showbase|FLAGS_showpos, 6, ' ', 4, " 800", IOSTATE_goodbit},
{STR, {.str = "3.14159"}, IOSTATE_goodbit, FLAGS_scientific, 2, 'x', 2, "3.14159", IOSTATE_goodbit},
- {STR, {.str = " Test"}, IOSTATE_goodbit, FLAGS_skipws, 6, 'x', 2, " Test", IOSTATE_goodbit}
+ {STR, {.str = " Test"}, IOSTATE_goodbit, FLAGS_skipws, 6, 'x', 2, " Test", IOSTATE_goodbit},
+ /* int */
+ {INT, {.i = 0}, IOSTATE_badbit, 0, 6, ' ', 0, "", IOSTATE_badbit|IOSTATE_failbit},
+ {INT, {.i = 0}, IOSTATE_eofbit, 0, 6, ' ', 0, "", IOSTATE_eofbit|IOSTATE_failbit},
+ {INT, {.i = 0}, IOSTATE_goodbit, 0, 6, ' ', 4, " 0", IOSTATE_goodbit},
+ {INT, {.i = 7}, IOSTATE_goodbit, 0, 6, '0', 3, "007", IOSTATE_goodbit},
+ {INT, {.i = 10}, IOSTATE_goodbit, FLAGS_left, 6, ' ', 5, "10 ", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_left|FLAGS_hex, 6, ' ', 0, "18", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_left|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_internal|FLAGS_hex|FLAGS_showbase, 6, '*', 8, "0x****18", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_oct|FLAGS_showbase, 6, '*', 4, "*030", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_oct|FLAGS_dec|FLAGS_showbase, 6, ' ', 0, "030", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_oct|FLAGS_dec|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_left|FLAGS_oct|FLAGS_hex, 6, ' ', 5, "18 ", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_dec|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
+ {INT, {.i = 24}, IOSTATE_goodbit, FLAGS_dec|FLAGS_showbase, 6, ' ', 0, "24", IOSTATE_goodbit},
+ {INT, {.i = 55}, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_uppercase, 6, ' ', 0, "0X37", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_showpoint|FLAGS_uppercase, 6, ' ', 0, "0X400", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_showpos, 6, ' ', 0, "0x400", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_hex|FLAGS_showpos, 6, ' ', 0, "400", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_oct|FLAGS_showpos, 6, ' ', 0, "2000", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_internal|FLAGS_oct|FLAGS_showbase, 6, 'x', 8, "0xxx2000", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_showbase|FLAGS_showpoint|FLAGS_showpos, 6, ' ', 0, "+1024", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_dec|FLAGS_showbase|FLAGS_showpos, 6, 'a', 6, "a+1024", IOSTATE_goodbit},
+ {INT, {.i = 1024}, IOSTATE_goodbit, FLAGS_internal|FLAGS_showbase|FLAGS_showpos, 6, ' ', 8, "+ 1024", IOSTATE_goodbit},
+ {INT, {.i = 1023}, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_uppercase, 6, ' ', 0, "0X3FF", IOSTATE_goodbit},
+ {INT, {.i = 1023}, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_scientific, 6, ' ', 0, "0x3ff", IOSTATE_goodbit},
+ {INT, {.i = 65536}, IOSTATE_goodbit, FLAGS_right|FLAGS_showpos|FLAGS_fixed, 6, ' ', 8, " +65536", IOSTATE_goodbit},
+ {INT, {.i = 2147483647}, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x7fffffff", IOSTATE_goodbit},
+ {INT, {.i = 2147483648}, IOSTATE_goodbit, FLAGS_dec, 6, ' ', 0, "-2147483648", IOSTATE_goodbit},
+ {INT, {.i = 4294967295}, IOSTATE_goodbit, FLAGS_internal, 6, ' ', 8, " -1", IOSTATE_goodbit},
+ {INT, {.i = -20}, IOSTATE_goodbit, FLAGS_internal|FLAGS_oct|FLAGS_showbase, 6, ' ', 8, "037777777754", IOSTATE_goodbit},
+ {INT, {.i = -20}, IOSTATE_goodbit, FLAGS_dec|FLAGS_showpos, 6, ' ', 0, "-20", IOSTATE_goodbit},
+ {INT, {.i = 0}, IOSTATE_goodbit, FLAGS_internal|FLAGS_showpos, 6, ' ', 8, " 0", IOSTATE_goodbit}
};
pssb = (strstreambuf*) call_func1(p_strstreambuf_ctor, &ssb);
@@ -3072,6 +3109,8 @@ static void test_ostream_print(void)
pos = (ostream*) call_func2(p_ostream_print_char, &os, (int) tests[i].param.c); break;
case STR:
pos = (ostream*) call_func2(p_ostream_print_str, &os, tests[i].param.str); break;
+ case INT:
+ pos = (ostream*) call_func2(p_ostream_print_int, &os, tests[i].param.i); break;
}
length = ssb.base.pptr - ssb.base.pbase;
--
2.7.4
More information about the wine-patches
mailing list