From 55210a7e30af724e9ae1a69008d9f14deb506571 Mon Sep 17 00:00:00 2001 From: blankie Date: Thu, 30 Mar 2023 21:30:03 +0700 Subject: [PATCH] Reflow logcat_entry.cpp --- logcat_entry.cpp | 171 ++++++++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 76 deletions(-) diff --git a/logcat_entry.cpp b/logcat_entry.cpp index 6c5a6ae..86de810 100644 --- a/logcat_entry.cpp +++ b/logcat_entry.cpp @@ -7,9 +7,24 @@ #include "logcat_entry.h" #include "pcre2_wrapper.h" -static const Pcre2Regex LogcatEntryRegex("^\\s*(\\d+)(?:\\.\\d+)?(?:\\s+([\\w\\d._-]+))?\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s+(.+?)\\s*:\\s(.*)$"); +static const Pcre2Regex LogcatEntryRegex( + "^ *(\\d+)(?:\\.\\d+)?" // time + "(?: +([\\w\\d._-]+))?" // optional user + " +(\\d+)" // pid + " +(\\d+)" // tid + " +([A-Z])" // priority + " +(.+?) *: (.*)$" // tag and message +); static const Pcre2Regex BufferRegex("^--------- (?:beginning of|switch to) (\\w+)$"); +static std::string leftpad(const std::string& str, size_t characters); +static inline char to_char(Priority priority); +static inline std::string rightpad(const std::string& str, size_t characters); + +static inline Priority priority_from(char c); +static inline long to_long(const char* str, const char* expected_end); +static unsigned long long to_ull(const char* str, const char* expected_end); + const char* to_string(Priority priority) { switch (priority) { case Priority::Verbose: return "Verbose"; @@ -44,30 +59,6 @@ const char* to_string_lower(Buffer buffer) { } } -static std::string leftpad(const std::string& str, size_t characters) { - return str.size() >= characters - ? str - : std::string(characters - str.size(), ' ') + str; -} - -static inline char to_char(Priority priority) { - switch (priority) { - case Priority::Verbose: return 'V'; - case Priority::Debug: return 'D'; - case Priority::Info: return 'I'; - case Priority::Warn: return 'W'; - case Priority::Error: return 'E'; - case Priority::Fatal: return 'F'; - case Priority::Unknown: return 'U'; - } -} - -static inline std::string rightpad(const std::string& str, size_t characters) { - return str.size() >= characters - ? str - : str + std::string(characters - str.size(), ' '); -} - std::string to_string(const LogcatEntry& logcat_entry) { char logcat_style_time_as_str[32] = {0}; strftime(logcat_style_time_as_str, 31 * sizeof(char), "%Y-%m-%d %H:%M:%S", &logcat_entry.time); @@ -81,45 +72,6 @@ std::string to_string(const LogcatEntry& logcat_entry) { + ": " + logcat_entry.message; } -static inline Priority priority_from(char c) { - switch (c) { - case 'V': return Priority::Verbose; - case 'D': return Priority::Debug; - case 'I': return Priority::Info; - case 'W': return Priority::Warn; - case 'E': return Priority::Error; - case 'F': return Priority::Fatal; - default: return Priority::Unknown; - } -} - -static inline long to_long(const char* str, const char* expected_end) { - char* endptr; - - errno = 0; - long res = strtol(str, &endptr, 10); - if (endptr != expected_end) { - throw std::invalid_argument(std::string(str) + " has trailing text"); - } else if (res == LONG_MAX && errno == ERANGE) { - throw std::overflow_error(std::string(str) + " is too big"); - } else if (res == LONG_MIN && errno == ERANGE) { - throw std::underflow_error(std::string(str) + " is too small"); - } - return res; -} - -static unsigned long long to_unsigned_long_long(const char* str, const char* expected_end) { - char* endptr; - - errno = 0; - unsigned long long res = strtoull(str, &endptr, 10); - if (endptr != expected_end) { - throw std::invalid_argument(std::string(str) + " has trailing text"); - } else if (res == ULLONG_MAX && errno == ERANGE) { - throw std::overflow_error(std::string(str) + " is too big"); - } - return res; -} std::optional try_parse_logcat_entry(char* buf, size_t length, Buffer buffer) { regmatch_t matches[8]; @@ -133,24 +85,25 @@ std::optional try_parse_logcat_entry(char* buf, size_t length, Buff return std::nullopt; } - std::optional user; - if (matches[2].rm_so > -1 && matches[2].rm_eo > -1) { - user = std::string(&buf[matches[2].rm_so], static_cast(matches[2].rm_eo - matches[2].rm_so)); - } + auto group_exists = [](const regmatch_t& match) { return match.rm_so > -1 && match.rm_eo > -1; }; + auto group_long = [&](const regmatch_t& match) { return to_long(&buf[match.rm_so], &buf[match.rm_eo]); }; + auto group_ull = [&](const regmatch_t& match) { return to_ull(&buf[match.rm_so], &buf[match.rm_eo]); }; + auto group_string = [&](const regmatch_t& match) { return std::string(&buf[match.rm_so], static_cast(match.rm_eo - match.rm_so)); }; + auto group_priority = [&](const regmatch_t& match) { return priority_from(buf[match.rm_so]); }; // if pcre2 gives us negative offsets then i'll die LogcatEntry logcat_entry = { - .buffer = buffer, + .buffer = buffer, // time to be set at the end - .user = std::move(user), - .pid = to_unsigned_long_long(&buf[matches[3].rm_so], &buf[matches[3].rm_eo]), - .tid = to_unsigned_long_long(&buf[matches[4].rm_so], &buf[matches[4].rm_eo]), - .priority = priority_from(buf[matches[5].rm_so]), - .tag = std::string(&buf[matches[6].rm_so], static_cast(matches[6].rm_eo - matches[6].rm_so)), - .message = std::string(&buf[matches[7].rm_so], static_cast(matches[7].rm_eo - matches[7].rm_so)), + .user = group_exists(matches[2]) ? std::optional(group_string(matches[2])) : std::nullopt, + .pid = group_ull(matches[3]), + .tid = group_ull(matches[4]), + .priority = group_priority(matches[5]), + .tag = group_string(matches[6]), + .message = group_string(matches[7]), }; - time_t time = to_long(&buf[matches[1].rm_so], &buf[matches[1].rm_eo]); + time_t time = group_long(matches[1]); localtime_r(&time, &logcat_entry.time); return std::move(logcat_entry); } @@ -241,3 +194,69 @@ void to_json(nlohmann::json& j, const Priority& priority) { case Priority::Fatal: j = "FATAL"; break; } } + + +static std::string leftpad(const std::string& str, size_t characters) { + return str.size() >= characters + ? str + : std::string(characters - str.size(), ' ') + str; +} + +static inline char to_char(Priority priority) { + switch (priority) { + case Priority::Verbose: return 'V'; + case Priority::Debug: return 'D'; + case Priority::Info: return 'I'; + case Priority::Warn: return 'W'; + case Priority::Error: return 'E'; + case Priority::Fatal: return 'F'; + case Priority::Unknown: return 'U'; + } +} + +static inline std::string rightpad(const std::string& str, size_t characters) { + return str.size() >= characters + ? str + : str + std::string(characters - str.size(), ' '); +} + + +static inline Priority priority_from(char c) { + switch (c) { + case 'V': return Priority::Verbose; + case 'D': return Priority::Debug; + case 'I': return Priority::Info; + case 'W': return Priority::Warn; + case 'E': return Priority::Error; + case 'F': return Priority::Fatal; + default: return Priority::Unknown; + } +} + +static inline long to_long(const char* str, const char* expected_end) { + char* endptr; + + errno = 0; + long res = strtol(str, &endptr, 10); + if (endptr != expected_end) { + throw std::invalid_argument(std::string(str) + " has trailing text"); + } else if (res == LONG_MAX && errno == ERANGE) { + throw std::overflow_error(std::string(str) + " is too big"); + } else if (res == LONG_MIN && errno == ERANGE) { + throw std::underflow_error(std::string(str) + " is too small"); + } + return res; +} + +static unsigned long long to_ull(const char* str, const char* expected_end) { + char* endptr; + + errno = 0; + unsigned long long res = strtoull(str, &endptr, 10); + if (endptr != expected_end) { + throw std::invalid_argument(std::string(str) + " has trailing text"); + } else if (res == ULLONG_MAX && errno == ERANGE) { + throw std::overflow_error(std::string(str) + " is too big"); + } + return res; +}