From 7aad8380d1a0e0387fa1a8085b6ad85686794d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Tue, 30 May 2017 17:19:26 +0200 Subject: [PATCH] Refactored logging interface. --- app/main.cpp | 8 ++--- include/anthem/StatementVisitor.h | 5 ++- include/anthem/Utils.h | 3 +- include/anthem/output/FormatScope.h | 48 +++++++++++++++++++++++++++++ include/anthem/output/Logger.h | 5 +-- include/anthem/output/NullStream.h | 38 +++++++++++++++++++++++ src/anthem/Translation.cpp | 5 ++- src/anthem/output/Logger.cpp | 19 +++++++----- src/anthem/output/NullStream.cpp | 24 +++++++++++++++ 9 files changed, 134 insertions(+), 21 deletions(-) create mode 100644 include/anthem/output/FormatScope.h create mode 100644 include/anthem/output/NullStream.h create mode 100644 src/anthem/output/NullStream.cpp diff --git a/app/main.cpp b/app/main.cpp index 511de1d..b77b3a7 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -47,7 +47,7 @@ int main(int argc, char **argv) } catch (const po::error &e) { - context.logger.log(anthem::output::Priority::Error, e.what()); + context.logger.log(anthem::output::Priority::Error) << e.what(); printHelp(); return EXIT_FAILURE; } @@ -74,7 +74,7 @@ int main(int argc, char **argv) context.logger.setColorPolicy(anthem::output::ColorStream::ColorPolicy::Always); else { - context.logger.log(anthem::output::Priority::Error, ("unknown color policy “" + colorPolicyString + "”").c_str()); + context.logger.log(anthem::output::Priority::Error) << "unknown color policy “" << colorPolicyString << "”"; context.logger.errorStream() << std::endl; printHelp(); return EXIT_FAILURE; @@ -89,7 +89,7 @@ int main(int argc, char **argv) } catch (const std::exception &e) { - context.logger.log(anthem::output::Priority::Error, ("unknown log priorty “" + logPriorityString + "”").c_str()); + context.logger.log(anthem::output::Priority::Error) << "unknown log priorty “" << logPriorityString << "”"; context.logger.errorStream() << std::endl; printHelp(); return EXIT_FAILURE; @@ -107,7 +107,7 @@ int main(int argc, char **argv) } catch (const std::exception &e) { - context.logger.log(anthem::output::Priority::Error, e.what()); + context.logger.log(anthem::output::Priority::Error) << e.what(); return EXIT_FAILURE; } diff --git a/include/anthem/StatementVisitor.h b/include/anthem/StatementVisitor.h index 8369d2b..baf893b 100644 --- a/include/anthem/StatementVisitor.h +++ b/include/anthem/StatementVisitor.h @@ -39,8 +39,7 @@ struct StatementVisitor { void visit(const Clingo::AST::Program &program, const Clingo::AST::Statement &statement, std::vector &, Context &context) { - // TODO: refactor - context.logger.log(output::Priority::Debug, (std::string("[program] ") + program.name).c_str()); + context.logger.log(output::Priority::Debug) << "[program] " << program.name; if (!program.parameters.empty()) throwErrorAtLocation(statement.location, "program parameters currently unsupported", context); @@ -76,7 +75,7 @@ struct StatementVisitor if (!consequent) { // TODO: think about throwing an exception instead - context.logger.log(output::Priority::Error, "could not translate formula consequent"); + context.logger.log(output::Priority::Error) << "could not translate formula consequent"; return; } diff --git a/include/anthem/Utils.h b/include/anthem/Utils.h index 49e75a1..f6f8fdf 100644 --- a/include/anthem/Utils.h +++ b/include/anthem/Utils.h @@ -31,13 +31,14 @@ inline input::Location location_cast(const Clingo::Location &location) //////////////////////////////////////////////////////////////////////////////////////////////////// +// TODO: refactor inline void throwErrorAtLocation(const Clingo::Location &clingoLocation, const char *errorMessage, Context &context) { const auto location = location_cast(clingoLocation); // TODO: think about removing this to avoid double error messages - context.logger.log(output::Priority::Error, location, errorMessage); + context.logger.log(output::Priority::Error, location) << errorMessage; throw std::runtime_error(errorMessage); } diff --git a/include/anthem/output/FormatScope.h b/include/anthem/output/FormatScope.h new file mode 100644 index 0000000..097787b --- /dev/null +++ b/include/anthem/output/FormatScope.h @@ -0,0 +1,48 @@ +#ifndef __ANTHEM__OUTPUT__FORMAT_SCOPE_H +#define __ANTHEM__OUTPUT__FORMAT_SCOPE_H + +#include +#include + +namespace anthem +{ +namespace output +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// FormatScope +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class FormatScope +{ + public: + explicit FormatScope(ColorStream &colorStream) + : m_colorStream{colorStream} + { + } + + ~FormatScope() + { + m_colorStream << output::ResetFormat() << std::endl; + } + + template + inline FormatScope &operator<<(T &&value) + { + m_colorStream << std::forward(value); + + return *this; + } + + private: + ColorStream &m_colorStream; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/include/anthem/output/Logger.h b/include/anthem/output/Logger.h index b18a140..0d9f2ec 100644 --- a/include/anthem/output/Logger.h +++ b/include/anthem/output/Logger.h @@ -5,6 +5,7 @@ #include #include +#include #include namespace anthem @@ -32,8 +33,8 @@ class Logger void setLogPriority(Priority logPriority); void setColorPolicy(ColorStream::ColorPolicy colorPolicy); - void log(Priority priority, const char *message); - void log(Priority priority, const input::Location &location, const char *message); + FormatScope log(Priority priority); + FormatScope log(Priority priority, const input::Location &location); private: ColorStream m_outputStream; diff --git a/include/anthem/output/NullStream.h b/include/anthem/output/NullStream.h new file mode 100644 index 0000000..c506f7d --- /dev/null +++ b/include/anthem/output/NullStream.h @@ -0,0 +1,38 @@ +#ifndef __ANTHEM__OUTPUT__NULL_STREAM_H +#define __ANTHEM__OUTPUT__NULL_STREAM_H + +#include + +namespace anthem +{ +namespace output +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// NullStream +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class NullBuffer : public std::streambuf +{ + public: + int overflow(int c) + { + return c; + } +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +extern ColorStream nullStream; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +} + +#endif diff --git a/src/anthem/Translation.cpp b/src/anthem/Translation.cpp index bed8eb5..d11f077 100644 --- a/src/anthem/Translation.cpp +++ b/src/anthem/Translation.cpp @@ -35,8 +35,7 @@ void translate(const std::vector &fileNames, Context &context) void translate(const char *fileName, std::istream &stream, Context &context) { - // TODO: refactor - context.logger.log(output::Priority::Info, (std::string("reading ") + fileName).c_str()); + context.logger.log(output::Priority::Info) << "reading " << fileName; auto fileContent = std::string(std::istreambuf_iterator(stream), {}); @@ -51,7 +50,7 @@ void translate(const char *fileName, std::istream &stream, Context &context) const auto logger = [&context](const Clingo::WarningCode, const char *text) { - context.logger.log(output::Priority::Error, text); + context.logger.log(output::Priority::Error) << text; }; Clingo::parse_program(fileContent.c_str(), translateStatement, logger); diff --git a/src/anthem/output/Logger.cpp b/src/anthem/output/Logger.cpp index 48b5a13..8f8fb83 100644 --- a/src/anthem/output/Logger.cpp +++ b/src/anthem/output/Logger.cpp @@ -1,6 +1,7 @@ #include #include +#include namespace anthem { @@ -92,28 +93,29 @@ void Logger::setColorPolicy(ColorStream::ColorPolicy colorPolicy) //////////////////////////////////////////////////////////////////////////////////////////////////// -void Logger::log(Priority priority, const char *message) +FormatScope Logger::log(Priority priority) { const auto priorityID = static_cast(priority); if (priorityID < static_cast(m_logPriority)) - return; + return FormatScope(detail::nullStream); m_errorStream << priorityFormat(priority) << priorityName(priority) << ":" << ResetFormat() << " " - << MessageBodyFormat << message - << ResetFormat() << std::endl; + << MessageBodyFormat; + + return FormatScope(m_errorStream); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void Logger::log(Priority priority, const input::Location &location, const char *message) +FormatScope Logger::log(Priority priority, const input::Location &location) { const auto priorityID = static_cast(priority); if (priorityID < static_cast(m_logPriority)) - return; + return FormatScope(detail::nullStream); m_errorStream << LocationFormat @@ -121,8 +123,9 @@ void Logger::log(Priority priority, const input::Location &location, const char << ResetFormat() << " " << priorityFormat(priority) << priorityName(priority) << ":" << ResetFormat() << " " - << MessageBodyFormat << message - << ResetFormat() << std::endl; + << MessageBodyFormat; + + return FormatScope(m_errorStream); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/anthem/output/NullStream.cpp b/src/anthem/output/NullStream.cpp new file mode 100644 index 0000000..58a23d6 --- /dev/null +++ b/src/anthem/output/NullStream.cpp @@ -0,0 +1,24 @@ +#include + +namespace anthem +{ +namespace output +{ +namespace detail +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// NullStream +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +NullBuffer nullBuffer; +std::ostream nullOStream(&nullBuffer); +ColorStream nullStream(nullOStream); + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} +}