mirror of
https://github.com/fmtlib/fmt.git
synced 2024-12-24 21:16:56 +00:00
Rewrite length specifier tests without using printf to workaround broken MSVC implementation.
This commit is contained in:
parent
137153b9f0
commit
adbf3f8b86
@ -273,15 +273,6 @@ TEST(PrintfTest, DynamicPrecision) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSupported(const std::string &format) {
|
|
||||||
#if _MSC_VER
|
|
||||||
// MSVC doesn't support hh, j, z and t format specifiers.
|
|
||||||
return format.substr(1, 2) != "hh";
|
|
||||||
#else
|
|
||||||
return true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct MakeSigned { typedef T Type; };
|
struct MakeSigned { typedef T Type; };
|
||||||
|
|
||||||
@ -297,66 +288,62 @@ SPECIALIZE_MAKE_SIGNED(unsigned long, long);
|
|||||||
SPECIALIZE_MAKE_SIGNED(fmt::ULongLong, fmt::LongLong);
|
SPECIALIZE_MAKE_SIGNED(fmt::ULongLong, fmt::LongLong);
|
||||||
|
|
||||||
template <typename T, typename U>
|
template <typename T, typename U>
|
||||||
std::string sprintf_int(std::string format, U value) {
|
void TestLength(const char *length_spec, U value) {
|
||||||
char buffer[BUFFER_SIZE];
|
std::ostringstream os;
|
||||||
char type = format[format.size() - 1];
|
// Use LongLong instead of T, because std::ostream prints signed char as
|
||||||
if (sizeof(T) < sizeof(int)) {
|
// a character, not a number.
|
||||||
if (type == 'd' || type == 'i') {
|
os << static_cast<fmt::LongLong>(
|
||||||
typedef typename MakeSigned<T>::Type Signed;
|
static_cast<typename MakeSigned<T>::Type>(value));
|
||||||
safe_sprintf(buffer, format.c_str(), static_cast<Signed>(value));
|
EXPECT_PRINTF(os.str(), fmt::format("%{}d", length_spec), value);
|
||||||
} else {
|
EXPECT_PRINTF(os.str(), fmt::format("%{}i", length_spec), value);
|
||||||
typedef typename fmt::internal::MakeUnsigned<T>::Type Unsigned;
|
fmt::ULongLong unsigned_value =
|
||||||
safe_sprintf(buffer, format.c_str(), static_cast<Unsigned>(value));
|
static_cast<typename fmt::internal::MakeUnsigned<T>::Type>(value);
|
||||||
}
|
os.str("");
|
||||||
} else {
|
os << unsigned_value;
|
||||||
safe_sprintf(buffer, format.c_str(), value);
|
EXPECT_PRINTF(os.str(), fmt::format("%{}u", length_spec), value);
|
||||||
}
|
os.str("");
|
||||||
return buffer;
|
os << std::oct << unsigned_value;
|
||||||
}
|
EXPECT_PRINTF(os.str(), fmt::format("%{}o", length_spec), value);
|
||||||
|
os.str("");
|
||||||
#define EXPECT_STD_PRINTF(format, T, arg) { \
|
os << std::hex << unsigned_value;
|
||||||
char buffer[BUFFER_SIZE]; \
|
EXPECT_PRINTF(os.str(), fmt::format("%{}x", length_spec), value);
|
||||||
if (IsSupported(format)) { \
|
os.str("");
|
||||||
safe_sprintf(buffer, fmt::StringRef(format).c_str(), arg); \
|
os << std::hex << std::uppercase << unsigned_value;
|
||||||
EXPECT_PRINTF(buffer, format, arg); \
|
EXPECT_PRINTF(os.str(), fmt::format("%{}X", length_spec), value);
|
||||||
} \
|
|
||||||
EXPECT_PRINTF(sprintf_int<T>(format, arg), format, arg); \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void TestLength(const char *length_spec) {
|
void TestLength(const char *length_spec) {
|
||||||
T min = std::numeric_limits<T>::min(), max = std::numeric_limits<T>::max();
|
T min = std::numeric_limits<T>::min(), max = std::numeric_limits<T>::max();
|
||||||
const char types[] = {'d', 'i', 'u', 'o', 'x', 'X'};
|
TestLength<T>(length_spec, 42);
|
||||||
for (int i = 0; i < sizeof(types); ++i) {
|
TestLength<T>(length_spec, -42);
|
||||||
std::string format = fmt::format("%{}{}", length_spec, types[i]);
|
TestLength<T>(length_spec, min);
|
||||||
EXPECT_STD_PRINTF(format, T, 42);
|
TestLength<T>(length_spec, max);
|
||||||
EXPECT_STD_PRINTF(format, T, min);
|
TestLength<T>(length_spec, fmt::LongLong(min) - 1);
|
||||||
EXPECT_STD_PRINTF(format, T, max);
|
TestLength<T>(length_spec, fmt::LongLong(max) + 1);
|
||||||
EXPECT_STD_PRINTF(format, T, fmt::LongLong(min) - 1);
|
TestLength<T>(length_spec, std::numeric_limits<short>::min());
|
||||||
EXPECT_STD_PRINTF(format, T, fmt::LongLong(max) + 1);
|
TestLength<T>(length_spec, std::numeric_limits<unsigned short>::max());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<short>::min());
|
TestLength<T>(length_spec, std::numeric_limits<int>::min());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<unsigned short>::max());
|
TestLength<T>(length_spec, std::numeric_limits<int>::max());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<int>::min());
|
TestLength<T>(length_spec, std::numeric_limits<unsigned>::min());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<int>::max());
|
TestLength<T>(length_spec, std::numeric_limits<unsigned>::max());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<unsigned>::min());
|
TestLength<T>(length_spec, std::numeric_limits<fmt::LongLong>::min());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<unsigned>::max());
|
TestLength<T>(length_spec, std::numeric_limits<fmt::LongLong>::max());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<fmt::LongLong>::min());
|
TestLength<T>(length_spec, std::numeric_limits<fmt::ULongLong>::min());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<fmt::LongLong>::max());
|
TestLength<T>(length_spec, std::numeric_limits<fmt::ULongLong>::max());
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<fmt::ULongLong>::min());
|
|
||||||
EXPECT_STD_PRINTF(format, T, std::numeric_limits<fmt::ULongLong>::max());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(PrintfTest, Length) {
|
TEST(PrintfTest, Length) {
|
||||||
|
TestLength<char>("hh");
|
||||||
TestLength<signed char>("hh");
|
TestLength<signed char>("hh");
|
||||||
TestLength<unsigned char>("hh");
|
TestLength<unsigned char>("hh");
|
||||||
TestLength<short>("h");
|
/*TestLength<short>("h");
|
||||||
TestLength<unsigned short>("h");
|
TestLength<unsigned short>("h");
|
||||||
TestLength<long>("l");
|
TestLength<long>("l");
|
||||||
//TestLength<unsigned long>("l");
|
TestLength<unsigned long>("l");
|
||||||
// TODO: more tests
|
// TODO: more tests
|
||||||
EXPECT_EQ("-1", sprintf_int<unsigned char>("%hhd", UCHAR_MAX));
|
EXPECT_EQ("-1", sprintf_int<unsigned char>("%hhd", UCHAR_MAX));
|
||||||
EXPECT_EQ("255", sprintf_int<unsigned char>("%hhu", UCHAR_MAX));
|
EXPECT_EQ("255", sprintf_int<unsigned char>("%hhu", UCHAR_MAX));*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: test type specifier
|
// TODO: test type specifier
|
||||||
|
Loading…
Reference in New Issue
Block a user