From 9a43d50969ecc34d9a3bc8944bc2182e55f7a712 Mon Sep 17 00:00:00 2001 From: mrbesen Date: Wed, 26 Oct 2022 21:16:56 +0200 Subject: [PATCH] qt support --- Log.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ Log.h | 47 +++++++++++++++++++++++++++++++++++++++++++++++ Makefile | 3 ++- 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/Log.cpp b/Log.cpp index 95c1f6c..32cd703 100644 --- a/Log.cpp +++ b/Log.cpp @@ -10,8 +10,29 @@ #include #endif +#if LOG_ENABLEQT == 1 +#include +#endif + namespace Log { +#if LOG_ENABLEQT == 1 +void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message) { + + // convert type to Log::Level + Log::Level lvl = Log::Level::off; + switch(type) { + case QtDebugMsg: lvl = Log::Level::debug; break; + case QtInfoMsg: lvl = Log::Level::info; break; + case QtWarningMsg: lvl = Log::Level::warn; break; + case QtCriticalMsg: lvl = Log::Level::error; break; + case QtFatalMsg: lvl = Log::Level::fatal; break; + } + + Entry(lvl, context) << message.toStdString(); +} +#endif + /* * abstract class Output * default implementations @@ -147,6 +168,13 @@ void log(Level lvl, std::stringbuf* strb) { /* * class Entry */ +#if LOG_ENABLEQT == 1 +Entry::Entry(Level lvl, const QMessageLogContext& context) : lvl{lvl}, context{&context} { + for(const auto& metafunc : entryMetaFunctions) { + metafunc(ss, *this); + } +} +#endif Entry::Entry(Level lvl) : lvl{lvl} { for(const auto& metafunc : entryMetaFunctions) { @@ -182,6 +210,16 @@ std::ostream& defaultEntryMetaLevel(std::ostream& os, const Entry& e) { return os << LevelTag[static_cast(e.getLevel())]; } +#if LOG_ENABLEQT == 1 +std::ostream& defaultEntryMetaQtContext(std::ostream& os, const Entry& e) { + if (e.getContext() && e.getContext()->file) { + const std::string file = e.getContext()->file; + return os << file << ':' << e.getContext()->line; + } + return os << "-:-"; +} +#endif + void init() { // add default console logger if (outputs.empty()) { @@ -196,11 +234,24 @@ void init() { entryMetaFunctions = { defaultEntryMetaTime, defaultEntryMetaLevel, + + #if LOG_ENABLEQT == 1 + space, + defaultEntryMetaQtContext, + #endif + space }; + + #if LOG_ENABLEQT == 1 + qInstallMessageHandler( &Log::qtMessageHandler ); + #endif } void stop() { + #if LOG_ENABLEQT == 1 + qInstallMessageHandler( nullptr ); + #endif outputs.clear(); } diff --git a/Log.h b/Log.h index b172eb5..3072eea 100644 --- a/Log.h +++ b/Log.h @@ -9,9 +9,45 @@ #define LOG_USEMUTEX 0 #endif +#ifndef LOG_ENABLEQT +#define LOG_ENABLEQT 0 +#endif + +#if LOG_ENABLEQT == 1 +#include +#include +#endif + +#if LOG_ENABLEQT == 1 +template +QDebug operator<<(QDebug dbg, const T& str) { + std::ostringstream stream; + stream << str; + QString conv = QString::fromStdString(stream.str()); + QDebugStateSaver saver(dbg); + dbg << conv; + return dbg; +} + +/* +// string specialisation, not allowed, because multiple definitions of the same operator are not allowed +template<> +QDebug operator<<(QDebug dbg, const std::string& str) { + QDebugStateSaver saver(dbg); + QString conv = QString::fromStdString(str); + dbg << conv; + return dbg; +} +*/ +#endif + namespace Log { enum class Level { off = 0, fatal, error, warn, note, info, debug, trace }; +#if LOG_ENABLEQT == 1 +void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message); +#endif + // set up the logger with a ConsoleOutput void init(); // close all output streams @@ -30,6 +66,11 @@ class Entry { private: std::stringstream ss; const Level lvl; +#if LOG_ENABLEQT == 1 + const QMessageLogContext* context = nullptr; + Entry(Level lvl, const QMessageLogContext&); + friend void qtMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString& message); +#endif void addMetadataHeader(); @@ -45,6 +86,12 @@ public: return lvl; } +#if LOG_ENABLEQT == 1 + constexpr const QMessageLogContext* getContext() const { + return context; + } +#endif + using MetaFunction = std::function; template Entry& operator<<(T&& msg) { diff --git a/Makefile b/Makefile index 89fcc76..0b94e75 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,8 @@ TARGET = Log.o TEST = test LOG_USEMUTEX ?= 0 -CXXFLAGS = -O2 -g -std=c++11 -Wall -Wextra -pedantic-errors -MMD -DLOG_USEMUTEX=$(LOG_USEMUTEX) +LOG_ENABLEQT ?= 0 +CXXFLAGS = -O2 -g -std=c++11 -Wall -Wextra -pedantic-errors -MMD -DLOG_USEMUTEX=$(LOG_USEMUTEX) -DLOG_ENABLEQT=$(LOG_ENABLEQT) .PHONY: all clean