Commit 686ff942 authored by Victor Zverovich's avatar Victor Zverovich

Fix compile-time parsing and add more tests

parent 5b95b5d7
...@@ -841,7 +841,7 @@ class null_terminating_iterator { ...@@ -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) { ...@@ -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> ...@@ -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 { ...@@ -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 { ...@@ -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) { ...@@ -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);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment