feat: formatting error messages improved

This commit is contained in:
Mateusz Pusz
2024-01-23 21:19:45 +01:00
parent dbd3bd07f1
commit 4e88298ce3
2 changed files with 19 additions and 12 deletions

View File

@@ -256,19 +256,24 @@ template<typename Char, typename Handler>
[[nodiscard]] constexpr const Char* parse_subentity_replacement_field(const Char* begin, const Char* end, [[nodiscard]] constexpr const Char* parse_subentity_replacement_field(const Char* begin, const Char* end,
Handler&& handler) Handler&& handler)
{ {
if (end - begin++ < 4) return MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format string")), end; if (end - begin++ < 4)
if (*begin++ != '%') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format")); return MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` too short")), end;
if (*begin == '}') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format")); if (*begin++ != '%')
MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should start with '%'"));
if (*begin == '}')
MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should have an identifier"));
auto it = begin; auto it = begin;
for (; it != end; ++it) { for (; it != end; ++it) {
if (*it == '{' || *it == '%') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format")); if (*it == '{' || *it == '%')
MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid `subentity-replacement-field` format"));
if (*it == '}' || *it == ':') break; if (*it == '}' || *it == ':') break;
} }
if (it == end) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format")); if (it == end) MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` too short"));
std::string_view id{begin, it}; std::string_view id{begin, it};
if (*it == ':') ++it; if (*it == ':') ++it;
it = handler.on_replacement_field(id, it); it = handler.on_replacement_field(id, it);
if (it == end || *it != '}') MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format")); if (it == end || *it != '}')
MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("`subentity-replacement-field` should end with '}'"));
return ++it; return ++it;
} }

View File

@@ -265,7 +265,7 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
return begin; return begin;
// on_replacement_field<dimension_t>(begin); // on_replacement_field<dimension_t>(begin);
} else } else
throw MP_UNITS_STD_FMT::format_error("invalid format"); throw MP_UNITS_STD_FMT::format_error("unknown replacement field '" + std::string(id) + "'");
} }
private: private:
@@ -275,7 +275,7 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
MP_UNITS_STD_FMT::formatter<T> sf; MP_UNITS_STD_FMT::formatter<T> sf;
ctx.advance_to(begin); ctx.advance_to(begin);
auto ptr = sf.parse(ctx); auto ptr = sf.parse(ctx);
if (*ptr != '}') throw MP_UNITS_STD_FMT::format_error("invalid format"); if (*ptr != '}') throw MP_UNITS_STD_FMT::format_error("unmatched '}' in format string");
format_str_lengths.push_back(mp_units::detail::to_unsigned(ptr - begin)); format_str_lengths.push_back(mp_units::detail::to_unsigned(ptr - begin));
return ptr; return ptr;
} }
@@ -314,7 +314,7 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
else if (id == "D") else if (id == "D")
on_dimension(format_str()); on_dimension(format_str());
else else
throw MP_UNITS_STD_FMT::format_error("invalid format"); throw MP_UNITS_STD_FMT::format_error("unknown replacement field '" + std::string(id) + "'");
return begin + *format_str_lengths_it++; return begin + *format_str_lengths_it++;
} }
}; };
@@ -325,7 +325,9 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
constexpr const Char* parse_quantity_specs(const Char* begin, const Char* end, Handler&& handler) const constexpr const Char* parse_quantity_specs(const Char* begin, const Char* end, Handler&& handler) const
{ {
if (begin == end || *begin == '}') return begin; if (begin == end || *begin == '}') return begin;
if (*begin != '%' && *begin != '{') throw MP_UNITS_STD_FMT::format_error("invalid format"); if (*begin != '%' && *begin != '{')
throw MP_UNITS_STD_FMT::format_error(
"`quantity-specs` should start with a `conversion-spec` ('%' or '{' characters expected)})");
auto ptr = begin; auto ptr = begin;
while (ptr != end) { while (ptr != end) {
auto c = *ptr; auto c = *ptr;
@@ -341,7 +343,7 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
} }
if (begin != ptr) handler.on_text(begin, ptr); if (begin != ptr) handler.on_text(begin, ptr);
++ptr; // consume '%' ++ptr; // consume '%'
if (ptr == end) throw MP_UNITS_STD_FMT::format_error("invalid format"); if (ptr == end) throw MP_UNITS_STD_FMT::format_error("invalid `placement-spec` format");
c = *ptr++; c = *ptr++;
switch (c) { switch (c) {
@@ -361,7 +363,7 @@ class MP_UNITS_STD_FMT::formatter<mp_units::quantity<Reference, Rep>, Char> {
handler.on_text(ptr - 1, ptr); handler.on_text(ptr - 1, ptr);
break; break;
default: default:
throw MP_UNITS_STD_FMT::format_error("invalid format"); throw MP_UNITS_STD_FMT::format_error(std::string("unknown `placement-spec` token '") + c + "'");
} }
begin = ptr; begin = ptr;
} }