From 71cc73578557fda4ad40c04729f20f5cea58b0ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Sun, 12 Feb 2017 20:04:19 -0800 Subject: [PATCH] vsnprintf: Added more unit tests. --- include/bx/string.h | 6 ++++++ src/crt.cpp | 45 ++++++++++++++++++++++++++-------------- src/dtoa.cpp | 28 ++++++++++++------------- src/string.cpp | 20 ++++++++++++++++++ tests/string_test.cpp | 2 +- tests/vsnprintf_test.cpp | 8 +++++++ 6 files changed, 79 insertions(+), 30 deletions(-) diff --git a/include/bx/string.h b/include/bx/string.h index 7789fc8..21ec6ea 100644 --- a/include/bx/string.h +++ b/include/bx/string.h @@ -110,9 +110,15 @@ namespace bx /// char toLower(char _ch); + /// + void toLower(char* _inOutStr, size_t _max = INT32_MAX); + /// char toUpper(char _ch); + /// + void toUpper(char* _inOutStr, size_t _max = INT32_MAX); + /// bool toBool(const char* _str); diff --git a/src/crt.cpp b/src/crt.cpp index fda52a0..00e9f2f 100644 --- a/src/crt.cpp +++ b/src/crt.cpp @@ -286,22 +286,30 @@ namespace bx return 0; } - const char* dot = strnchr(str, '.'); - const int32_t precLen = int32_t( - dot - + uint32_min(_param.prec + _param.spec, 1) - + _param.prec - - str - ); - if (precLen > len) + if (_param.upper) { - for (int32_t ii = len; ii < precLen; ++ii) - { - str[ii] = '0'; - } - str[precLen] = '\0'; + toUpper(str, len); + } + + const char* dot = strnchr(str, '.'); + if (NULL != dot) + { + const int32_t precLen = int32_t( + dot + + uint32_min(_param.prec + _param.spec, 1) + + _param.prec + - str + ); + if (precLen > len) + { + for (int32_t ii = len; ii < precLen; ++ii) + { + str[ii] = '0'; + } + str[precLen] = '\0'; + } + len = precLen; } - len = precLen; return write(_writer, str, len, _param, _err); } @@ -440,9 +448,15 @@ namespace bx { case 'h': param.bits = sizeof(signed char )*8; break; case 'l': param.bits = sizeof(long long int)*8; break; + case '3': case '6': read(&reader, ch); - if ('4' == ch) { param.bits = sizeof(int64_t)*8; } + switch (ch) + { + case '2': param.bits = sizeof(int32_t)*8; break; + case '4': param.bits = sizeof(int64_t)*8; break; + default: break; + } break; default: seek(&reader, -1); break; @@ -484,6 +498,7 @@ namespace bx break; case 'f': + param.upper = isUpper(ch); size += write(_writer, va_arg(_argList, double), param, _err); break; diff --git a/src/dtoa.cpp b/src/dtoa.cpp index 6b7280a..4dd0079 100644 --- a/src/dtoa.cpp +++ b/src/dtoa.cpp @@ -424,34 +424,34 @@ namespace bx return length + 2 + exp; } - int32_t toString(char* _dst, size_t _max, double value) + int32_t toString(char* _dst, size_t _max, double _value) { - if (isNan(value) ) - { - return (int32_t)strlncpy(_dst, _max, "NaN"); - } - else if (isInfinite(value) ) - { - return (int32_t)strlncpy(_dst, _max, "Inf"); - } - - int32_t sign = 0.0 > value ? 1 : 0; + int32_t sign = 0 != (doubleToBits(_value) & (UINT64_C(1)<<63) ) ? 1 : 0; if (1 == sign) { *_dst++ = '-'; --_max; - value = -value; + _value = -_value; + } + + if (isNan(_value) ) + { + return (int32_t)strlncpy(_dst, _max, "nan") + sign; + } + else if (isInfinite(_value) ) + { + return (int32_t)strlncpy(_dst, _max, "inf") + sign; } int32_t len; - if (0.0 == value) + if (0.0 == _value) { len = (int32_t)strlncpy(_dst, _max, "0.0"); } else { int32_t kk; - Grisu2(value, _dst, &len, &kk); + Grisu2(_value, _dst, &len, &kk); len = Prettify(_dst, len, kk); } diff --git a/src/string.cpp b/src/string.cpp index b003494..4093e4e 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -60,11 +60,31 @@ namespace bx return _ch + (isUpper(_ch) ? 0x20 : 0); } + void toLower(char* _inOutStr, size_t _max) + { + size_t len = strnlen(_inOutStr, _max); + + for (size_t ii = 0; ii < len; ++ii) + { + *_inOutStr = toLower(*_inOutStr); + } + } + char toUpper(char _ch) { return _ch - (isLower(_ch) ? 0x20 : 0); } + void toUpper(char* _inOutStr, size_t _max) + { + size_t len = strnlen(_inOutStr, _max); + + for (size_t ii = 0; ii < len; ++ii) + { + *_inOutStr = toUpper(*_inOutStr); + } + } + bool toBool(const char* _str) { char ch = toLower(_str[0]); diff --git a/tests/string_test.cpp b/tests/string_test.cpp index 0c8955e..6b4d5e9 100644 --- a/tests/string_test.cpp +++ b/tests/string_test.cpp @@ -152,7 +152,7 @@ TEST_CASE("toString int32_t/uint32_t", "") TEST_CASE("toString double", "") { REQUIRE(testToString(0.0, "0.0") ); - REQUIRE(testToString(-0.0, "0.0") ); + REQUIRE(testToString(-0.0, "-0.0") ); REQUIRE(testToString(1.0, "1.0") ); REQUIRE(testToString(-1.0, "-1.0") ); REQUIRE(testToString(1.2345, "1.2345") ); diff --git a/tests/vsnprintf_test.cpp b/tests/vsnprintf_test.cpp index cf524d0..24a4d20 100644 --- a/tests/vsnprintf_test.cpp +++ b/tests/vsnprintf_test.cpp @@ -6,6 +6,7 @@ #include "test.h" #include #include +#include TEST_CASE("vsnprintf NULL buffer", "No output buffer provided.") { @@ -52,6 +53,13 @@ TEST_CASE("vsnprintf f", "") REQUIRE(test(" 13.370", "%*.*f", 8, 3, 13.37) ); REQUIRE(test("13.370 ", "%-8.3f", 13.37) ); REQUIRE(test("13.370 ", "%*.*f", -8, 3, 13.37) ); + + REQUIRE(test("nan ", "%-8f", NAN) ); + REQUIRE(test(" nan", "%8f", NAN) ); + REQUIRE(test("-NAN ", "%-8F", -NAN) ); + REQUIRE(test(" inf", "%8f", INFINITY) ); + REQUIRE(test("inf ", "%-8f", INFINITY) ); + REQUIRE(test(" -INF", "%8F", -INFINITY) ); } TEST_CASE("vsnprintf d/i/o/u/x", "")