diff --git a/src/string.cpp b/src/string.cpp index dba1c8c..1b85120 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -736,13 +736,28 @@ namespace bx len = min(_param.width, len); } - int32_t padding = _param.width > len ? _param.width - len : 0; - bool sign = _param.sign && len > 1 && _str[0] != '-'; - padding = padding > 0 ? padding - sign : 0; + const bool hasSign = _param.sign || _str[0] == '-'; + char sign = hasSign ? _str[0] == '-' ? '-' : '+' : '\0'; + + const char* str = _str; + if (str[0] == '-') + { + str++; + len--; + } + + int32_t padding = _param.width > len ? _param.width - len - hasSign: 0; if (!_param.left) { - size += writeRep(_writer, _param.fill, padding, _err); + if (' ' != _param.fill + && '\0' != sign) + { + size += write(_writer, sign, _err); + sign = '\0'; + } + + size += writeRep(_writer, _param.fill, max(0, padding), _err); } if (NULL == _str) @@ -753,17 +768,17 @@ namespace bx { for (int32_t ii = 0; ii < len; ++ii) { - size += write(_writer, toUpper(_str[ii]), _err); + size += write(_writer, toUpper(str[ii]), _err); } } - else if (sign) - { - size += write(_writer, '+', _err); - size += write(_writer, _str, len, _err); - } else { - size += write(_writer, _str, len, _err); + if ('\0' != sign) + { + size += write(_writer, sign, _err); + } + + size += write(_writer, str, len, _err); } if (_param.left) diff --git a/tests/vsnprintf_test.cpp b/tests/vsnprintf_test.cpp index 9a00790..ae4bb28 100644 --- a/tests/vsnprintf_test.cpp +++ b/tests/vsnprintf_test.cpp @@ -92,6 +92,10 @@ TEST_CASE("vsnprintf d/i/o/u/x") REQUIRE(test("1234ABCD ", "%-20X", 0x1234abcd) ); REQUIRE(test("edcb5433 ", "%-20x", -0x1234abcd) ); REQUIRE(test("EDCB5433 ", "%-20X", -0x1234abcd) ); + REQUIRE(test(" 1234abcd", "% 20x", 0x1234abcd) ); + REQUIRE(test(" 1234ABCD", "% 20X", 0x1234abcd) ); + REQUIRE(test(" edcb5433", "% 20x", -0x1234abcd) ); + REQUIRE(test(" EDCB5433", "% 20X", -0x1234abcd) ); REQUIRE(test("0000000000001234abcd", "%020x", 0x1234abcd) ); REQUIRE(test("0000000000001234ABCD", "%020X", 0x1234abcd) ); REQUIRE(test("000000000000edcb5433", "%020x", -0x1234abcd) ); @@ -106,6 +110,18 @@ TEST_CASE("vsnprintf d/i/o/u/x") REQUIRE(test("0xfffffff", "0x%07x", -1) ); REQUIRE(test("0xffffffff", "0x%08x", -1) ); + REQUIRE(test(" -1", "% 4i", -1) ); + REQUIRE(test(" -1", "% 4i", -1) ); + REQUIRE(test(" 0", "% 4i", 0) ); + REQUIRE(test(" 1", "% 4i", 1) ); + REQUIRE(test(" +1", "%+4i", 1) ); + REQUIRE(test(" +0", "%+4i", 0) ); + REQUIRE(test(" -1", "%+4i", -1) ); + REQUIRE(test("0001", "%04i", 1) ); + REQUIRE(test("0000", "%04i", 0) ); + REQUIRE(test("-001", "%04i", -1) ); + REQUIRE(test("+001", "%+04i", 1) ); + if (BX_ENABLED(BX_ARCH_32BIT) ) { REQUIRE(test("2147483647", "%jd", INTMAX_MAX) );