Added LogStream class for uniform color output handling.

This commit is contained in:
Patrick Lühne 2016-06-14 15:53:53 +02:00
parent 57e9de6b05
commit b599670572
3 changed files with 294 additions and 71 deletions

View File

@ -3,7 +3,7 @@
#include <iostream>
#include <unistd.h>
#include <plasp/utils/LogStream.h>
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<StandardStream StandardStream>
LogStream<StandardStream> &operator<<(LogStream<StandardStream> &stream, const Format &format)
{
const auto fontWeightCode = static_cast<size_t>(format.fontWeight);
const auto colorCode = 30 + static_cast<size_t>(format.color);
if (!stream.supportsColor())
return stream;
return (ostream << "\033[" << fontWeightCode << ";" << colorCode << "m");
const auto fontWeightCode = static_cast<size_t>(format.m_fontWeight);
const auto colorCode = 30 + static_cast<size_t>(format.m_color);
return (stream << "\033[" << fontWeightCode << ";" << colorCode << "m");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -68,9 +72,13 @@ class ResetFormat
////////////////////////////////////////////////////////////////////////////////////////////////////
std::ostream &operator<<(std::ostream &ostream, const ResetFormat &)
template<StandardStream StandardStream>
LogStream<StandardStream> &operator<<(LogStream<StandardStream> &stream, const ResetFormat &)
{
return (ostream << "\033[0m");
if (!stream.supportsColor())
return stream;
return (stream << "\033[0m");
}
////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,247 @@
#ifndef __PLASP__UTILS__LOG_STREAM_H
#define __PLASP__UTILS__LOG_STREAM_H
#include <iostream>
#include <unistd.h>
namespace plasp
{
namespace utils
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// LogStream
//
////////////////////////////////////////////////////////////////////////////////////////////////////
enum class StandardStream
{
Out,
Err
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
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<CharacterType, TraitsType> *sb);
LogStream &operator<<(std::ios_base &(*func)(std::ios_base &));
LogStream &operator<<(std::basic_ios<CharacterType, TraitsType> &(*func)(std::basic_ios<CharacterType, TraitsType> &));
LogStream &operator<<(std::basic_ostream<CharacterType, TraitsType> &(*func)(std::basic_ostream<CharacterType, TraitsType> &));
};
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(short value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(unsigned short value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(int value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(unsigned int value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(long value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(unsigned long value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(long long value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(unsigned long long value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(float value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(double value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(long double value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(bool value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(const void *value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(const char *value)
{
ostream() << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(std::basic_streambuf<CharacterType, TraitsType>* sb)
{
ostream() << sb;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(std::ios_base &(*func)(std::ios_base &))
{
ostream() << func;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(std::basic_ios<CharacterType, TraitsType> &(*func)(std::basic_ios<CharacterType, TraitsType> &))
{
ostream() << func;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream>
LogStream<StandardStream> &LogStream<StandardStream>::operator<<(std::basic_ostream<CharacterType, TraitsType> &(*func)(std::basic_ostream<CharacterType, TraitsType> &))
{
ostream() << func;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<StandardStream StandardStream, class CharacterType, class Traits, class Allocator>
LogStream<StandardStream> &operator<<(LogStream<StandardStream> &stream, const std::basic_string<CharacterType, Traits, Allocator> &string)
{
stream.ostream() << string;
return stream;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@ -1,6 +1,7 @@
#include <plasp/utils/Logger.h>
#include <plasp/utils/Formatting.h>
#include <plasp/utils/LogStream.h>
namespace plasp
{
@ -63,31 +64,22 @@ void Logger::setWarningLevel(WarningLevel warningLevel)
void Logger::logError(const std::string &message)
{
if (isatty(STDERR_FILENO))
{
std::cerr
LogStream<StandardStream::Err> stream;
stream
<< Format(Color::Red, FontWeight::Bold) << "error:"
<< ResetFormat() << " "
<< Format(Color::White, FontWeight::Bold) << message
<< ResetFormat() << std::endl;
}
else
{
std::cerr
<< "error:"
<< " "
<< message
<< std::endl;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
void Logger::logError(const Parser::Coordinate &coordinate, const std::string &message)
{
if (isatty(STDERR_FILENO))
{
std::cerr
LogStream<StandardStream::Err> stream;
stream
<< Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":"
<< std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":"
<< ResetFormat() << " "
@ -95,18 +87,6 @@ void Logger::logError(const Parser::Coordinate &coordinate, const std::string &m
<< 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;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@ -121,9 +101,9 @@ void Logger::logWarning(const Parser &parser, const std::string &message)
const auto coordinate = parser.coordinate();
if (isatty(STDERR_FILENO))
{
std::cerr
LogStream<StandardStream::Err> stream;
stream
<< Format(Color::White, FontWeight::Bold) << coordinate.sectionName << ":"
<< std::to_string(coordinate.row) + ":" + std::to_string(coordinate.column) << ":"
<< ResetFormat() << " "
@ -131,18 +111,6 @@ void Logger::logWarning(const Parser &parser, const std::string &message)
<< 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;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////