diff --git a/src/core/include/mp-units/bits/fmt.h b/src/core/include/mp-units/bits/fmt.h index e570a0ef..5957cbd3 100644 --- a/src/core/include/mp-units/bits/fmt.h +++ b/src/core/include/mp-units/bits/fmt.h @@ -256,19 +256,24 @@ template [[nodiscard]] constexpr const Char* parse_subentity_replacement_field(const Char* begin, const Char* end, Handler&& handler) { - if (end - begin++ < 4) return MP_UNITS_THROW(MP_UNITS_STD_FMT::format_error("invalid format string")), 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("invalid format")); + if (end - begin++ < 4) + 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("`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; 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 == 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}; if (*it == ':') ++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; } diff --git a/src/core/include/mp-units/format.h b/src/core/include/mp-units/format.h index 0695a037..8256a4d1 100644 --- a/src/core/include/mp-units/format.h +++ b/src/core/include/mp-units/format.h @@ -265,7 +265,7 @@ class MP_UNITS_STD_FMT::formatter, Char> { return begin; // on_replacement_field(begin); } else - throw MP_UNITS_STD_FMT::format_error("invalid format"); + throw MP_UNITS_STD_FMT::format_error("unknown replacement field '" + std::string(id) + "'"); } private: @@ -275,7 +275,7 @@ class MP_UNITS_STD_FMT::formatter, Char> { MP_UNITS_STD_FMT::formatter sf; ctx.advance_to(begin); 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)); return ptr; } @@ -314,7 +314,7 @@ class MP_UNITS_STD_FMT::formatter, Char> { else if (id == "D") on_dimension(format_str()); 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++; } }; @@ -325,7 +325,9 @@ class MP_UNITS_STD_FMT::formatter, Char> { constexpr const Char* parse_quantity_specs(const Char* begin, const Char* end, Handler&& handler) const { 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; while (ptr != end) { auto c = *ptr; @@ -341,7 +343,7 @@ class MP_UNITS_STD_FMT::formatter, Char> { } if (begin != ptr) handler.on_text(begin, ptr); ++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++; switch (c) { @@ -361,7 +363,7 @@ class MP_UNITS_STD_FMT::formatter, Char> { handler.on_text(ptr - 1, ptr); break; 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; }