Simplify format string parsing

This commit is contained in:
Victor Zverovich
2022-12-30 10:58:22 -08:00
parent ffb9b1d13c
commit a05ba44df8
5 changed files with 90 additions and 106 deletions

View File

@@ -489,13 +489,29 @@ TEST(core_test, has_sign) {
type::int128_type, type::float_type,
type::double_type, type::long_double_type};
for (auto t : types_with_sign) EXPECT_TRUE(fmt::detail::has_sign(t));
type types_without_sign[] = {type::uint_type, type::ulong_long_type,
type::uint128_type, type::bool_type,
type::char_type, type::string_type,
type::cstring_type, type::custom_type};
type types_without_sign[] = {
type::none_type, type::uint_type, type::ulong_long_type,
type::uint128_type, type::bool_type, type::char_type,
type::string_type, type::cstring_type, type::custom_type};
for (auto t : types_without_sign) EXPECT_FALSE(fmt::detail::has_sign(t));
}
TEST(core_test, has_precision) {
using fmt::detail::type;
type types_with_precision[] = {type::float_type, type::double_type,
type::long_double_type, type::string_type,
type::cstring_type};
for (auto t : types_with_precision)
EXPECT_TRUE(fmt::detail::has_precision(t));
type types_without_precision[] = {type::none_type, type::int_type,
type::uint_type, type::long_long_type,
type::ulong_long_type, type::int128_type,
type::uint128_type, type::bool_type,
type::char_type, type::custom_type};
for (auto t : types_without_precision)
EXPECT_FALSE(fmt::detail::has_precision(t));
}
#if FMT_USE_CONSTEXPR
enum class arg_id_result { none, empty, index, name };

View File

@@ -766,10 +766,10 @@ TEST(format_test, hash_flag) {
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), 'c'), format_error,
"invalid format specifier for char");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), "abc"), format_error,
"format specifier requires numeric argument");
"invalid format specifier");
EXPECT_THROW_MSG(
(void)fmt::format(runtime("{0:#}"), reinterpret_cast<void*>(0x42)),
format_error, "format specifier requires numeric argument");
format_error, "invalid format specifier");
}
TEST(format_test, zero_flag) {
@@ -907,54 +907,54 @@ TEST(format_test, precision) {
char format_str[buffer_size];
safe_sprintf(format_str, "{0:.%u", UINT_MAX);
increment(format_str + 4);
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error,
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
"number is too big");
size_t size = std::strlen(format_str);
format_str[size] = '}';
format_str[size + 1] = 0;
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error,
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
"number is too big");
safe_sprintf(format_str, "{0:.%u", INT_MAX + 1u);
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error,
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
"number is too big");
safe_sprintf(format_str, "{0:.%u}", INT_MAX + 1u);
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0), format_error,
EXPECT_THROW_MSG((void)fmt::format(runtime(format_str), 0.0), format_error,
"number is too big");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:."), 0), format_error,
"missing precision");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.}"), 0), format_error,
"missing precision");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:."), 0.0), format_error,
"invalid precision");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.}"), 0.0), format_error,
"invalid precision");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2"), 0), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42u), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42u), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42l), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42l), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ul), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ul), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ll), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ll), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2}"), 42ull), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.2f}"), 42ull), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:3.0}"), 'x'), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_EQ("1.2", fmt::format("{0:.2}", 1.2345));
EXPECT_EQ("1.2", fmt::format("{0:.2}", 1.2345l));
EXPECT_EQ("1.2e+56", fmt::format("{:.2}", 1.234e56));
@@ -1033,10 +1033,10 @@ TEST(format_test, precision) {
EXPECT_THROW_MSG(
(void)fmt::format(runtime("{0:.2}"), reinterpret_cast<void*>(0xcafe)),
format_error, "precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG(
(void)fmt::format(runtime("{0:.2f}"), reinterpret_cast<void*>(0xcafe)),
format_error, "precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{:.{}e}"), 42.0,
fmt::detail::max_value<int>()),
format_error, "number is too big");
@@ -1071,7 +1071,7 @@ TEST(format_test, runtime_precision) {
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{?}}"), 0.0), format_error,
"invalid format string");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}"), 0, 0), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 0.0), format_error,
"argument not found");
@@ -1098,51 +1098,40 @@ TEST(format_test, runtime_precision) {
format_error, "precision is not integer");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42, 2), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42, 2), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42u, 2), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42u, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42l, 2), format_error,
"precision not allowed for this argument type");
"invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42l, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ul, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ul, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ll, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ll, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"), 42ull, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"), 42ull, 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:3.{1}}"), 'x', 0),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_EQ("1.2", fmt::format("{0:.{1}}", 1.2345, 2));
EXPECT_EQ("1.2", fmt::format("{1:.{0}}", 2, 1.2345l));
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}}"),
reinterpret_cast<void*>(0xcafe), 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:.{1}f}"),
reinterpret_cast<void*>(0xcafe), 2),
format_error,
"precision not allowed for this argument type");
format_error, "invalid format specifier");
EXPECT_EQ("st", fmt::format("{0:.{1}}", "str", 2));
}

View File

@@ -92,7 +92,7 @@ TEST(ostream_test, format_specs) {
EXPECT_THROW_MSG((void)fmt::format(runtime("{0: }"), test_string()),
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:#}"), test_string()),
format_error, "format specifier requires numeric argument");
format_error, "invalid format specifier");
EXPECT_THROW_MSG((void)fmt::format(runtime("{0:05}"), test_string()),
format_error, "format specifier requires numeric argument");
EXPECT_EQ("test ", fmt::format("{0:13}", test_string("test")));