mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 02:37:36 +02:00
More tests
This commit is contained in:
@ -1740,18 +1740,23 @@ constexpr void handle_integral_type_spec(char c, Handler &&handler) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct int_type_checker {
|
template <typename ErrorHandler>
|
||||||
|
class int_type_checker {
|
||||||
|
public:
|
||||||
|
constexpr int_type_checker(ErrorHandler &eh) : eh_(eh) {}
|
||||||
|
|
||||||
constexpr void on_dec() {}
|
constexpr void on_dec() {}
|
||||||
constexpr void on_hex() {}
|
constexpr void on_hex() {}
|
||||||
constexpr void on_bin() {}
|
constexpr void on_bin() {}
|
||||||
constexpr void on_oct() {}
|
constexpr void on_oct() {}
|
||||||
constexpr void on_num() {}
|
constexpr void on_num() {}
|
||||||
|
|
||||||
template <typename T = void>
|
|
||||||
constexpr void on_error() {
|
constexpr void on_error() {
|
||||||
error_handler eh;
|
eh_.on_error("invalid type specifier");
|
||||||
eh.on_error("invalid type specifier");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ErrorHandler &eh_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Context>
|
template <typename Context>
|
||||||
@ -2218,10 +2223,8 @@ class specs_checker : public Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
constexpr void end_precision() {
|
constexpr void end_precision() {
|
||||||
if (is_integral(arg_type_) || arg_type_ == POINTER) {
|
if (is_integral(arg_type_) || arg_type_ == POINTER)
|
||||||
report_error("precision not allowed in {} format specifier",
|
this->on_error("precision not allowed for this argument type");
|
||||||
arg_type_ == POINTER ? "pointer" : "integer");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -2642,7 +2645,8 @@ class format_string_checker : public ErrorHandler {
|
|||||||
constexpr static size_t NUM_ARGS = sizeof...(Args);
|
constexpr static size_t NUM_ARGS = sizeof...(Args);
|
||||||
|
|
||||||
constexpr void check_arg_index() {
|
constexpr void check_arg_index() {
|
||||||
if (arg_index_ < 0 || arg_index_ >= NUM_ARGS)
|
unsigned unsigned_index = arg_index_;
|
||||||
|
if (arg_index_ < 0 || unsigned_index >= NUM_ARGS)
|
||||||
this->on_error("argument index out of range");
|
this->on_error("argument index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3189,16 +3193,16 @@ typename basic_writer<Char>::pointer_type
|
|||||||
template <typename Char>
|
template <typename Char>
|
||||||
template <typename T, typename Spec>
|
template <typename T, typename Spec>
|
||||||
void basic_writer<Char>::write_int(T value, const Spec& spec) {
|
void basic_writer<Char>::write_int(T value, const Spec& spec) {
|
||||||
|
using unsigned_type = typename internal::int_traits<T>::main_type;
|
||||||
struct spec_handler {
|
struct spec_handler {
|
||||||
basic_writer<Char> &writer;
|
basic_writer<Char> &writer;
|
||||||
const Spec& spec;
|
const Spec& spec;
|
||||||
unsigned prefix_size = 0;
|
unsigned prefix_size = 0;
|
||||||
typedef typename internal::int_traits<T>::main_type UnsignedType;
|
unsigned_type abs_value;
|
||||||
UnsignedType abs_value;
|
|
||||||
char prefix[4] = "";
|
char prefix[4] = "";
|
||||||
|
|
||||||
spec_handler(basic_writer<Char> &w, T value, const Spec& s)
|
spec_handler(basic_writer<Char> &w, T value, const Spec& s)
|
||||||
: writer(w), spec(s), abs_value(static_cast<UnsignedType>(value)) {
|
: writer(w), spec(s), abs_value(static_cast<unsigned_type>(value)) {
|
||||||
if (internal::is_negative(value)) {
|
if (internal::is_negative(value)) {
|
||||||
prefix[0] = '-';
|
prefix[0] = '-';
|
||||||
++prefix_size;
|
++prefix_size;
|
||||||
@ -3217,7 +3221,7 @@ void basic_writer<Char>::write_int(T value, const Spec& spec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void on_hex() {
|
void on_hex() {
|
||||||
UnsignedType n = abs_value;
|
unsigned_type n = abs_value;
|
||||||
if (spec.flag(HASH_FLAG)) {
|
if (spec.flag(HASH_FLAG)) {
|
||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
prefix[prefix_size++] = spec.type();
|
prefix[prefix_size++] = spec.type();
|
||||||
@ -3237,7 +3241,7 @@ void basic_writer<Char>::write_int(T value, const Spec& spec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void on_bin() {
|
void on_bin() {
|
||||||
UnsignedType n = abs_value;
|
unsigned_type n = abs_value;
|
||||||
if (spec.flag(HASH_FLAG)) {
|
if (spec.flag(HASH_FLAG)) {
|
||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
prefix[prefix_size++] = spec.type();
|
prefix[prefix_size++] = spec.type();
|
||||||
@ -3255,7 +3259,7 @@ void basic_writer<Char>::write_int(T value, const Spec& spec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void on_oct() {
|
void on_oct() {
|
||||||
UnsignedType n = abs_value;
|
unsigned_type n = abs_value;
|
||||||
if (spec.flag(HASH_FLAG))
|
if (spec.flag(HASH_FLAG))
|
||||||
prefix[prefix_size++] = '0';
|
prefix[prefix_size++] = '0';
|
||||||
unsigned num_digits = 0;
|
unsigned num_digits = 0;
|
||||||
@ -3764,8 +3768,10 @@ struct formatter<
|
|||||||
internal::specs_checker<handler_type>
|
internal::specs_checker<handler_type>
|
||||||
handler(handler_type(specs_, ctx), internal::get_type<T>());
|
handler(handler_type(specs_, ctx), internal::get_type<T>());
|
||||||
it = parse_format_specs(it, handler);
|
it = parse_format_specs(it, handler);
|
||||||
if (std::is_integral<T>::value)
|
if (std::is_integral<T>::value) {
|
||||||
handle_integral_type_spec(specs_.type(), internal::int_type_checker());
|
handle_integral_type_spec(
|
||||||
|
specs_.type(), internal::int_type_checker<ParseContext>(ctx));
|
||||||
|
}
|
||||||
return pointer_from(it);
|
return pointer_from(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3951,6 +3957,7 @@ class udl_formatter {
|
|||||||
constexpr bool invalid_format =
|
constexpr bool invalid_format =
|
||||||
check_format_string<Char, error_handler, Args...>(
|
check_format_string<Char, error_handler, Args...>(
|
||||||
basic_string_view<Char>(s, sizeof...(CHARS)));
|
basic_string_view<Char>(s, sizeof...(CHARS)));
|
||||||
|
(void)invalid_format;
|
||||||
return format(s, args...);
|
return format(s, args...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -847,40 +847,40 @@ TEST(FormatterTest, Precision) {
|
|||||||
format_error, "missing precision specifier");
|
format_error, "missing precision specifier");
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2", 0),
|
EXPECT_THROW_MSG(format("{0:.2", 0),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42),
|
EXPECT_THROW_MSG(format("{0:.2}", 42),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42u),
|
EXPECT_THROW_MSG(format("{0:.2}", 42u),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42u),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42u),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42l),
|
EXPECT_THROW_MSG(format("{0:.2}", 42l),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42l),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42l),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42ul),
|
EXPECT_THROW_MSG(format("{0:.2}", 42ul),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42ul),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42ul),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42ll),
|
EXPECT_THROW_MSG(format("{0:.2}", 42ll),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42ll),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42ll),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", 42ull),
|
EXPECT_THROW_MSG(format("{0:.2}", 42ull),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", 42ull),
|
EXPECT_THROW_MSG(format("{0:.2f}", 42ull),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:3.0}", 'x'),
|
EXPECT_THROW_MSG(format("{0:3.0}", 'x'),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_EQ("1.2", format("{0:.2}", 1.2345));
|
EXPECT_EQ("1.2", format("{0:.2}", 1.2345));
|
||||||
EXPECT_EQ("1.2", format("{0:.2}", 1.2345l));
|
EXPECT_EQ("1.2", format("{0:.2}", 1.2345l));
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.2}", reinterpret_cast<void*>(0xcafe)),
|
EXPECT_THROW_MSG(format("{0:.2}", reinterpret_cast<void*>(0xcafe)),
|
||||||
format_error, "precision not allowed in pointer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)),
|
EXPECT_THROW_MSG(format("{0:.2f}", reinterpret_cast<void*>(0xcafe)),
|
||||||
format_error, "precision not allowed in pointer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
|
|
||||||
EXPECT_EQ("st", format("{0:.2}", "str"));
|
EXPECT_EQ("st", format("{0:.2}", "str"));
|
||||||
}
|
}
|
||||||
@ -905,7 +905,7 @@ TEST(FormatterTest, RuntimePrecision) {
|
|||||||
EXPECT_THROW_MSG(format("{0:.{?}}", 0),
|
EXPECT_THROW_MSG(format("{0:.{?}}", 0),
|
||||||
format_error, "invalid format string");
|
format_error, "invalid format string");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}", 0, 0),
|
EXPECT_THROW_MSG(format("{0:.{1}", 0, 0),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 0),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 0),
|
||||||
format_error, "argument index out of range");
|
format_error, "argument index out of range");
|
||||||
|
|
||||||
@ -932,38 +932,38 @@ TEST(FormatterTest, RuntimePrecision) {
|
|||||||
format_error, "precision is not integer");
|
format_error, "precision is not integer");
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42u, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42u, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42u, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42u, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42l, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42l, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42l, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42l, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42ul, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42ul, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ul, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ul, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42ll, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42ll, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ll, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ll, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", 42ull, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", 42ull, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", 42ull, 2),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:3.{1}}", 'x', 0),
|
EXPECT_THROW_MSG(format("{0:3.{1}}", 'x', 0),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2));
|
EXPECT_EQ("1.2", format("{0:.{1}}", 1.2345, 2));
|
||||||
EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l));
|
EXPECT_EQ("1.2", format("{1:.{0}}", 2, 1.2345l));
|
||||||
|
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}}", reinterpret_cast<void*>(0xcafe), 2),
|
EXPECT_THROW_MSG(format("{0:.{1}}", reinterpret_cast<void*>(0xcafe), 2),
|
||||||
format_error, "precision not allowed in pointer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2),
|
EXPECT_THROW_MSG(format("{0:.{1}f}", reinterpret_cast<void*>(0xcafe), 2),
|
||||||
format_error, "precision not allowed in pointer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
|
|
||||||
EXPECT_EQ("st", format("{0:.{1}}", "str", 2));
|
EXPECT_EQ("st", format("{0:.{1}}", "str", 2));
|
||||||
}
|
}
|
||||||
@ -1578,7 +1578,7 @@ TEST(FormatTest, DynamicFormatter) {
|
|||||||
EXPECT_THROW_MSG(format("{:0}", str),
|
EXPECT_THROW_MSG(format("{:0}", str),
|
||||||
format_error, "format specifier '=' requires numeric argument");
|
format_error, "format specifier '=' requires numeric argument");
|
||||||
EXPECT_THROW_MSG(format("{:.2}", num),
|
EXPECT_THROW_MSG(format("{:.2}", num),
|
||||||
format_error, "precision not allowed in integer format specifier");
|
format_error, "precision not allowed for this argument type");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct test_arg_id_handler {
|
struct test_arg_id_handler {
|
||||||
@ -1876,4 +1876,10 @@ TEST(FormatTest, FormatStringErrors) {
|
|||||||
EXPECT_ERROR("{0x}", "invalid format string");
|
EXPECT_ERROR("{0x}", "invalid format string");
|
||||||
EXPECT_ERROR("{-}", "invalid format string");
|
EXPECT_ERROR("{-}", "invalid format string");
|
||||||
EXPECT_ERROR("{1}", "argument index out of range", int);
|
EXPECT_ERROR("{1}", "argument index out of range", int);
|
||||||
|
EXPECT_ERROR("{:10000000000}", "number is too big", int);
|
||||||
|
EXPECT_ERROR("{:{0x}}", "invalid format string", int);
|
||||||
|
EXPECT_ERROR("{:{-}}", "invalid format string", int);
|
||||||
|
EXPECT_ERROR("{:.10000000000}", "number is too big", int);
|
||||||
|
EXPECT_ERROR("{:.{0x}}", "invalid format string", int);
|
||||||
|
EXPECT_ERROR("{:.{-}}", "invalid format string", int);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user