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>
|
template <typename Char>
|
||||||
void fmt::BasicFormatter<Char>::DoFormat() {
|
void fmt::BasicFormatter<Char>::DoFormat() {
|
||||||
const Char *start = format_;
|
const Char *start = format_;
|
||||||
|
const Char *original = format_; // capture the format string before it is reset
|
||||||
format_ = 0;
|
format_ = 0;
|
||||||
next_arg_index_ = 0;
|
next_arg_index_ = 0;
|
||||||
const Char *s = start;
|
const Char *s = start;
|
||||||
BasicWriter<Char> &writer = *writer_;
|
BasicWriter<Char> &writer = *writer_;
|
||||||
|
try {
|
||||||
while (*s) {
|
while (*s) {
|
||||||
Char c = *s++;
|
Char c = *s++;
|
||||||
if (c != '{' && c != '}') continue;
|
if (c != '{' && c != '}') continue;
|
||||||
@ -652,6 +654,10 @@ void fmt::BasicFormatter<Char>::DoFormat() {
|
|||||||
break;
|
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);
|
writer.buffer_.append(start, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,6 +693,18 @@ template void fmt::BasicFormatter<char>::CheckSign(
|
|||||||
|
|
||||||
template void fmt::BasicFormatter<char>::DoFormat();
|
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.
|
// Explicit instantiations for wchar_t.
|
||||||
|
|
||||||
template void fmt::BasicWriter<wchar_t>::FormatDouble<double>(
|
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);
|
const wchar_t *&s, const Arg &arg);
|
||||||
|
|
||||||
template void fmt::BasicFormatter<wchar_t>::DoFormat();
|
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::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 {
|
enum Alignment {
|
||||||
ALIGN_DEFAULT, ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTER, ALIGN_NUMERIC
|
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);
|
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.
|
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) { \
|
inline IntFormatter<TYPE, TypeSpec<'b'> > bin(TYPE value) { \
|
||||||
return IntFormatter<TYPE, TypeSpec<'b'> >(value, TypeSpec<'b'>()); \
|
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) { \
|
inline IntFormatter<TYPE, TypeSpec<'o'> > oct(TYPE value) { \
|
||||||
return IntFormatter<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
|
return IntFormatter<TYPE, TypeSpec<'o'> >(value, TypeSpec<'o'>()); \
|
||||||
} \
|
} \
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user