Skip to content

Commit

Permalink
Merge branch 'rewrite'
Browse files Browse the repository at this point in the history
  • Loading branch information
evan1026 committed Feb 5, 2017
2 parents 643e53c + bd11513 commit 0a5a228
Show file tree
Hide file tree
Showing 8 changed files with 344 additions and 414 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
build/*
*.swp
test.out
17 changes: 0 additions & 17 deletions CMakeLists.txt

This file was deleted.

13 changes: 13 additions & 0 deletions GlobalLogger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#ifndef GLOBAL_LOGGER_HPP
#define GLOBAL_LOGGER_HPP

#include "Logger.hpp"

// This file defines a global logger that anyone can use
// Include it in all the files you need and they'll share a logger

namespace Logger {
extern Logger globalLogger;
}

#endif
15 changes: 15 additions & 0 deletions Logger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "Logger.hpp"
#include "GlobalLogger.hpp"

namespace Logger {
namespace Levels {
/*! Level representing messages meant to inform */
Level Info ("[INFO] ", Color::NoColor);
/*! Level representing messages meant to warn */
Level Warning("[WARN] ", Color::Yellow);
/*! Level representing messages displaying an error */
Level Error ("[ERROR] ", Color::Red);
}
/*! Logger that is defined globally by default to make it easy to use across files */
Logger globalLogger;
}
273 changes: 273 additions & 0 deletions Logger.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,273 @@
#ifndef LOGGER_HPP
#define LOGGER_HPP

#if defined(linux) || defined(__linux) || defined(__linux__) || defined(Macintosh) || defined(macintosh) || (defined(__APPLE__) && defined(__MACH__))
#define COLOR_SUPPORT
#endif

#include <iostream>
#include <vector>
#include <memory>
#include <sstream>

