forked from fmtlib/fmt
Fix compile-time parsing and add more tests
This commit is contained in:
@ -841,7 +841,7 @@ class null_terminating_iterator {
|
|||||||
return ptr_ - other.ptr_;
|
return ptr_ - other.ptr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(null_terminating_iterator other) const {
|
constexpr bool operator!=(null_terminating_iterator other) const {
|
||||||
return ptr_ != other.ptr_;
|
return ptr_ != other.ptr_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2570,10 +2570,13 @@ constexpr void parse_format_string(Iterator it, Handler &&handler) {
|
|||||||
} else if (*it == ':') {
|
} else if (*it == ':') {
|
||||||
++it;
|
++it;
|
||||||
it = handler.on_format_specs(it);
|
it = handler.on_format_specs(it);
|
||||||
if (*it != '}')
|
if (*it != '}') {
|
||||||
handler.on_error("unknown format specifier");
|
handler.on_error("unknown format specifier");
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
handler.on_error("missing '}' in format string");
|
handler.on_error("missing '}' in format string");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
start = ++it;
|
start = ++it;
|
||||||
@ -2591,7 +2594,7 @@ template <typename Char, typename ErrorHandler, typename... Args>
|
|||||||
class format_string_checker : public ErrorHandler {
|
class format_string_checker : public ErrorHandler {
|
||||||
public:
|
public:
|
||||||
explicit constexpr format_string_checker(ErrorHandler eh, const Char *end)
|
explicit constexpr format_string_checker(ErrorHandler eh, const Char *end)
|
||||||
: ErrorHandler(std::move(eh)), end_(end) {}
|
: ErrorHandler(eh), end_(end) {}
|
||||||
|
|
||||||
constexpr void on_text(const Char *, const Char *) {}
|
constexpr void on_text(const Char *, const Char *) {}
|
||||||
|
|
||||||
@ -2613,8 +2616,10 @@ class format_string_checker : public ErrorHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
constexpr static size_t NUM_ARGS = sizeof...(Args);
|
||||||
|
|
||||||
constexpr void check_arg_index() {
|
constexpr void check_arg_index() {
|
||||||
if (arg_index_ < 0 || arg_index_ >= sizeof...(Args))
|
if (arg_index_ < 0 || arg_index_ >= NUM_ARGS)
|
||||||
this->on_error("argument index out of range");
|
this->on_error("argument index out of range");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2623,7 +2628,7 @@ class format_string_checker : public ErrorHandler {
|
|||||||
|
|
||||||
const Char *end_;
|
const Char *end_;
|
||||||
int arg_index_ = -1;
|
int arg_index_ = -1;
|
||||||
parse_func parse_funcs_[sizeof...(Args)] = {
|
parse_func parse_funcs_[NUM_ARGS > 0 ? NUM_ARGS : 1] = {
|
||||||
&parse_format_specs<Char, Args>...
|
&parse_format_specs<Char, Args>...
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -1858,4 +1858,6 @@ TEST(FormatTest, FormatStringErrors) {
|
|||||||
EXPECT_ERROR("foo", nullptr);
|
EXPECT_ERROR("foo", nullptr);
|
||||||
EXPECT_ERROR("}", "unmatched '}' in format string");
|
EXPECT_ERROR("}", "unmatched '}' in format string");
|
||||||
EXPECT_ERROR("{0:s", "unknown format specifier", Date);
|
EXPECT_ERROR("{0:s", "unknown format specifier", Date);
|
||||||
|
EXPECT_ERROR("{0:=5", "unknown format specifier", char);
|
||||||
|
EXPECT_ERROR("{foo", "missing '}' in format string", int);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user