add support for better error message back
This commit is contained in:
parent
f2e75f74cc
commit
0616edd08e
36
format.cc
36
format.cc
@ -411,10 +411,12 @@ 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 *original = format_; // capture the format string before it is reset
|
||||
format_ = 0;
|
||||
next_arg_index_ = 0;
|
||||
const Char *s = start;
|
||||
BasicWriter<Char> &writer = *writer_;
|
||||
try {
|
||||
while (*s) {
|
||||
Char c = *s++;
|
||||
if (c != '{' && c != '}') continue;
|
||||
@ -652,6 +654,10 @@ 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);
|
||||
}
|
||||
|
||||
@ -687,6 +693,18 @@ template void fmt::BasicFormatter<char>::CheckSign(
|
||||
|
||||
template void fmt::BasicFormatter<char>::DoFormat();
|
||||
|
||||
#ifdef FMT_FORMAT_STRING_IN_ERRORS
|
||||
std::string fmt::FormatErrorMessage(const std::string &message, const char *format) {
|
||||
fmt::Writer w;
|
||||
w << "error: " << message << " while parsing format string " << format;
|
||||
return w.str();
|
||||
}
|
||||
#else
|
||||
std::string fmt::FormatErrorMessage(const std::string &message, const char *format) {
|
||||
return message;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Explicit instantiations for wchar_t.
|
||||
|
||||
template void fmt::BasicWriter<wchar_t>::FormatDouble<double>(
|
||||
@ -719,3 +737,21 @@ template void fmt::BasicFormatter<wchar_t>::CheckSign(
|
||||
const wchar_t *&s, const Arg &arg);
|
||||
|
||||
template void fmt::BasicFormatter<wchar_t>::DoFormat();
|
||||
|
||||
#ifdef FMT_FORMAT_STRING_IN_ERRORS
|
||||
std::string fmt::FormatErrorMessage(const std::string &message, const wchar_t *format) {
|
||||
|
||||
int size = FMT_SNPRINTF(NULL, 0, "%ls", format);
|
||||
char* buf = (char*)malloc(size+1);
|
||||
FMT_SNPRINTF(buf, size+1, "%ls", format);
|
||||
|
||||
fmt::Writer w;
|
||||
w << "error: " << message << " while parsing format string " << buf;
|
||||
free(buf);
|
||||
return w.str();
|
||||
}
|
||||
#else
|
||||
std::string fmt::FormatErrorMessage(const std::string &message, const wchar_t *format) {
|
||||
return message;
|
||||
}
|
||||
#endif
|
||||
|
||||
23
format.h
23
format.h
@ -315,6 +315,20 @@ class FormatError : public std::runtime_error {
|
||||
: std::runtime_error(message) {}
|
||||
};
|
||||
|
||||
std::string FormatErrorMessage(const std::string &message, const char *format);
|
||||
std::string FormatErrorMessage(const std::string &message, const wchar_t *format);
|
||||
|
||||
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)
|
||||
: std::runtime_error(fmt::FormatErrorMessage(message, format)), format_(format){}
|
||||
virtual ~BasicFormatError() throw() {}
|
||||
const Char *format() const { return format_.c_str(); }
|
||||
};
|
||||
|
||||
enum Alignment {
|
||||
ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
|
||||
};
|
||||
@ -402,6 +416,11 @@ class IntFormatter : public SpecT {
|
||||
*/
|
||||
IntFormatter<int, TypeSpec<'b'> > bin(int value);
|
||||
|
||||
/**
|
||||
Returns an integer formatter that formats the value in base 2.
|
||||
*/
|
||||
IntFormatter<int, TypeSpec<'B'> > binu(int value);
|
||||
|
||||
/**
|
||||
Returns an integer formatter that formats the value in base 8.
|
||||
*/
|
||||
@ -439,7 +458,9 @@ IntFormatter<int, AlignTypeSpec<TYPE_CODE> > pad(
|
||||
inline IntFormatter<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
|
||||
return IntFormatter<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
|
||||
} \
|
||||
\
|
||||
inline IntFormatter<TYPE, TypeSpec<'B'> > binu(TYPE value) { \
|
||||
return IntFormatter<TYPE, TypeSpec<'B'> >(value, TypeSpec<'B'>()); \
|
||||
} \
|
||||
inline IntFormatter<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
|
||||
return IntFormatter<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
|
||||
} \
|
||||
|
||||
Loading…
Reference in New Issue
Block a user