diff --git a/include/plasp/utils/Formatting.h b/include/plasp/utils/Formatting.h index b0c1cf1..ee64388 100644 --- a/include/plasp/utils/Formatting.h +++ b/include/plasp/utils/Formatting.h @@ -3,7 +3,7 @@ #include -#include +#include namespace plasp { @@ -41,23 +41,27 @@ enum class FontWeight struct Format { Format(Color color, FontWeight fontWeight = FontWeight::Normal) - : color{color}, - fontWeight{fontWeight} + : m_color{color}, + m_fontWeight{fontWeight} { } - Color color; - FontWeight fontWeight; + Color m_color; + FontWeight m_fontWeight; }; //////////////////////////////////////////////////////////////////////////////////////////////////// -std::ostream &operator<<(std::ostream &ostream, const Format &format) +template +LogStream &operator<<(LogStream &stream, const Format &format) { - const auto fontWeightCode = static_cast(format.fontWeight); - const auto colorCode = 30 + static_cast(format.color); + if (!stream.supportsColor()) + return stream; - return (ostream << "\033[" << fontWeightCode << ";" << colorCode << "m"); + const auto fontWeightCode = static_cast(format.m_fontWeight); + const auto colorCode = 30 + static_cast(format.m_color); + + return (stream << "\033[" << fontWeightCode << ";" << colorCode << "m"); } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -68,9 +72,13 @@ class ResetFormat //////////////////////////////////////////////////////////////////////////////////////////////////// -std::ostream &operator<<(std::ostream &ostream, const ResetFormat &) +template +LogStream &operator<<(LogStream &stream, const ResetFormat &) { - return (ostream << "\033[0m"); + if (!stream.supportsColor()) + return stream; + + return (stream << "\033[0m"); } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/plasp/utils/LogStream.h b/include/plasp/utils/LogStream.h new file mode 100644 index 0000000..13d46af --- /dev/null +++ b/include/plasp/utils/LogStream.h @@ -0,0 +1,247 @@ +#ifndef __PLASP__UTILS__LOG_STREAM_H +#define __PLASP__UTILS__LOG_STREAM_H + +#include +#include + +namespace plasp +{ +namespace utils +{ + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// LogStream +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +enum class StandardStream +{ + Out, + Err +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +class LogStream +{ + private: + using CharacterType = std::ostream::char_type; + using TraitsType = std::ostream::traits_type; + + public: + bool supportsColor() const + { + const auto fileDescriptor = + (StandardStream == StandardStream::Out) + ? STDOUT_FILENO + : STDERR_FILENO; + + return isatty(fileDescriptor); + } + + std::ostream &ostream() + { + return (StandardStream == StandardStream::Out) + ? std::cout + : std::cerr; + } + + LogStream &operator<<(short value); + LogStream &operator<<(unsigned short value); + LogStream &operator<<(int value); + LogStream &operator<<(unsigned int value); + LogStream &operator<<(long value); + LogStream &operator<<(unsigned long value); + LogStream &operator<<(long long value); + LogStream &operator<<(unsigned long long value); + LogStream &operator<<(float value); + LogStream &operator<<(double value); + LogStream &operator<<(long double value); + LogStream &operator<<(bool value); + LogStream &operator<<(const void *value); + LogStream &operator<<(const char *value); + LogStream &operator<<(std::basic_streambuf *sb); + LogStream &operator<<(std::ios_base &(*func)(std::ios_base &)); + LogStream &operator<<(std::basic_ios &(*func)(std::basic_ios &)); + LogStream &operator<<(std::basic_ostream &(*func)(std::basic_ostream &)); +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(short value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(unsigned short value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(int value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(unsigned int value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(long value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(unsigned long value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(long long value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(unsigned long long value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(float value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(double value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(long double value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(bool value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(const void *value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(const char *value) +{ + ostream() << value; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(std::basic_streambuf* sb) +{ + ostream() << sb; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(std::ios_base &(*func)(std::ios_base &)) +{ + ostream() << func; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(std::basic_ios &(*func)(std::basic_ios &)) +{ + ostream() << func; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &LogStream::operator<<(std::basic_ostream &(*func)(std::basic_ostream &)) +{ + ostream() << func; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +template +LogStream &operator<<(LogStream &stream, const std::basic_string &string) +{ + stream.ostream() << string; + return stream; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +} +} + +#endif diff --git a/src/plasp/utils/Logger.cpp b/src/plasp/utils/Logger.cpp index ba045d2..5e4cfac 100644 --- a/src/plasp/utils/Logger.cpp +++ b/src/plasp/utils/Logger.cpp @@ -1,6 +1,7 @@ #include #include +#include namespace plasp { @@ -63,50 +64,29 @@ void Logger::setWarningLevel(WarningLevel warningLevel) void Logger::logError(const std::string &message) { - if (isatty(STDERR_FILENO)) - { - std::cerr - << Format(Color::Red, FontWeight::Bold) << "error:" - << ResetFormat() << " " - << Format(Color::White, FontWeight::Bold) << message - << ResetFormat() << std::endl; - } - else - { - std::cerr - << "error:" - << " " - << message - << std::endl; - } + LogStream stream; + + stream + << Format(Color::Red, FontWeight::Bold) << "error:" + << ResetFormat() << " " + << Format(Color::White, FontWeight::Bold) << message + << ResetFormat() << std::endl; } //////////////////////////////////////////////////////////////////////////////////////////////////// void Logger::logError(const Parser::Coordinate &coordinate, const std::string &message) { - if (isatty(STDERR_FILENO)) - { - std::cerr - << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" - << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" - << ResetFormat() << " " - << Format(Color::Red, FontWeight::Bold) << "error:" - << ResetFormat() << " " - << Format(Color::White, FontWeight::Bold) << message - << ResetFormat() << std::endl; - } - else - { - std::cerr - << coordinate.sectionName << ":" - << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" - << " " - << "error:" - << " " - << message - << std::endl; - } + LogStream stream; + + stream + << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" + << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" + << ResetFormat() << " " + << Format(Color::Red, FontWeight::Bold) << "error:" + << ResetFormat() << " " + << Format(Color::White, FontWeight::Bold) << message + << ResetFormat() << std::endl; } //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -121,28 +101,16 @@ void Logger::logWarning(const Parser &parser, const std::string &message) const auto coordinate = parser.coordinate(); - if (isatty(STDERR_FILENO)) - { - std::cerr - << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" - << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" - << ResetFormat() << " " - << Format(Color::Magenta, FontWeight::Bold) << "warning:" - << ResetFormat() << " " - << Format(Color::White, FontWeight::Bold) << message - << ResetFormat() << std::endl; - } - else - { - std::cerr - << coordinate.sectionName << ":" - << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" - << " " - << "warning:" - << " " - << message - << std::endl; - } + LogStream stream; + + stream + << Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":" + << std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":" + << ResetFormat() << " " + << Format(Color::Magenta, FontWeight::Bold) << "warning:" + << ResetFormat() << " " + << Format(Color::White, FontWeight::Bold) << message + << ResetFormat() << std::endl; } ////////////////////////////////////////////////////////////////////////////////////////////////////