|
|
@@ -36,26 +36,70 @@ namespace logging { namespace {
|
|
|
return to_string(lp.level, true);
|
|
|
}
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
+ void erase_prefix(std::string & str, char const * prefix) {
|
|
|
+ size_t size = strlen(prefix);
|
|
|
+ if (str.find(prefix, 0, size) == 0) {
|
|
|
+ str.erase(0, size);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void trim_upto_prefix_alpha(std::string & str, char const * prefix) {
|
|
|
+ size_t size = strlen(prefix);
|
|
|
+ for (size_t i = str.find(prefix); i != std::string::npos;
|
|
|
+ i = str.find(prefix, i + 1)) {
|
|
|
+ if (isalpha(str[i + size])) {
|
|
|
+ str.erase(0, i + size);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
struct location_info_gen : public format::generator_t {
|
|
|
- enum { method, line, file } where;
|
|
|
+ enum { method, line, file, classname, location } where;
|
|
|
constexpr static const decltype(where) format_codes[] = {
|
|
|
['F'] = file,
|
|
|
['M'] = method,
|
|
|
['L'] = line,
|
|
|
+ ['C'] = classname,
|
|
|
+ ['l'] = location
|
|
|
};
|
|
|
|
|
|
location_info_gen(char wh) : where(format_codes[wh]) {}
|
|
|
- std::string str(logpacket const & lp) const override {
|
|
|
- switch (where) {
|
|
|
+ static std::string str(logpacket const & lp, decltype(where) wh) {
|
|
|
+ switch (wh) {
|
|
|
case file:
|
|
|
return lp.info.filename;
|
|
|
case line:
|
|
|
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 location:
|
|
|
+ return str(lp, classname) + "::" + str(lp, method) + " (" +
|
|
|
+ str(lp, file) + ", " + str(lp, line) + ")";
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ std::string str(logpacket const & lp) const override {
|
|
|
+ return str(lp, where);
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
struct message_gen : public format::generator_t {
|
|
|
@@ -110,7 +154,9 @@ namespace logging {
|
|
|
return std::make_shared<message_gen>();
|
|
|
} else if (is('t')) {
|
|
|
return std::make_shared<literal_gen>("???");
|
|
|
- } else if (is('F') || is('M') || is('L')) {
|
|
|
+// } 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: '"};
|