/*!
* Container namspace for everything having to do with the logger
*/
namespace Logger {

/*!
* Namespace containing predefined colors. You can make your own too, but these are provided.
*
* Note that because of the way doxygen parses files, it will display the empty string versions
* of these colors (for when color is not supported) even if colors are supported on your system.
*/
namespace Color {
#ifdef COLOR_SUPPORT
/*! String corresponding to the unix code for black */
const std::string Black = "\e[30m";
/*! String corresponding to the unix code for red */
const std::string Red = "\e[31m";
/*! String corresponding to the unix code for green */
const std::string Green = "\e[32m";
/*! String corresponding to the unix code for yellow */
const std::string Yellow = "\e[33m";
/*! String corresponding to the unix code for blue */
const std::string Blue = "\e[34m";
/*! String corresponding to the unix code for magenta */
const std::string Magenta = "\e[35m";
/*! String corresponding to the unix code for cyan */
const std::string Cyan = "\e[36m";
/*! String corresponding to the unix code for white */
const std::string White = "\e[37m";
/*! String corresponding to the unix code for the default color */
const std::string NoColor = "\e[0m";
#else
/*! Empty string since color isn't supported */
const std::string Black = "";
/*! Empty string since color isn't supported */
const std::string Red = "";
/*! Empty string since color isn't supported */
const std::string Green = "";
/*! Empty string since color isn't supported */
const std::string Yellow = "";
/*! Empty string since color isn't supported */
const std::string Blue = "";
/*! Empty string since color isn't supported */
const std::string Magenta = "";
/*! Empty string since color isn't supported */
const std::string Cyan = "";
/*! Empty string since color isn't supported */
const std::string White = "";
/*! Empty string since color isn't supported */
const std::string NoColor = "";
#endif
};

/*!
* Simple data container for logging levels which are represented as a prefix and a color.
*
* So, for instance, the warning built-in level is ("[WARN] ", Color::Yellow). This means
* that every message with the waning level will be displayed in yellow (if supported) and
* with have the prefix "[WARN] " before the line.
*/
struct Level {
/*! The string representing the prefix to put before the line when logging with this level */
std::string prefix;
/*! The string representing the color to make the line if colors are being used */
std::string color;

/*! \callergraph
*
* Constructs a new level
*
* \p p - Prefix string <br>
* \p c - Color string <br>
*/
Level(std::string p, std::string c) : prefix(p), color(c) {}
};

/*!
* Namespace containing the built-in levels
*/
namespace Levels {
extern Logger::Level Info;
extern Logger::Level Warning;
extern Logger::Level Error;
};

/*!
* Logger class
*
* TODO better documentation
*/
class Logger {

struct Stream {
std::shared_ptr<std::ostream> s;
bool c;
};

std::vector<Stream> outStreams;

void makeString(std::stringstream& ss, const Level& l) {
ss << l.prefix;
}

template <typename T>
void makeString(std::stringstream& ss, const T& t) {
ss << t;
}

template <typename T, typename... Ts>
void makeString(std::stringstream& ss, const T& t, const Ts&... ts) {
makeString(ss, t);
makeString(ss, ts...);
}

template <typename... Ts>
std::string makeString(const Ts&... ts) {
std::stringstream ss;
makeString(ss, ts...);
return ss.str();
}

public:

/*! \callergraph
*
* Constructs a new logger
*
* \p o - std::ostream to print the data to <br>
* \p color - Whether or not to print colors with the data <br>
*/
Logger(std::ostream& o, bool color) {
addStream(o, color);
}

/*! \callergraph
*
* Default constructor which creates a logger that logs to std::cout with color
*/
Logger() : Logger(std::cout, true) {}

/*! \callergraph
*
* Adds a new std::ostream to the logger, so that you can output to multiple
* streams at the same time
*
* \p o - std::ostream to print the data to <br>
* \p color - Whether or not to print colors with the data <br>
*/
void addStream(std::ostream& o, bool color) {
Stream s;
s.s = std::shared_ptr<std::ostream>(&o, [](std::ostream*){});
s.c = color;

outStreams.push_back(s);
}

/*! \callergraph
*
* Prints stuff to the output. Takes an arbitrary number of arguments and
* prints them each to the output stream. Accepts any type of arguments
* as long as they have a << operator defined.
*
* Example usage:
* logger.print(Levels::Info, "These ", "will ", "be ", "one ", "message.");
*
* \p l - Level to use for this line <br>
* \p args - Stuff to print <br>
*/
template <typename... Args>
void print(const Level& l, const Args&... args) {
std::string line = makeString(l, args...);
for (auto _stream : outStreams) {
if (_stream.c) {
*_stream.s << l.color;
}
*_stream.s << line;
}
}

/*! \callergraph
*
* See docs for the other version of print()
*
* This version doesn't output anything having to do with the level,
* so if no newline was used on the last call of print(), this version
* can be used to continue writing to the line.
*/
template <typename... Args>
void print(const Args&... args) {
std::string line = makeString(args...);
for (auto _stream : outStreams) {
*_stream.s << line;
}
}

/*! \callergraph
*
* Like print(), but inserts a newline afterward.
*
* Since this version takes care of colors as well, it should
* be preferred over print().
*/
template <typename... Args>
void println(const Args&... args) {
print(args...);
for (auto _stream : outStreams) {
*_stream.s << std::endl;
if (_stream.c) {
*_stream.s << Color::NoColor;
}
}
}

/*! \callergraph
*
* Calls println() with Levels::Info and whatever you send it
*/
template <typename... Args>
void log(const Args&... args) {
println(Levels::Info, args...);
}

/*! \callergraph
*
* Same as log()
*/
template <typename... Args>
void info(const Args&... args) {
println(Levels::Info, args...);
}

/*! \callergraph
*
* Calls println() with Levels::Warning and whatever you send it
*/
template <typename... Args>
void warn(const Args&... args) {
println(Levels::Warning, args...);
}

/*! \callergraph
*
* Same as warn()
*/
template <typename... Args>
void warning(const Args&... args) {
println(Levels::Warning, args...);
}

/*! \callergraph
*
* Calls println() with Levels::Error and whatever you send it
*/
template <typename... Args>
void error(const Args&... args) {
println(Levels::Error, args...);
}
};
};

#endif
Loading

0 comments on commit 0a5a228

Please sign in to comment.