From eb3d91f0850286be9c650d24faf9f1ef601f24c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Tue, 14 Jun 2016 18:02:59 +0200 Subject: [PATCH] Added command-line option to autodetect, enable, or disable color output. --- CHANGELOG.md | 1 + apps/plasp-app/main.cpp | 38 +++++++++++++++++++++------------ include/plasp/utils/LogStream.h | 37 +++++++++++++++++++++++++++++--- include/plasp/utils/Logger.h | 1 + src/plasp/utils/Logger.cpp | 17 +++++++++++---- 5 files changed, 73 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5687d67..75453b6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Features: * new command-line option `--language` to explicitly specify input language * new command-line option `--warning-level` to treat warnings as errors or to ignore warnings * supports colorized output +* new command-line option `--color` to autodetect, enable, or disable color output Bug Fixes: diff --git a/apps/plasp-app/main.cpp b/apps/plasp-app/main.cpp index 9f0bc8d..dd43531 100644 --- a/apps/plasp-app/main.cpp +++ b/apps/plasp-app/main.cpp @@ -22,7 +22,8 @@ int main(int argc, char **argv) ("version,v", "Display version information.") ("input,i", po::value>(), "Specify the PDDL or SAS input file.") ("language,l", po::value(), "Specify the input language (SAS or PDDL). Omit for automatic detection.") - ("warning-level", po::value()->default_value("normal"), "Specify whether to output warnings normally (normal), to treat them as critical errors (error), or to ignore them (ignore)."); + ("warning-level", po::value()->default_value("normal"), "Specify whether to output warnings normally (normal), to treat them as critical errors (error), or to ignore them (ignore).") + ("color", po::value()->default_value("auto"), "Specify whether to colorize the output (always, never, or auto)."); po::positional_options_description positionalOptionsDescription; positionalOptionsDescription.add("input", -1); @@ -38,6 +39,8 @@ int main(int argc, char **argv) std::cout << description; }; + plasp::utils::Logger logger; + try { po::store(po::command_line_parser(argc, argv) @@ -49,7 +52,8 @@ int main(int argc, char **argv) } catch (const po::error &e) { - std::cerr << "Error: " << e.what() << std::endl << std::endl; + logger.logError(e.what()); + std::cout << std::endl; printHelp(); return EXIT_FAILURE; } @@ -66,6 +70,22 @@ int main(int argc, char **argv) return EXIT_SUCCESS; } + const auto warningLevel = variablesMap["warning-level"].as(); + + if (warningLevel == "error") + logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Error); + else if (warningLevel == "ignore") + logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Ignore); + + const auto colorPolicy = variablesMap["color"].as(); + + if (colorPolicy == "auto") + logger.setColorPolicy(plasp::utils::LogStream::ColorPolicy::Auto); + else if (colorPolicy == "never") + logger.setColorPolicy(plasp::utils::LogStream::ColorPolicy::Never); + else if (colorPolicy == "always") + logger.setColorPolicy(plasp::utils::LogStream::ColorPolicy::Always); + try { plasp::utils::Parser parser; @@ -100,7 +120,6 @@ int main(int argc, char **argv) if (language == plasp::Language::Type::Unknown) { - plasp::utils::Logger logger; logger.logError("unknown input language"); std::cout << std::endl; printHelp(); @@ -109,24 +128,15 @@ int main(int argc, char **argv) if (language == plasp::Language::Type::PDDL) { - auto context = plasp::pddl::Context(std::move(parser)); - - const auto warningLevel = variablesMap["warning-level"].as(); - - if (warningLevel == "error") - context.logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Error); - else if (warningLevel == "ignore") - context.logger.setWarningLevel(plasp::utils::Logger::WarningLevel::Ignore); - + auto context = plasp::pddl::Context(std::move(parser), std::move(logger)); auto description = plasp::pddl::Description::fromContext(std::move(context)); const auto translator = plasp::pddl::TranslatorASP(description, description.context().logger.outputStream()); translator.translate(); } else if (language == plasp::Language::Type::SAS) { - plasp::utils::LogStream logStream(plasp::utils::StandardStream::Out); const auto description = plasp::sas::Description::fromParser(std::move(parser)); - const auto translator = plasp::sas::TranslatorASP(description, logStream); + const auto translator = plasp::sas::TranslatorASP(description, logger.outputStream()); translator.translate(); } } diff --git a/include/plasp/utils/LogStream.h b/include/plasp/utils/LogStream.h index d8832e8..e086b6d 100644 --- a/include/plasp/utils/LogStream.h +++ b/include/plasp/utils/LogStream.h @@ -25,40 +25,70 @@ enum class StandardStream class LogStream { + public: + enum class ColorPolicy + { + Never, + Auto, + Always + }; + private: using CharacterType = std::ostream::char_type; using TraitsType = std::ostream::traits_type; public: LogStream(StandardStream standardStream) - : m_standardStream{standardStream} + : m_standardStream{standardStream}, + m_colorPolicy{ColorPolicy::Never} { } LogStream(const LogStream &other) - : m_standardStream{other.m_standardStream} + : m_standardStream{other.m_standardStream}, + m_colorPolicy{ColorPolicy::Never} { } LogStream &operator=(const LogStream &other) { m_standardStream = other.m_standardStream; + m_colorPolicy = other.m_colorPolicy; + return *this; } LogStream(LogStream &&other) - : m_standardStream{other.m_standardStream} + : m_standardStream{other.m_standardStream}, + m_colorPolicy{other.m_colorPolicy} { + other.m_colorPolicy = ColorPolicy::Never; } LogStream &operator=(LogStream &&other) { m_standardStream = other.m_standardStream; + m_colorPolicy = other.m_colorPolicy; + + other.m_colorPolicy = ColorPolicy::Never; + return *this; } + void setColorPolicy(ColorPolicy colorPolicy) + { + m_colorPolicy = colorPolicy; + } + bool supportsColor() const { + if (m_colorPolicy == ColorPolicy::Never) + return false; + + if (m_colorPolicy == ColorPolicy::Always) + return true; + + // Autodetect by checking whether output goes to a terminal const auto fileDescriptor = (m_standardStream == utils::StandardStream::Out) ? STDOUT_FILENO @@ -95,6 +125,7 @@ class LogStream private: StandardStream m_standardStream; + ColorPolicy m_colorPolicy; }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/utils/Logger.h b/include/plasp/utils/Logger.h index ff56ba1..263fc6f 100644 --- a/include/plasp/utils/Logger.h +++ b/include/plasp/utils/Logger.h @@ -41,6 +41,7 @@ class Logger LogStream &errorStream(); void setWarningLevel(WarningLevel warningLevel); + void setColorPolicy(LogStream::ColorPolicy colorPolicy); void logError(const std::string &message); void logError(const Parser::Coordinate &coordinate, const std::string &message); diff --git a/src/plasp/utils/Logger.cpp b/src/plasp/utils/Logger.cpp index 80cbf9c..8702597 100644 --- a/src/plasp/utils/Logger.cpp +++ b/src/plasp/utils/Logger.cpp @@ -43,8 +43,8 @@ Logger &Logger::operator=(const Logger &other) //////////////////////////////////////////////////////////////////////////////////////////////////// Logger::Logger(Logger &&other) -: m_outputStream{other.m_outputStream}, - m_errorStream{other.m_errorStream}, +: m_outputStream{std::move(other.m_outputStream)}, + m_errorStream{std::move(other.m_errorStream)}, m_warningLevel{other.m_warningLevel} { other.m_warningLevel = WarningLevel::Normal; @@ -54,9 +54,10 @@ Logger::Logger(Logger &&other) Logger &Logger::operator=(Logger &&other) { - m_outputStream = other.m_outputStream; - m_errorStream = other.m_errorStream; + m_outputStream = std::move(other.m_outputStream); + m_errorStream = std::move(other.m_errorStream); m_warningLevel = other.m_warningLevel; + other.m_warningLevel = WarningLevel::Normal; return *this; @@ -85,6 +86,14 @@ void Logger::setWarningLevel(WarningLevel warningLevel) //////////////////////////////////////////////////////////////////////////////////////////////////// +void Logger::setColorPolicy(LogStream::ColorPolicy colorPolicy) +{ + m_outputStream.setColorPolicy(colorPolicy); + m_errorStream.setColorPolicy(colorPolicy); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + void Logger::logError(const std::string &message) { m_errorStream