diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-24 13:23:55 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-24 13:23:55 +0100 |
commit | 99c6f5df144d0530fe43225d353dee881cfdf26a (patch) | |
tree | a9a7499dda7d643861c753855823ed0f71aa8021 /src/core/frontend | |
parent | 67d36e699a2852ce471c4d1b8dab5992d6c01a98 (diff) |
Moved Terminal and TerminalLogger to own classes in new frontent folder
Diffstat (limited to 'src/core/frontend')
-rw-r--r-- | src/core/frontend/Terminal.cpp | 58 | ||||
-rw-r--r-- | src/core/frontend/Terminal.hpp | 124 | ||||
-rw-r--r-- | src/core/frontend/TerminalLogger.cpp | 151 | ||||
-rw-r--r-- | src/core/frontend/TerminalLogger.hpp | 79 |
4 files changed, 412 insertions, 0 deletions
diff --git a/src/core/frontend/Terminal.cpp b/src/core/frontend/Terminal.cpp new file mode 100644 index 0000000..447e595 --- /dev/null +++ b/src/core/frontend/Terminal.cpp @@ -0,0 +1,58 @@ +/* + Ousía + Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <sstream> + +#include "Terminal.hpp" + +namespace ousia { + +std::string Terminal::color(int color, bool bright) const +{ + if (!useColor) { + return std::string{}; + } + std::stringstream ss; + ss << "\x1b["; + if (bright) { + ss << "1;"; + } + ss << color << "m"; + return ss.str(); +} + +std::string Terminal::bright() const +{ + if (!useColor) { + return std::string{}; + } + std::stringstream ss; + ss << "\x1b[1m"; + return ss.str(); +} + +std::string Terminal::reset() const +{ + if (!useColor) { + return std::string{}; + } + return "\x1b[0m"; +} + +} + diff --git a/src/core/frontend/Terminal.hpp b/src/core/frontend/Terminal.hpp new file mode 100644 index 0000000..730853d --- /dev/null +++ b/src/core/frontend/Terminal.hpp @@ -0,0 +1,124 @@ +/* + Ousía + Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/** + * @file Terminal.hpp + * + * Classes for printing colored output to a terminal. + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_TERMINAL_HPP_ +#define _OUSIA_TERMINAL_HPP_ + +#include <string> + +namespace ousia { + +/** + * The Terminal class contains some helper functions used to interact with the + * terminal as used for colorful output when logging error messages. + * + * TODO: Disable on Windows or use corresponding API-functions for setting the + * color. + * TODO: Give output stream to terminal/use terminal as output stream + */ +class Terminal { +private: + /** + * If set to false, no control codes are generated. + */ + bool useColor; + +public: + /** + * ANSI color code for black. + */ + static const int BLACK = 30; + + /** + * ANSI color code for red. + */ + static const int RED = 31; + + /** + * ANSI color code for green. + */ + static const int GREEN = 32; + + /** + * ANSI color code for yellow. + */ + static const int YELLOW = 33; + + /** + * ANSI color code for blue. + */ + static const int BLUE = 34; + + /** + * ANSI color code for magenta. + */ + static const int MAGENTA = 35; + + /** + * ANSI color code for cyan. + */ + static const int CYAN = 36; + + /** + * ANSI color code for white. + */ + static const int WHITE = 37; + + /** + * Creates a new instance of the Terminal class. + * + * @param useColor specifies whether color codes should be generated. + */ + Terminal(bool useColor) : useColor(useColor) {} + + /** + * Returns a control string for switching to the given color. + * + * @param color is the color the terminal should switch to. + * @param bright specifies whether the terminal should switch to the bright + * mode. + * @return a control string to be included in the output stream. + */ + std::string color(int color, bool bright = true) const; + + /** + * Returns a control string for switching to the bright mode. + * + * @return a control string to be included in the output stream. + */ + std::string bright() const; + + /** + * Returns a control string for switching to the default mode. + * + * @return a control string to be included in the output stream. + */ + std::string reset() const; +}; +} + +#endif /* _OUSIA_TERMINAL_HPP_ */ + diff --git a/src/core/frontend/TerminalLogger.cpp b/src/core/frontend/TerminalLogger.cpp new file mode 100644 index 0000000..fdb7c8f --- /dev/null +++ b/src/core/frontend/TerminalLogger.cpp @@ -0,0 +1,151 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <core/common/Utils.hpp> + +#include "Terminal.hpp" +#include "TerminalLogger.hpp" + +namespace ousia { + +/* Class TerminalLogger */ + +void TerminalLogger::processMessage(const Message &msg) +{ + Terminal t(useColor); + + // Fetch filename, position and context + const SourceContext ctx = messageContext(msg); + + // Print the file name + if (ctx.hasFile()) { + os << t.bright() << ctx.filename << t.reset(); + } + + // Print line and column number + if (ctx.hasLine()) { + if (ctx.hasFile()) { + os << ':'; + } + os << t.bright() << ctx.startLine << t.reset(); + if (ctx.hasColumn()) { + os << ':' << ctx.startColumn; + } + } + + // Print the optional seperator + if (ctx.hasFile() || ctx.hasLine()) { + os << ": "; + } + + // Print the severity + switch (msg.severity) { + case Severity::DEBUG: + break; + case Severity::NOTE: + os << t.color(Terminal::CYAN, true) << "note: "; + break; + case Severity::WARNING: + os << t.color(Terminal::MAGENTA, true) << "warning: "; + break; + case Severity::ERROR: + os << t.color(Terminal::RED, true) << "error: "; + break; + case Severity::FATAL_ERROR: + os << t.color(Terminal::RED, true) << "fatal error: "; + break; + } + os << t.reset(); + + // Print the actual message + os << msg.msg << std::endl; + + // Print the error message context if available + if (ctx.hasText()) { + // Iterate over each line in the text + std::vector<std::string> lines = Utils::split(ctx.text, '\n'); + + const size_t relLen = ctx.relLen ? ctx.relLen : 1; + const size_t relPos = ctx.relPos; + const size_t pstart = relPos; + const size_t pend = relPos + relLen; + + size_t lstart = 0; + size_t lend = 0; + for (size_t n = 0; n < lines.size(); n++) { + bool firstLine = n == 0; + bool lastLine = n == lines.size() - 1; + + // Indicate truncation and indent non-first lines + if (ctx.truncatedStart && firstLine) { + os << "[...] "; + } + if (!firstLine) { + os << "\t"; + } + + // Print the actual line + os << lines[n]; + + // Indicate truncation + if (ctx.truncatedEnd && lastLine) { + os << " [...]"; + } + os << std::endl; + + // Repeat truncation or indendation space in the next line + if (ctx.truncatedStart && firstLine) { + os << " "; + } + if (!firstLine) { + os << "\t"; + } + + // Print the position indicators + lend = lastLine ? pend : lstart + lines[n].size(); + for (size_t i = lstart; i < lend; i++) { + if (i >= pstart && i < pend) { + os << t.color(Terminal::GREEN); + for (; i < std::min(lend, pend); i++) { + if (relLen == 1) { + os << '^'; + } else { + os << '~'; + } + if (i < ctx.text.size() && ctx.text[i] == '\t') { + os << '\t'; + } + } + os << t.reset(); + } else { + if (i < ctx.text.size() && ctx.text[i] == '\t') { + os << '\t'; + } else { + os << ' '; + } + } + } + os << std::endl; + + lstart = lend; + } + } +} + +} + diff --git a/src/core/frontend/TerminalLogger.hpp b/src/core/frontend/TerminalLogger.hpp new file mode 100644 index 0000000..03930e9 --- /dev/null +++ b/src/core/frontend/TerminalLogger.hpp @@ -0,0 +1,79 @@ +/* + Ousía + Copyright (C) 2014, 2015 Benjamin Paaßen, Andreas Stöckel + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/** + * @file TerminalLogger.hpp + * + * Provides the TerminalLogger class, which is used to log messages to an output + * stream, possibly a Terminal. + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ + +#ifndef _OUSIA_TERMINAL_LOGGER_HPP_ +#define _OUSIA_TERMINAL_LOGGER_HPP_ + +#include <ostream> + +#include <core/common/Logger.hpp> + +namespace ousia { + +/** + * Class extending the Logger class and printing (possibly colored) log messages + * to the given stream. + */ +class TerminalLogger : public ConcreteLogger { +private: + /** + * Reference to the target output stream. + */ + std::ostream &os; + + /** + * If true, the TerminalLogger will use colors to make the log messages + * prettier. + */ + bool useColor; + +protected: + void processMessage(const Message &msg) override; + +public: + /** + * Constructor of the TerminalLogger class. + * + * @param os is the output stream the log messages should be logged to. + * Should be set to std::cerr in most cases. + * @param useColor if true, the TerminalLogger class will do its best to + * use ANSI/VT100 control sequences for colored log messages. + * @param minSeverity is the minimum severity below which log messages + * are discarded. + */ + TerminalLogger(std::ostream &os, bool useColor = false, + Severity minSeverity = DEFAULT_MIN_SEVERITY) + : ConcreteLogger(minSeverity), os(os), useColor(useColor) + { + } +}; + +} + +#endif /* _OUSIA_TERMINAL_LOGGER_HPP_ */ + + |