From 99c6f5df144d0530fe43225d353dee881cfdf26a Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Sat, 24 Jan 2015 13:23:55 +0100 Subject: Moved Terminal and TerminalLogger to own classes in new frontent folder --- src/core/frontend/TerminalLogger.cpp | 151 +++++++++++++++++++++++++++++++++++ 1 file changed, 151 insertions(+) create mode 100644 src/core/frontend/TerminalLogger.cpp (limited to 'src/core/frontend/TerminalLogger.cpp') 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 . +*/ + +#include + +#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 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; + } + } +} + +} + -- cgit v1.2.3 From 2e8432a2fd10f4cf5519628c7ab6e7c6e270ca15 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Sat, 24 Jan 2015 14:24:19 +0100 Subject: Vastly improved terminal logger context output routine (code is still and will forever be a mess, but it is PREEEEETYYYY!) --- src/core/frontend/TerminalLogger.cpp | 60 ++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'src/core/frontend/TerminalLogger.cpp') diff --git a/src/core/frontend/TerminalLogger.cpp b/src/core/frontend/TerminalLogger.cpp index fdb7c8f..3bead06 100644 --- a/src/core/frontend/TerminalLogger.cpp +++ b/src/core/frontend/TerminalLogger.cpp @@ -93,18 +93,27 @@ void TerminalLogger::processMessage(const Message &msg) // Indicate truncation and indent non-first lines if (ctx.truncatedStart && firstLine) { - os << "[...] "; + os << t.italic() << "[...] " << t.reset(); } if (!firstLine) { os << "\t"; } - // Print the actual line - os << lines[n]; + // Print the actual line, replace tabs + for (char c: lines[n]) { + if (c == '\t') { + os << " "; + } else { + os << c; + } + } + if (!lastLine) { + os << t.color(Terminal::BLACK) << "¶" << t.reset(); + } // Indicate truncation if (ctx.truncatedEnd && lastLine) { - os << " [...]"; + os << t.italic() << " [...]" << t.reset(); } os << std::endl; @@ -118,31 +127,48 @@ void TerminalLogger::processMessage(const Message &msg) // Print the position indicators lend = lastLine ? pend : lstart + lines[n].size(); - for (size_t i = lstart; i < lend; i++) { + bool inRegion = false; + for (size_t i = lstart; i < lend + 1; i++) { if (i >= pstart && i < pend) { - os << t.color(Terminal::GREEN); - for (; i < std::min(lend, pend); i++) { + if (!inRegion) { + os << t.color(Terminal::GREEN); + inRegion = true; + } + } else { + if (inRegion) { + os << t.reset(); + inRegion = false; + } + } + char c = i < ctx.text.size() ? ctx.text[i] : ' '; + if (c == '\t') { + if (inRegion) { if (relLen == 1) { - os << '^'; + os << "^ "; } else { - os << '~'; - } - if (i < ctx.text.size() && ctx.text[i] == '\t') { - os << '\t'; + os << "~~~~"; } + } else { + os << " "; } - os << t.reset(); } else { - if (i < ctx.text.size() && ctx.text[i] == '\t') { - os << '\t'; + if (inRegion) { + if (relLen == 1) { + os << "^"; + } else { + os << "~"; + } } else { - os << ' '; + os << " "; } } } + if (inRegion) { + os << t.reset(); + } os << std::endl; - lstart = lend; + lstart = lend + 1; // skip newline } } } -- cgit v1.2.3