From 1fee2bc08b9215ce728f16be2ee8a3068ae45618 Mon Sep 17 00:00:00 2001 From: aristocratos Date: Sun, 21 May 2023 13:52:19 +0200 Subject: Add DebugTimer class and change some Logger::error calls to Logger::debug --- src/btop_tools.hpp | 60 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 6 deletions(-) (limited to 'src/btop_tools.hpp') diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp index 4ae27f8..7e499f6 100644 --- a/src/btop_tools.hpp +++ b/src/btop_tools.hpp @@ -152,6 +152,12 @@ namespace Term { namespace Tools { constexpr auto SSmax = std::numeric_limits::max(); + class MyNumPunct : public std::numpunct { + protected: + virtual char do_thousands_sep() const { return '\''; } + virtual std::string do_grouping() const { return "\03"; } + }; + size_t wide_ulen(const string& str); size_t wide_ulen(const std::wstring& w_str); @@ -335,7 +341,6 @@ namespace Tools { //* Convert a celsius value to celsius, fahrenheit, kelvin or rankin and return tuple with new value and unit. auto celsius_to(const long long& celsius, const string& scale) -> tuple; - } //* Simple logging implementation @@ -349,13 +354,56 @@ namespace Logger { }; extern std::filesystem::path logfile; + enum Level : size_t { + DISABLED = 0, + ERROR = 1, + WARNING = 2, + INFO = 3, + DEBUG = 4, + }; + //* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG" void set(const string& level); - void log_write(const size_t level, const string& msg); - inline void error(const string msg) { log_write(1, msg); } - inline void warning(const string msg) { log_write(2, msg); } - inline void info(const string msg) { log_write(3, msg); } - inline void debug(const string msg) { log_write(4, msg); } + void log_write(const Level level, const string& msg); + inline void error(const string msg) { log_write(ERROR, msg); } + inline void warning(const string msg) { log_write(WARNING, msg); } + inline void info(const string msg) { log_write(INFO, msg); } + inline void debug(const string msg) { log_write(DEBUG, msg); } } +namespace Tools { + //* Creates a named timer that is started on construct (by default) and reports elapsed time in microseconds to Logger::debug() on destruct if running + //* Unless delayed_report is set to false, all reporting is buffered and delayed until DebugTimer is destructed or .force_report() is called + //* Usage example: Tools::DebugTimer timer(name:"myTimer", [start:true], [delayed_report:true]) // Create timer and start + //* timer.stop(); // Stop timer and report elapsed time + //* timer.stop_rename_reset("myTimer2"); // Stop timer, report elapsed time, rename timer, reset and restart + class DebugTimer { + uint64_t start_time{}; + uint64_t elapsed_time{}; + bool running{}; + std::locale custom_locale = std::locale(std::locale::classic(), new Tools::MyNumPunct); + vector report_buffer{}; + public: + string name{}; + bool delayed_report{}; + Logger::Level log_level = Logger::DEBUG; + DebugTimer() = default; + DebugTimer(const string name, bool start = true, bool delayed_report = true); + ~DebugTimer(); + + void start(); + void stop(bool report = true); + void reset(bool restart = true); + //* Stops and reports (default), renames timer then resets and restarts (default) + void stop_rename_reset(const string& new_name, bool report = true, bool restart = true); + void report(); + void force_report(); + uint64_t elapsed(); + bool is_running(); + }; + +} + + + -- cgit v1.2.3 From bd5d697830f65adb0ce6c4bd7e292e34c10079db Mon Sep 17 00:00:00 2001 From: aristocratos Date: Sat, 26 Aug 2023 20:29:43 +0200 Subject: Squashed commit of the following: commit c296ac13cd4c16a11e137c309b7452bab096312e Merge: 9a1e760 091c30a Author: Jakob P. Liljenberg Date: Sat Aug 26 19:29:57 2023 +0200 Merge pull request #590 from nobounce/dangling-reference-config Convert parameters and config keys to std::string_view commit 9a1e760a661c9a160dd83e6d3ab710bf36b19b04 Merge: 9c8af4d 22e64ca Author: Jakob P. Liljenberg Date: Sat Aug 26 19:20:18 2023 +0200 Merge pull request #602 from jfouquart/main Fix getting zfs pool name with '.' char in freebsd commit 9c8af4df436c2847eefa66d2e0eb7ebfd75d70cf Merge: 8a49d8c 2217cbe Author: Jakob P. Liljenberg Date: Sat Aug 26 19:18:55 2023 +0200 Merge pull request #601 from joske/cleanup [macos] don't check /sys on macos commit 8a49d8cf456d0a15db65e7dc704d627b75a0fe43 Merge: 1556388 008fcd8 Author: Jakob P. Liljenberg Date: Sat Aug 26 19:18:07 2023 +0200 Merge pull request #600 from joske/makefile [macos/freebsd] support gcc13 commit 1556388c83644d122fab9241aa876232d94d1928 Merge: 1b126f5 d17e1a2 Author: Jakob P. Liljenberg Date: Sat Aug 26 19:14:00 2023 +0200 Merge pull request #599 from joske/main [macos] fix temp sensor on system with many cores commit d17e1a2dac79458940319d7117a21bdcd73ed53c Author: Jos Dehaes Date: Fri Aug 25 16:18:39 2023 +0200 fix some warnings commit 4d8aa6b11896dac99f81019e6dea11cc8d8856f1 Author: Jos Dehaes Date: Fri Aug 25 15:52:58 2023 +0200 fix core check commit 22e64caaff3d5877b7a494980a8ee3f17ea8f824 Author: Jonathan Fouquart Date: Fri Aug 25 09:37:49 2023 +0200 Fix getting zfs pool name with '.' char in freebsd commit 2217cbe143dd5aa45dbd50b4dc829577e2e1ccda Author: Jos Dehaes Date: Wed Aug 23 16:01:04 2023 +0200 [macos] don't check /sys on macos commit 008fcd889e862f1d378d331dab51b3d3ce9d9f3c Author: Jos Dehaes Date: Wed Aug 23 16:05:00 2023 +0200 also add g++13 commit 0fdca5eb0385253969e029fdfcf1fb9cff83ea33 Author: Jos Dehaes Date: Wed Aug 23 15:54:07 2023 +0200 support gcc13 commit dcbdb7360d44b4071ec0fe0757a0875a12147c8a Author: Jos Dehaes Date: Wed Aug 23 15:46:47 2023 +0200 [macos] fix temp sensor on system with many cores commit 1b126f55e38de76a2cca796593ef1554828d61e6 Author: aristocratos Date: Fri Aug 4 01:08:27 2023 +0200 Update Makefile for partial static compilation on freebsd commit c8ec6bbb000a865f14c50414e456955c473a2f3a Author: aristocratos Date: Thu Aug 3 23:08:33 2023 +0200 Fix freebsd nullptr changes and makefile for gcc12 and newer commit 8a33aab5885f828d7d0d2523aff31f9c33170332 Merge: 94e5c02 e4abcef Author: Jakob P. Liljenberg Date: Sun Jul 30 13:21:48 2023 +0200 Merge pull request #539 from nobounce/replace-NULL-nullptr Modernize using nullptr. commit 94e5c02d113f3fc8956d63ef4f0eecebfbf31b9d Author: aristocratos Date: Thu Jul 27 20:51:21 2023 +0200 Better text editing commit 091c30ab2be074836bb8d9a4f658cec9a5b36303 Author: nobounce Date: Thu Jul 27 14:17:54 2023 +0200 Convert parameters and config keys to std::string_view Using std::string_view instead of std::string& silences a new warning from GCC 13, -Wdangling-reference Also switch return type of `getI` from int& to int, trivial types are cheaper to copy by value commit e4abcefbf92e5d94ad169e1e47c0fbec7279fa6f Author: nobounce Date: Wed Jul 26 16:19:17 2023 +0200 Use nullptr instead of NULL. See https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf TLDR: NULL is of type int and relies on proper implicit pointer conversion which may lead to issues when using overloaded functions It is also considered a 'best practise' for modern C++ and conveys the programmers intention more precisly. commit d53307f14cfa9cb416a3d1c8919d4f61cbb20bf7 Author: nobounce Date: Sun Jul 23 19:53:36 2023 +0200 Fix path to Linux CI file in itself The CI file has a list of dependent files including itself. The path was not updated when the CI was split into different files commit 594f42b9ebf886b70f6cdf0fb909d53eb6c5407f Merge: aca2e4b 53d6eba Author: Jakob P. Liljenberg Date: Wed Jul 26 15:38:01 2023 +0200 Merge pull request #584 from nobounce/nb/fix-ci-path Fix path to Linux CI file in itself commit aca2e4be7568186e122f1506fa25bdfb8c4f7f2a Author: aristocratos Date: Wed Jul 26 14:38:48 2023 +0200 Fix whitespace indent -> tab indent commit 33faa01910309895763011dce2a3194b889a0b6a Author: aristocratos Date: Wed Jul 26 14:34:15 2023 +0200 Revert fmt submodule to static fmt folder in include commit 53d6ebabc052a618001fa857eff25d5252a89210 Author: nobounce Date: Sun Jul 23 19:53:36 2023 +0200 Fix path to Linux CI file in itself The CI file has a list of dependent files including itself. The path was not updated when the CI was split into different files --- src/btop_tools.hpp | 67 +++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 34 deletions(-) (limited to 'src/btop_tools.hpp') diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp index 7e499f6..c4d9670 100644 --- a/src/btop_tools.hpp +++ b/src/btop_tools.hpp @@ -39,10 +39,10 @@ tab-size = 4 #endif #endif #define FMT_HEADER_ONLY -#include -#include -#include -#include +#include "fmt/core.h" +#include "fmt/format.h" +#include "fmt/ostream.h" +#include "fmt/ranges.h" using std::array; using std::atomic; @@ -50,7 +50,6 @@ using std::string; using std::to_string; using std::tuple; using std::vector; -using namespace fmt; using namespace fmt::literals; //? ------------------------------------------------- NAMESPACES ------------------------------------------------------ @@ -92,19 +91,19 @@ namespace Fx { //* Collection of escape codes and functions for cursor manipulation namespace Mv { //* Move cursor to , - inline string to(int line, int col) { return Fx::e + to_string(line) + ';' + to_string(col) + 'f'; } + inline string to(int line, int col) { return Fx::e + to_string(line) + ';' + to_string(col) + 'f'; } //* Move cursor right columns - inline string r(int x) { return Fx::e + to_string(x) + 'C'; } + inline string r(int x) { return Fx::e + to_string(x) + 'C'; } //* Move cursor left columns - inline string l(int x) { return Fx::e + to_string(x) + 'D'; } + inline string l(int x) { return Fx::e + to_string(x) + 'D'; } //* Move cursor up x lines - inline string u(int x) { return Fx::e + to_string(x) + 'A'; } + inline string u(int x) { return Fx::e + to_string(x) + 'A'; } //* Move cursor down x lines - inline string d(int x) { return Fx::e + to_string(x) + 'B'; } + inline string d(int x) { return Fx::e + to_string(x) + 'B'; } //* Save cursor position const string save = Fx::e + "s"; @@ -162,15 +161,15 @@ namespace Tools { size_t wide_ulen(const std::wstring& w_str); //* Return number of UTF8 characters in a string (wide=true for column size needed on terminal) - inline size_t ulen(const string& str, bool wide = false) { + inline size_t ulen(const string& str, bool wide = false) { return (wide ? wide_ulen(str) : std::ranges::count_if(str, [](char c) { return (static_cast(c) & 0xC0) != 0x80; })); } //* Resize a string consisting of UTF8 characters (only reduces size) - string uresize(const string str, const size_t len, bool wide = false); + string uresize(const string str, const size_t len, bool wide = false); //* Resize a string consisting of UTF8 characters from left (only reduces size) - string luresize(const string str, const size_t len, bool wide = false); + string luresize(const string str, const size_t len, bool wide = false); //* Replace in with and return new string string s_replace(const string& str, const string& from, const string& to); @@ -207,11 +206,11 @@ namespace Tools { //* Check if string contains string , while ignoring case inline bool s_contains_ic(const string& str, const string& find_val) { - auto it = std::search( - str.begin(), str.end(), - find_val.begin(), find_val.end(), - [](char ch1, char ch2) { return std::toupper(ch1) == std::toupper(ch2); } - ); + auto it = std::search( + str.begin(), str.end(), + find_val.begin(), find_val.end(), + [](char ch1, char ch2) { return std::toupper(ch1) == std::toupper(ch2); } + ); return it != str.end(); } @@ -272,35 +271,35 @@ namespace Tools { auto ssplit(const string& str, const char& delim = ' ') -> vector; //* Put current thread to sleep for milliseconds - inline void sleep_ms(const size_t& ms) { - std::this_thread::sleep_for(std::chrono::milliseconds(ms)); - } + inline void sleep_ms(const size_t& ms) { + std::this_thread::sleep_for(std::chrono::milliseconds(ms)); + } //* Put current thread to sleep for microseconds - inline void sleep_micros(const size_t& micros) { - std::this_thread::sleep_for(std::chrono::microseconds(micros)); - } + inline void sleep_micros(const size_t& micros) { + std::this_thread::sleep_for(std::chrono::microseconds(micros)); + } //* Left justify string if is greater than length, limit return size to by default - string ljust(string str, const size_t x, bool utf = false, bool wide = false, bool limit = true); + string ljust(string str, const size_t x, bool utf = false, bool wide = false, bool limit = true); //* Right justify string if is greater than length, limit return size to by default - string rjust(string str, const size_t x, bool utf = false, bool wide = false, bool limit = true); + string rjust(string str, const size_t x, bool utf = false, bool wide = false, bool limit = true); //* Center justify string if is greater than length, limit return size to by default - string cjust(string str, const size_t x, bool utf = false, bool wide = false, bool limit = true); + string cjust(string str, const size_t x, bool utf = false, bool wide = false, bool limit = true); //* Replace whitespaces " " with escape code for move right string trans(const string& str); //* Convert seconds to format "d ::" and return string - string sec_to_dhms(size_t seconds, bool no_days = false, bool no_seconds = false); + string sec_to_dhms(size_t seconds, bool no_days = false, bool no_seconds = false); //* Scales up in steps of 1024 to highest positive value unit and returns string with unit suffixed //* bit=True or defaults to bytes //* start=int to set 1024 multiplier starting unit //* short=True always returns 0 decimals and shortens unit to 1 character - string floating_humanizer(uint64_t value, bool shorten = false, size_t start = 0, bool bit = false, bool per_second = false); + string floating_humanizer(uint64_t value, bool shorten = false, size_t start = 0, bool bit = false, bool per_second = false); //* Add std::string operator * : Repeat string number of times std::string operator*(const string& str, int64_t n); @@ -323,21 +322,21 @@ namespace Tools { #endif } - void atomic_wait(const atomic& atom, bool old = true) noexcept; + void atomic_wait(const atomic& atom, bool old = true) noexcept; - void atomic_wait_for(const atomic& atom, bool old = true, const uint64_t wait_ms = 0) noexcept; + void atomic_wait_for(const atomic& atom, bool old = true, const uint64_t wait_ms = 0) noexcept; //* Sets atomic to true on construct, sets to false on destruct class atomic_lock { atomic& atom; - bool not_true{}; // defaults to false + bool not_true{}; // defaults to false public: - atomic_lock(atomic& atom, bool wait = false); + atomic_lock(atomic& atom, bool wait = false); ~atomic_lock(); }; //* Read a complete file and return as a string - string readfile(const std::filesystem::path& path, const string& fallback = ""); + string readfile(const std::filesystem::path& path, const string& fallback = ""); //* Convert a celsius value to celsius, fahrenheit, kelvin or rankin and return tuple with new value and unit. auto celsius_to(const long long& celsius, const string& scale) -> tuple; -- cgit v1.2.3 From ced47a960f649d3c4e81c91128fe97a81e4c4ad5 Mon Sep 17 00:00:00 2001 From: aristocratos Date: Mon, 25 Dec 2023 02:26:13 +0100 Subject: Replace robin_hood map and set with STD alternative and add safeVal() function for map/vector access with fallback --- src/btop_tools.hpp | 106 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 29 deletions(-) (limited to 'src/btop_tools.hpp') diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp index c4d9670..c7b2cc3 100644 --- a/src/btop_tools.hpp +++ b/src/btop_tools.hpp @@ -31,6 +31,10 @@ tab-size = 4 #include #include #include +#include +#ifdef BTOP_DEBUG +#include +#endif #ifndef HOST_NAME_MAX #ifdef __APPLE__ #define HOST_NAME_MAX 255 @@ -146,6 +150,35 @@ namespace Term { void restore(); } +//* Simple logging implementation +namespace Logger { + const vector log_levels = { + "DISABLED", + "ERROR", + "WARNING", + "INFO", + "DEBUG", + }; + extern std::filesystem::path logfile; + + enum Level : size_t { + DISABLED = 0, + ERROR = 1, + WARNING = 2, + INFO = 3, + DEBUG = 4, + }; + + //* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG" + void set(const string& level); + + void log_write(const Level level, const string& msg); + inline void error(const string msg) { log_write(ERROR, msg); } + inline void warning(const string msg) { log_write(WARNING, msg); } + inline void info(const string msg) { log_write(INFO, msg); } + inline void debug(const string msg) { log_write(DEBUG, msg); } +} + //? --------------------------------------------------- FUNCTIONS ----------------------------------------------------- namespace Tools { @@ -304,6 +337,50 @@ namespace Tools { //* Add std::string operator * : Repeat string number of times std::string operator*(const string& str, int64_t n); + template +#ifdef BTOP_DEBUG + T safeVal(const std::unordered_map& map, const K& key, T fallback = T(), std::source_location loc = std::source_location::current()) { + if (map.contains(key)) { + return map.at(key); + } else { + Logger::error(fmt::format("safeVal() called with invalid key: [{}] in file: {} on line: {}", key, loc.file_name(), loc.line())); + return fallback; + } + }; +#else + T safeVal(const std::unordered_map& map, const K& key, T fallback = T()) { + if (map.contains(key)) { + return map.at(key); + } else { + Logger::error(fmt::format("safeVal() called with invalid key: [{}] (Compile btop with DEBUG=true for more extensive logging!)", key)); + return fallback; + } + }; +#endif + + template +#ifdef BTOP_DEBUG + T safeVal(const std::vector& vec, const size_t& index, T fallback = T(), std::source_location loc = std::source_location::current()) { + if (index < vec.size()) { + return vec.at(index); + } else { + Logger::error(fmt::format("safeVal() called with invalid index: [{}] in file: {} on line: {}", index, loc.file_name(), loc.line())); + return fallback; + } + }; +#else + T safeVal(const std::vector& vec, const size_t& index, T fallback = T()) { + if (index < vec.size()) { + return vec.at(index); + } else { + Logger::error(fmt::format("safeVal() called with invalid index: [{}] (Compile btop with DEBUG=true for more extensive logging!)", index)); + return fallback; + } + }; +#endif + + + //* Return current time in format string strf_time(const string& strf); @@ -342,35 +419,6 @@ namespace Tools { auto celsius_to(const long long& celsius, const string& scale) -> tuple; } -//* Simple logging implementation -namespace Logger { - const vector log_levels = { - "DISABLED", - "ERROR", - "WARNING", - "INFO", - "DEBUG", - }; - extern std::filesystem::path logfile; - - enum Level : size_t { - DISABLED = 0, - ERROR = 1, - WARNING = 2, - INFO = 3, - DEBUG = 4, - }; - - //* Set log level, valid arguments: "DISABLED", "ERROR", "WARNING", "INFO" and "DEBUG" - void set(const string& level); - - void log_write(const Level level, const string& msg); - inline void error(const string msg) { log_write(ERROR, msg); } - inline void warning(const string msg) { log_write(WARNING, msg); } - inline void info(const string msg) { log_write(INFO, msg); } - inline void debug(const string msg) { log_write(DEBUG, msg); } -} - namespace Tools { //* Creates a named timer that is started on construct (by default) and reports elapsed time in microseconds to Logger::debug() on destruct if running //* Unless delayed_report is set to false, all reporting is buffered and delayed until DebugTimer is destructed or .force_report() is called -- cgit v1.2.3 From 8b81c4a4ecfd7a3e56960befc2b3726f9dddd92d Mon Sep 17 00:00:00 2001 From: aristocratos Date: Mon, 25 Dec 2023 03:28:35 +0100 Subject: Return const refs --- src/btop_tools.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/btop_tools.hpp') diff --git a/src/btop_tools.hpp b/src/btop_tools.hpp index c7b2cc3..bda89f2 100644 --- a/src/btop_tools.hpp +++ b/src/btop_tools.hpp @@ -339,7 +339,7 @@ namespace Tools { template #ifdef BTOP_DEBUG - T safeVal(const std::unordered_map& map, const K& key, T fallback = T(), std::source_location loc = std::source_location::current()) { + const T& safeVal(const std::unordered_map& map, const K& key, const T& fallback = T{}, std::source_location loc = std::source_location::current()) { if (map.contains(key)) { return map.at(key); } else { @@ -348,7 +348,7 @@ namespace Tools { } }; #else - T safeVal(const std::unordered_map& map, const K& key, T fallback = T()) { + const T& safeVal(const std::unordered_map& map, const K& key, const T& fallback = T{}) { if (map.contains(key)) { return map.at(key); } else { @@ -360,7 +360,7 @@ namespace Tools { template #ifdef BTOP_DEBUG - T safeVal(const std::vector& vec, const size_t& index, T fallback = T(), std::source_location loc = std::source_location::current()) { + const T& safeVal(const std::vector& vec, const size_t& index, const T& fallback = T{}, std::source_location loc = std::source_location::current()) { if (index < vec.size()) { return vec.at(index); } else { @@ -369,7 +369,7 @@ namespace Tools { } }; #else - T safeVal(const std::vector& vec, const size_t& index, T fallback = T()) { + const T& safeVal(const std::vector& vec, const size_t& index, const T& fallback = T{}) { if (index < vec.size()) { return vec.at(index); } else { -- cgit v1.2.3