Started implementing improved output utilities.

This commit is contained in:
2016-11-24 00:21:01 +01:00
parent 5019922488
commit e6a9ee1cc7
7 changed files with 793 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
#ifndef __ANTHEM__OUTPUT__LOCATION_H
#define __ANTHEM__OUTPUT__LOCATION_H
namespace anthem
{
namespace input
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Location
//
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Location
{
const char *sectionStart = nullptr;
const char *sectionEnd = nullptr;
int rowStart = -1;
int rowEnd = -1;
int columnStart = -1;
int columnEnd = -1;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@@ -0,0 +1,294 @@
#ifndef __ANTHEM__OUTPUT__COLOR_STREAM_H
#define __ANTHEM__OUTPUT__COLOR_STREAM_H
#include <iostream>
#include <unistd.h>
namespace anthem
{
namespace output
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ColorStream
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class ColorStream
{
public:
enum class ColorPolicy
{
Never,
Auto,
Always
};
private:
using CharacterType = std::ostream::char_type;
using TraitsType = std::ostream::traits_type;
public:
ColorStream(std::ostream &stream)
: m_stream{stream},
m_colorPolicy{ColorPolicy::Auto}
{
}
void setColorPolicy(ColorPolicy colorPolicy)
{
m_colorPolicy = colorPolicy;
}
bool supportsColor() const
{
if (m_colorPolicy == ColorPolicy::Never)
return false;
if (m_colorPolicy == ColorPolicy::Always)
return true;
if (&m_stream == &std::cout)
return isatty(fileno(stdin));
if (&m_stream == &std::cerr)
return isatty(fileno(stderr));
return false;
}
std::ostream &stream()
{
return m_stream;
}
inline ColorStream &operator<<(short value);
inline ColorStream &operator<<(unsigned short value);
inline ColorStream &operator<<(int value);
inline ColorStream &operator<<(unsigned int value);
inline ColorStream &operator<<(long value);
inline ColorStream &operator<<(unsigned long value);
inline ColorStream &operator<<(long long value);
inline ColorStream &operator<<(unsigned long long value);
inline ColorStream &operator<<(float value);
inline ColorStream &operator<<(double value);
inline ColorStream &operator<<(long double value);
inline ColorStream &operator<<(bool value);
inline ColorStream &operator<<(const void *value);
inline ColorStream &operator<<(const char *value);
inline ColorStream &operator<<(const signed char *value);
inline ColorStream &operator<<(const unsigned char *value);
inline ColorStream &operator<<(std::basic_streambuf<CharacterType, TraitsType> *sb);
inline ColorStream &operator<<(std::ios_base &(*func)(std::ios_base &));
inline ColorStream &operator<<(std::basic_ios<CharacterType, TraitsType> &(*func)(std::basic_ios<CharacterType, TraitsType> &));
inline ColorStream &operator<<(std::basic_ostream<CharacterType, TraitsType> &(*func)(std::basic_ostream<CharacterType, TraitsType> &));
inline ColorStream &operator<<(char value);
inline ColorStream &operator<<(signed char value);
inline ColorStream &operator<<(unsigned char value);
private:
std::ostream &m_stream;
ColorPolicy m_colorPolicy;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(short value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(unsigned short value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(int value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(unsigned int value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(long value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(unsigned long value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(long long value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(unsigned long long value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(float value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(double value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(long double value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(bool value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(const void *value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(const char *value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(const signed char *value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(const unsigned char *value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(std::basic_streambuf<CharacterType, TraitsType>* sb)
{
m_stream << sb;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(std::ios_base &(*func)(std::ios_base &))
{
m_stream << func;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(std::basic_ios<CharacterType, TraitsType> &(*func)(std::basic_ios<CharacterType, TraitsType> &))
{
m_stream << func;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(std::basic_ostream<CharacterType, TraitsType> &(*func)(std::basic_ostream<CharacterType, TraitsType> &))
{
m_stream << func;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
template<class CharacterType, class Traits, class Allocator>
inline ColorStream &operator<<(ColorStream &colorStream, const std::basic_string<CharacterType, Traits, Allocator> &string)
{
colorStream.stream() << string;
return colorStream;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(char value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(signed char value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
ColorStream &ColorStream::operator<<(unsigned char value)
{
m_stream << value;
return *this;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@@ -0,0 +1,244 @@
#ifndef __ANTHEM_OUTPUT__FORMATTING_H
#define __ANTHEM_OUTPUT__FORMATTING_H
#include <iostream>
#include <anthem/output/ColorStream.h>
namespace anthem
{
namespace output
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Formatting
//
////////////////////////////////////////////////////////////////////////////////////////////////////
enum class Color
{
Default = 39,
Black = 30,
Red = 31,
Green = 32,
Yellow = 33,
Blue = 34,
Magenta = 35,
Cyan = 36,
LightGray = 37,
DarkGray = 90,
LightRed = 91,
LightGreen = 92,
LightYellow = 93,
LightBlue = 94,
LightMagenta = 95,
LightCyan = 96,
White = 97
};
////////////////////////////////////////////////////////////////////////////////////////////////////
enum class FontWeight
{
Normal = 21,
Bold = 1
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Format
{
Color color = Color::Default;
FontWeight fontWeight = FontWeight::Normal;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Format &format)
{
if (!stream.supportsColor())
return stream;
const auto fontWeightCode = static_cast<int>(format.fontWeight);
const auto colorCode = static_cast<int>(format.color);
return (stream << "\033[" << fontWeightCode << ";" << colorCode << "m");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct ResetFormat
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const ResetFormat &)
{
if (!stream.supportsColor())
return stream;
return (stream << "\033[0m");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Token
{
const char *name;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Function: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Function &function)
{
return (stream
<< Format({Color::White, FontWeight::Bold})
<< function.name
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Keyword: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Keyword &keyword)
{
return (stream
<< Format({Color::Blue, FontWeight::Normal})
<< keyword.name
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Number: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Number &number)
{
return (stream
<< Format({Color::Yellow, FontWeight::Normal})
<< number.name
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Variable: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Variable &variable)
{
return (stream
<< Format({Color::Green, FontWeight::Bold})
<< variable.name
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct String: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const String &string)
{
return (stream
<< Format({Color::Green, FontWeight::Normal})
<< "\"" << string.name << "\""
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Boolean: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Boolean &boolean)
{
return (stream
<< Format({Color::Red, FontWeight::Normal})
<< boolean.name
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Reserved: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Reserved &reserved)
{
return (stream
<< Format({Color::White, FontWeight::Normal})
<< reserved.name
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Heading1: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Heading1 &heading1)
{
return (stream
<< Format({Color::Blue, FontWeight::Bold})
<< "%---------------------------------------" << std::endl
<< "% " << heading1.name << std::endl
<< "%---------------------------------------"
<< ResetFormat()
<< std::endl);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
struct Heading2: public Token
{
};
////////////////////////////////////////////////////////////////////////////////////////////////////
inline ColorStream &operator<<(ColorStream &stream, const Heading2 &heading2)
{
return (stream
<< Format({Color::Blue, FontWeight::Bold})
<< "% " << heading2.name
<< ResetFormat());
}
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@@ -0,0 +1,54 @@
#ifndef __ANTHEM__OUTPUT__LOGGER_H
#define __ANTHEM__OUTPUT__LOGGER_H
#include <string>
#include <anthem/input/Location.h>
#include <anthem/output/ColorStream.h>
#include <anthem/output/Priority.h>
namespace anthem
{
namespace output
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Logger
//
////////////////////////////////////////////////////////////////////////////////////////////////////
class Logger
{
public:
Logger();
Logger(const Logger &other) = default;
Logger &operator=(const Logger &other) = default;
Logger(Logger &&other) = default;
Logger &operator=(Logger &&other) = default;
ColorStream &outputStream();
ColorStream &errorStream();
// The level from which on messages should be printed
void setOutputPriority(Priority outputLevel);
void setColorPolicy(ColorStream::ColorPolicy colorPolicy);
void log(Priority priority, const char *message);
void log(Priority priority, const input::Location &location, const char *message);
private:
ColorStream m_outputStream;
ColorStream m_errorStream;
Priority m_outputPriority;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif

View File

@@ -0,0 +1,28 @@
#ifndef __ANTHEM__OUTPUT__PRIORITY_H
#define __ANTHEM__OUTPUT__PRIORITY_H
namespace anthem
{
namespace output
{
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Priority
//
////////////////////////////////////////////////////////////////////////////////////////////////////
enum class Priority
{
Debug,
Note,
Warning,
Error
};
////////////////////////////////////////////////////////////////////////////////////////////////////
}
}
#endif