From b87dae95de5535d20961dcfadadaf82ce5ca2df0 Mon Sep 17 00:00:00 2001 From: heapwolf Date: Fri, 5 Jul 2019 13:50:24 -0700 Subject: [PATCH] add color, incremental time delta, test env var as regex --- index.hxx | 74 ++++++++++++++++++++++++++++++++++++++++++-------- test/index.cxx | 32 ++++++++++++++++++++-- 2 files changed, 93 insertions(+), 13 deletions(-) diff --git a/index.hxx b/index.hxx index ea46b58..6dc9436 100644 --- a/index.hxx +++ b/index.hxx @@ -4,29 +4,74 @@ #include #include #include +#include +#include +#include class Debug { - std::string name = ""; + using clock_t = std::chrono::high_resolution_clock; + using duration_t = clock_t::duration; + using Str = std::string; + + Str name = ""; std::ostream& output = std::cout; + inline static std::map colors; + inline static int colorIndex = 0; + + const Str RESET = "\033[0m"; + + clock_t::time_point start; + + void init () { + start = clock_t::now(); + + if (Debug::colorIndex == 255) { + Debug::colorIndex = 0; + } + + const auto n = std::to_string(Debug::colorIndex++); + Debug::colors[this->name] = "\033[38;5;" + n + "m"; + } + public: + Debug () { init(); } - Debug (); + Debug (const Str& str) + : name(str) { init(); }; - Debug (const std::string& str) - : name(str) {}; + Debug (const Str& str, std::ostream& out) + : name(str), output(out) { init(); }; - Debug (const std::string& str, std::ostream& out) - : name(str), output(out) {}; + Str ms() const { + using namespace std::literals; + const auto delta = (clock_t::now() - start) / 1ms; + const auto sign = Debug::colors[this->name] + " +"; + + return sign + std::to_string(delta) + "ms" + RESET; + } + + Str replace(Str s, const Str& a, const Str& b) { + Str::size_type pos = 0; + + while ((pos = s.find(a, pos)) != Str::npos) { + s.replace(pos, a.length(), b); + pos += b.length(); + } + + return s; + } template void operator() (Args&&... args) { - auto envp = std::getenv("DEBUG"); + const auto envp = std::getenv("DEBUG"); if (envp != nullptr) { - auto env = std::string(envp); + auto env = Str(envp); + + const auto res = replace(env, "*", "(.*)"); - if (env.find(this->name) == std::string::npos) { + if (!std::regex_match(this->name, std::regex(res))) { return; // the env var does not contain the name } } @@ -34,7 +79,8 @@ class Debug { // // Print out the name of this instance. // - this->output << this->name << " "; + const auto color = Debug::colors[this->name]; + this->output << color << this->name << RESET << " "; // // Put all the args and their types into a container @@ -48,7 +94,13 @@ class Debug { auto size = std::tuple_size::value - 1; auto print = [this, &size](auto&&... args) { - ((this->output << args << (size-- == 0 ? "" : " ")), ...); + ( + ( + this->output + << args + << (size-- ? " " : ms()) + ), ... + ); }; std::apply(print, v); diff --git a/test/index.cxx b/test/index.cxx index d7f31f1..6efae69 100644 --- a/test/index.cxx +++ b/test/index.cxx @@ -31,9 +31,37 @@ int main() { debug(2, "hello", 'x', 1.1); auto actual = ss.str(); - auto expected = "foo 2 hello x 1.1\n"; - t->equal(actual, expected, "output matches"); + t->ok(actual.find("foo") != std::string::npos, "output matches"); + t->ok(actual.find("hello x 1.1") != std::string::npos, "output matches"); + + t->end(); + }); + + t.test("time", [&](auto t) { + putenv("DEBUG=foo:*:bazz"); + using namespace std::chrono_literals; + + std::stringstream ss; + Debug x("foo:bar:bazz", ss); + Debug y("foo:boop:bazz", ss); + Debug z("foo:boop:nope", ss); + + for (int i = 0; i < 10; i++) { + std::this_thread::sleep_for(0.01s); + x("test", rand(), "x=" + std::to_string(i)); + y("test", "y=" + std::to_string(i)); + z("test", "z=" + std::to_string(i)); + } + + auto actual = ss.str(); + + for (int i = 0; i < 10; i++) { + t->ok(actual.find("x=" + std::to_string(i)) != std::string::npos, "output matches"); + t->ok(actual.find("y=" + std::to_string(i)) != std::string::npos, "output matches"); + t->ok(actual.find("z=" + std::to_string(i)) == std::string::npos, "output matches"); + } + t->end(); }); }