add support for better error messages
This includes extended error messages which show the original format string. It works for 'char' type with wchar_t returning only the message. The thrown exception class now has a format() method to retrieve the pointer to the original format.
This commit is contained in:
parent
225d4f7032
commit
62466cc3d9
27
format.cc
27
format.cc
@ -409,12 +409,14 @@ void fmt::BasicFormatter<Char>::CheckSign(const Char *&s, const Arg &arg) {
|
||||
|
||||
template <typename Char>
|
||||
void fmt::BasicFormatter<Char>::DoFormat() {
|
||||
const Char *start = format_;
|
||||
const Char *start = format_; // capture the format string before it is reset
|
||||
const Char *original = format_;
|
||||
format_ = 0;
|
||||
next_arg_index_ = 0;
|
||||
const Char *s = start;
|
||||
typedef internal::Array<Char, BasicWriter<Char>::INLINE_BUFFER_SIZE> Buffer;
|
||||
BasicWriter<Char> &writer = *writer_;
|
||||
try {
|
||||
while (*s) {
|
||||
Char c = *s++;
|
||||
if (c != '{' && c != '}') continue;
|
||||
@ -644,6 +646,11 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (const FormatError &e) {
|
||||
// rethrow FormatError with the format string pointed to by start
|
||||
throw BasicFormatError<Char>(e.what(), original);
|
||||
}
|
||||
|
||||
writer.buffer_.append(start, s);
|
||||
}
|
||||
|
||||
@ -679,6 +686,17 @@ template void fmt::BasicFormatter<char>::CheckSign(
|
||||
|
||||
template void fmt::BasicFormatter<char>::DoFormat();
|
||||
|
||||
const char* FormatErrorMessage(const std::string &message, const char* format) {
|
||||
return fmt::c_str(fmt::Format("error: {} while parsing {}") << message << format);
|
||||
}
|
||||
|
||||
template<> fmt::BasicFormatError<char>::BasicFormatError(const std::string &message, const char *format)
|
||||
: std::runtime_error(FormatErrorMessage(message, format)), format_(format) {}
|
||||
|
||||
template<> fmt::BasicFormatError<char>::~BasicFormatError() {
|
||||
std::runtime_error::~runtime_error();
|
||||
}
|
||||
|
||||
// Explicit instantiations for wchar_t.
|
||||
|
||||
template void fmt::BasicWriter<wchar_t>::FormatDouble<double>(
|
||||
@ -711,3 +729,10 @@ template void fmt::BasicFormatter<wchar_t>::CheckSign(
|
||||
const wchar_t *&s, const Arg &arg);
|
||||
|
||||
template void fmt::BasicFormatter<wchar_t>::DoFormat();
|
||||
|
||||
template<> fmt::BasicFormatError<wchar_t>::BasicFormatError(const std::string &message, const wchar_t *format)
|
||||
: std::runtime_error(message), format_(format){}
|
||||
|
||||
template<> fmt::BasicFormatError<wchar_t>::~BasicFormatError() {
|
||||
std::runtime_error::~runtime_error();
|
||||
}
|
||||
|
||||
10
format.h
10
format.h
@ -292,6 +292,16 @@ class FormatError : public std::runtime_error {
|
||||
: std::runtime_error(message) {}
|
||||
};
|
||||
|
||||
template <typename Char>
|
||||
class BasicFormatError : public std::runtime_error {
|
||||
private:
|
||||
std::basic_string<Char> format_;
|
||||
public:
|
||||
explicit BasicFormatError(const std::string &message, const Char *format);
|
||||
virtual ~BasicFormatError() throw();
|
||||
const Char *format() const { return format_.c_str(); }
|
||||
};
|
||||
|
||||
enum Alignment {
|
||||
ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user