[v2 3/7] msvcirt: Implement ostream::operator<< for integers

Iván Matellanes matellanesivan at gmail.com
Wed Jun 22 04:53:04 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 9ec61c3..9988944 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 46d2e97..6a89519 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");
@@ -3017,8 +3020,9 @@ static void test_ostream_print(void)
 
     char param_char[] = {'a', '9', 'e'};
     const char* param_str[] = {"Test", "800", "3.14159", " Test"};
+    int param_int[] = {0, 7, 10, 24 ,55, 1024, 1023, 65536, 2147483647, 2147483648, 4294967295, -20};
     struct ostream_print_test {
-        enum { CHAR, STR } type;
+        enum { CHAR, STR, INT } type;
         int param_index;
         ios_io_state state;
         ios_flags flags;
@@ -3050,7 +3054,40 @@ static void test_ostream_print(void)
         {STR, /* "Test" */ 0, IOSTATE_goodbit, FLAGS_left|FLAGS_hex|FLAGS_showpoint, 6, '?', 6, "Test??", IOSTATE_goodbit},
         {STR, /* "800" */ 1, IOSTATE_goodbit, FLAGS_showbase|FLAGS_showpos, 6, ' ', 4, " 800", IOSTATE_goodbit},
         {STR, /* "3.14159" */ 2, IOSTATE_goodbit, FLAGS_scientific, 2, 'x', 2, "3.14159", IOSTATE_goodbit},
-        {STR, /* " Test" */ 3, IOSTATE_goodbit, FLAGS_skipws, 6, 'x', 2, " Test", IOSTATE_goodbit}
+        {STR, /* " Test" */ 3, IOSTATE_goodbit, FLAGS_skipws, 6, 'x', 2, " Test", IOSTATE_goodbit},
+        /* int */
+        {INT, /* 0 */ 0, IOSTATE_badbit, 0, 6, ' ', 0, "", IOSTATE_badbit|IOSTATE_failbit},
+        {INT, /* 0 */ 0, IOSTATE_eofbit, 0, 6, ' ', 0, "", IOSTATE_eofbit|IOSTATE_failbit},
+        {INT, /* 0 */ 0, IOSTATE_goodbit, 0, 6, ' ', 4, "   0", IOSTATE_goodbit},
+        {INT, /* 7 */ 1, IOSTATE_goodbit, 0, 6, '0', 3, "007", IOSTATE_goodbit},
+        {INT, /* 10 */ 2, IOSTATE_goodbit, FLAGS_left, 6, ' ', 5, "10   ", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_left|FLAGS_hex, 6, ' ', 0, "18", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_left|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_internal|FLAGS_hex|FLAGS_showbase, 6, '*', 8, "0x****18", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_oct|FLAGS_showbase, 6, '*', 4, "*030", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_oct|FLAGS_dec|FLAGS_showbase, 6, ' ', 0, "030", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_oct|FLAGS_dec|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_left|FLAGS_oct|FLAGS_hex, 6, ' ', 5, "18   ", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_dec|FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x18", IOSTATE_goodbit},
+        {INT, /* 24 */ 3, IOSTATE_goodbit, FLAGS_dec|FLAGS_showbase, 6, ' ', 0, "24", IOSTATE_goodbit},
+        {INT, /* 55 */ 4, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_uppercase, 6, ' ', 0, "0X37", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_showpoint|FLAGS_uppercase, 6, ' ', 0, "0X400", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_showpos, 6, ' ', 0, "0x400", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_hex|FLAGS_showpos, 6, ' ', 0, "400", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_oct|FLAGS_showpos, 6, ' ', 0, "2000", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_internal|FLAGS_oct|FLAGS_showbase, 6, 'x', 8, "0xxx2000", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_showbase|FLAGS_showpoint|FLAGS_showpos, 6, ' ', 0, "+1024", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_dec|FLAGS_showbase|FLAGS_showpos, 6, 'a', 6, "a+1024", IOSTATE_goodbit},
+        {INT, /* 1024 */ 5, IOSTATE_goodbit, FLAGS_internal|FLAGS_showbase|FLAGS_showpos, 6, ' ', 8, "+   1024", IOSTATE_goodbit},
+        {INT, /* 1023 */ 6, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_uppercase, 6, ' ', 0, "0X3FF", IOSTATE_goodbit},
+        {INT, /* 1023 */ 6, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase|FLAGS_scientific, 6, ' ', 0, "0x3ff", IOSTATE_goodbit},
+        {INT, /* 65536 */ 7, IOSTATE_goodbit, FLAGS_right|FLAGS_showpos|FLAGS_fixed, 6, ' ', 8, "  +65536", IOSTATE_goodbit},
+        {INT, /* 2147483647 */ 8, IOSTATE_goodbit, FLAGS_hex|FLAGS_showbase, 6, ' ', 0, "0x7fffffff", IOSTATE_goodbit},
+        {INT, /* 2147483648 */ 9, IOSTATE_goodbit, FLAGS_dec, 6, ' ', 0, "-2147483648", IOSTATE_goodbit},
+        {INT, /* 4294967295 */ 10, IOSTATE_goodbit, FLAGS_internal, 6, ' ', 8, "      -1", IOSTATE_goodbit},
+        {INT, /* -20 */ 11, IOSTATE_goodbit, FLAGS_internal|FLAGS_oct|FLAGS_showbase, 6, ' ', 8, "037777777754", IOSTATE_goodbit},
+        {INT, /* -20 */ 11, IOSTATE_goodbit, FLAGS_dec|FLAGS_showpos, 6, ' ', 0, "-20", IOSTATE_goodbit},
+        {INT, /* 0 */ 0, IOSTATE_goodbit, FLAGS_internal|FLAGS_showpos, 6, ' ', 8, "       0", IOSTATE_goodbit}
     };
 
     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;
         case STR:
             pos = call_func2(p_ostream_print_str, &os, param_str[tests[i].param_index]); break;
+        case INT:
+            pos = call_func2(p_ostream_print_int, &os, param_int[tests[i].param_index]); break;
         }
 
         length = ssb.base.pptr - ssb.base.pbase;
-- 
2.7.4




More information about the wine-patches mailing list