|
|
@@ -55,6 +55,40 @@ namespace logging { namespace {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ struct class_info_gen : public format::generator_t {
|
|
|
+ size_t components;
|
|
|
+ class_info_gen(char const * token) : components(0) {
|
|
|
+ if (token && *token == '{') {
|
|
|
+ components = atol(token + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ std::string str(logpacket const & lp) const override {
|
|
|
+ std::string pf = lp.info.pretty_function;
|
|
|
+ std::string func = std::string(lp.info.function) + "(";
|
|
|
+ if (pf[pf.find(func)-1] == ' ') {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ pf.erase(pf.find(func));
|
|
|
+ if (pf.rfind("::", pf.size()) != std::string::npos) {
|
|
|
+ pf.erase(pf.size() - 2);
|
|
|
+ }
|
|
|
+ // Erase virtual prefix
|
|
|
+ erase_prefix(pf, "virtual ");
|
|
|
+ erase_prefix(pf, "static ");
|
|
|
+ trim_upto_prefix_alpha(pf, "> ");
|
|
|
+ trim_upto_prefix_alpha(pf, "&");
|
|
|
+ pf.erase(0, pf.find(" ") + 1);
|
|
|
+ for (size_t i = pf.rfind("::"), c = 1;
|
|
|
+ i != std::string::npos && c <= components;
|
|
|
+ i = pf.rfind("::", i-1), ++c) {
|
|
|
+ if (c == components) {
|
|
|
+ pf.erase(0, i + 2);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return pf;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
struct location_info_gen : public format::generator_t {
|
|
|
enum { method, line, file, classname, location } where;
|
|
|
constexpr static const decltype(where) format_codes[] = {
|
|
|
@@ -74,23 +108,8 @@ namespace logging { namespace {
|
|
|
return std::to_string(lp.info.line);
|
|
|
case method:
|
|
|
return lp.info.function;
|
|
|
- case classname: {
|
|
|
- std::string pf = lp.info.pretty_function;
|
|
|
- std::string func = std::string(lp.info.function) + "(";
|
|
|
- if (pf[pf.find(func)-1] == ' ') {
|
|
|
- return "";
|
|
|
- }
|
|
|
- pf.erase(pf.find(func));
|
|
|
- if (pf.rfind("::", pf.size()) != std::string::npos) {
|
|
|
- pf.erase(pf.size() - 2);
|
|
|
- }
|
|
|
- // Erase virtual prefix
|
|
|
- erase_prefix(pf, "virtual ");
|
|
|
- trim_upto_prefix_alpha(pf, "> ");
|
|
|
- trim_upto_prefix_alpha(pf, "&");
|
|
|
- pf.erase(0, pf.find(" ") + 1);
|
|
|
- return pf;
|
|
|
- }
|
|
|
+ case classname:
|
|
|
+ return class_info_gen(0).str(lp);
|
|
|
case location:
|
|
|
return str(lp, classname) + "::" + str(lp, method) + " (" +
|
|
|
str(lp, file) + ", " + str(lp, line) + ")";
|
|
|
@@ -154,10 +173,6 @@ namespace logging {
|
|
|
return std::make_shared<message_gen>();
|
|
|
} else if (is('t')) {
|
|
|
return std::make_shared<literal_gen>("???");
|
|
|
-// } else if (is('r')) {
|
|
|
-// // TODO: milliseconds from layout creation
|
|
|
- } else if (is('F') || is('M') || is('L') || is('C') || is('l')) {
|
|
|
- return std::make_shared<location_info_gen>(*next);
|
|
|
} else {
|
|
|
std::string error_msg{"unknown format character: '"};
|
|
|
throw unknown_format_specifier{error_msg + *next + "'"};
|
|
|
@@ -215,6 +230,11 @@ namespace logging {
|
|
|
out.gen.push_back(std::make_shared<literal_gen>("%"));
|
|
|
} else if (is('.') || is('-') || isdigit( *next )) {
|
|
|
out.gen.push_back(parse_with_bounds(next));
|
|
|
+ } else if (is('C')) {
|
|
|
+ out.gen.push_back(std::make_shared<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));
|
|
|
} else {
|
|
|
out.gen.push_back(handle(next));
|
|
|
}
|