|
|
@@ -153,8 +153,7 @@ namespace logging {
|
|
|
|
|
|
format::generator date_token(char const * next);
|
|
|
|
|
|
- format::generator handle( char const * & next ) {
|
|
|
- auto is = [&next](char c) { return *next == c; };
|
|
|
+ format::generator format_factory::create_impl() {
|
|
|
if (is('c')) {
|
|
|
return std::make_shared<log_handle_gen>();
|
|
|
} else if (is('p')) {
|
|
|
@@ -164,8 +163,8 @@ namespace logging {
|
|
|
} else if (is('t')) {
|
|
|
return std::make_shared<thread_name_gen>();
|
|
|
} else {
|
|
|
- std::string error_msg{"unknown format character: '"};
|
|
|
- throw unknown_format_specifier{error_msg + *next + "'"};
|
|
|
+ throw unknown_format_specifier{std::string("unknown format character: '")
|
|
|
+ + *next_ + "'"};
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -176,71 +175,67 @@ namespace logging {
|
|
|
return rval;
|
|
|
}
|
|
|
|
|
|
- std::pair<int, size_t> get_bounds(char const * & next) {
|
|
|
- int min = *next == '.' ? 0 : eat(next);
|
|
|
- size_t max = *next == '.' ? eat(++next) : std::string::npos;
|
|
|
- return std::make_pair(min, max);
|
|
|
- }
|
|
|
-
|
|
|
- format::generator parse_with_bounds(char const * & next) {
|
|
|
- bool const is_left = *next == '-';
|
|
|
- if (is_left) ++next;
|
|
|
+ void format_factory::create_size_bounded() {
|
|
|
+ bool const is_left = is('-');
|
|
|
+ if (is_left) ++next_;
|
|
|
|
|
|
- auto bounds = get_bounds(next);
|
|
|
+ int const min = is('.') ? 0 : eat(next_);
|
|
|
+ size_t const max = is('.') ? eat(++next_) : std::string::npos;
|
|
|
|
|
|
- bounds_gen gen{handle(next), is_left, bounds.first, bounds.second};
|
|
|
- return std::make_shared<bounds_gen>(gen);
|
|
|
+ append<bounds_gen>(create_impl(), is_left, min, max);
|
|
|
}
|
|
|
|
|
|
- format format::parse_format_string( std::string const & fmt ) {
|
|
|
- format out;
|
|
|
- char const * curr = fmt.c_str();
|
|
|
- char const * next = nullptr;
|
|
|
- char const * const end = curr + fmt.size();
|
|
|
- auto is = [&next](char c) { return *next == c; };
|
|
|
-
|
|
|
- while ((next = std::strchr(curr, '%')) != nullptr) {
|
|
|
- ++next;
|
|
|
- if (end == next) {
|
|
|
- std::string error_msg{"expected format specifier, got end of string"};
|
|
|
- throw format_parsing_exception{error_msg}; // TODO
|
|
|
+ format format_factory::create() {
|
|
|
+ while ((next_ = std::strchr(curr_, '%')) != nullptr) {
|
|
|
+ ++next_;
|
|
|
+ if (end_ == next_) {
|
|
|
+ throw format_parsing_exception{
|
|
|
+ "expected format specifier, got end of string"};
|
|
|
}
|
|
|
|
|
|
- if (curr < next-1) {
|
|
|
- std::string lit{curr, next - 1};
|
|
|
- out.gen.push_back(std::make_shared<literal_gen>(lit));
|
|
|
+ if (curr_ < next_ - 1) {
|
|
|
+ append<literal_gen>(std::string(curr_, next_ - 1));
|
|
|
}
|
|
|
|
|
|
if (is('d')) {
|
|
|
- ++next;
|
|
|
- out.gen.push_back(date_token(next));
|
|
|
- if (is('{')) next = std::strchr(next, '}');
|
|
|
+ ++next_;
|
|
|
+ create_date();
|
|
|
+ if (is('{')) next_ = std::strchr(next_, '}');
|
|
|
} else if (is('n')) {
|
|
|
- out.gen.push_back(std::make_shared<literal_gen>(NEWLINE_TOKEN));
|
|
|
+ append<literal_gen>(NEWLINE_TOKEN);
|
|
|
} else if (is('%')) {
|
|
|
- out.gen.push_back(std::make_shared<literal_gen>("%"));
|
|
|
- } else if (is('.') || is('-') || isdigit( *next )) {
|
|
|
- out.gen.push_back(parse_with_bounds(next));
|
|
|
+ append<literal_gen>("%");
|
|
|
+ } else if (is('.') || is('-') || isdigit(*next_)) {
|
|
|
+ create_size_bounded();
|
|
|
} else if (is('C')) {
|
|
|
- out.gen.push_back(std::make_shared<class_info_gen>(++next));
|
|
|
- if (is('{')) next = std::strchr(next, '}');
|
|
|
+ append<class_info_gen>(++next_);
|
|
|
+ if (is('{')) next_ = std::strchr(next_, '}');
|
|
|
} else if (is('F') || is('M') || is('L') || is('l')) {
|
|
|
- out.gen.push_back(std::make_shared<location_info_gen>(*next));
|
|
|
+ append<location_info_gen>(*next_);
|
|
|
} else if (is('r')) {
|
|
|
- out.gen.push_back(std::make_shared<time_elapsed_gen>());
|
|
|
+ append<time_elapsed_gen>();
|
|
|
} else {
|
|
|
- out.gen.push_back(handle(next));
|
|
|
+ generators_.push_back(create_impl());
|
|
|
}
|
|
|
- curr = ++next;
|
|
|
+ curr_ = ++next_;
|
|
|
}
|
|
|
- if (curr < end) {
|
|
|
- std::string lit{curr, end};
|
|
|
- out.gen.push_back(std::make_shared<literal_gen>(lit));
|
|
|
+ if (curr_ < end_) {
|
|
|
+ append<literal_gen>(std::string(curr_, end_));
|
|
|
}
|
|
|
+
|
|
|
+ format out;
|
|
|
+ out.gen = generators_;
|
|
|
return out;
|
|
|
}
|
|
|
-#undef is
|
|
|
|
|
|
+ format_factory::format_factory(std::string const & fmt)
|
|
|
+ : data_string_(fmt), curr_(data_string_.c_str()),
|
|
|
+ end_(curr_ + data_string_.size()){}
|
|
|
+
|
|
|
+ format format::parse_format_string(std::string const & fmt) {
|
|
|
+ return format_factory(fmt).create();
|
|
|
+ }
|
|
|
+
|
|
|
void format::process(logpacket const & pkt, std::ostream & os) const {
|
|
|
for (auto func : gen) { func->write(pkt, os); }
|
|
|
}
|