summaryrefslogtreecommitdiff
path: root/src/core/common/Logger.cpp
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-01-01 15:11:17 +0100
committerAndreas Stöckel <andreas@somweyr.de>2015-01-01 15:11:17 +0100
commit5e46e4ebaafff2bb02d595162ded75593cc2ab57 (patch)
tree0640a0cc55e91cdd158ae612f8e7d702188c68ac /src/core/common/Logger.cpp
parent347d5366356f254284f742772095fd4fd1092be8 (diff)
Adapted Logger to new Location classes, now using ContextCallback to retrieve the context for a certain SourceLocation
Diffstat (limited to 'src/core/common/Logger.cpp')
-rw-r--r--src/core/common/Logger.cpp200
1 files changed, 154 insertions, 46 deletions
diff --git a/src/core/common/Logger.cpp b/src/core/common/Logger.cpp
index d8cf5b4..b2c724f 100644
--- a/src/core/common/Logger.cpp
+++ b/src/core/common/Logger.cpp
@@ -25,33 +25,27 @@ namespace ousia {
/* Class Logger */
-void Logger::log(Severity severity, std::string msg, TextCursor::Position pos,
- TextCursor::Context ctx)
+void Logger::log(Severity severity, const std::string &msg,
+ const SourceLocation &loc)
{
- // Update the maximum encountered severity level
- if (static_cast<int>(severity) > static_cast<int>(maxEncounteredSeverity)) {
- maxEncounteredSeverity = severity;
- }
-
- // Only process the message if its severity is larger than the
- // set minimum severity.
- if (static_cast<int>(severity) >= static_cast<int>(minSeverity)) {
- processMessage(
- Message{severity, std::move(msg), std::move(pos), std::move(ctx)});
+ // Assemble the message and pass it through the filter, then process it
+ Message message { severity, std::move(msg), loc };
+ if (filterMessage(message)) {
+ processMessage(message);
}
}
-LoggerFork Logger::fork() { return LoggerFork{this, minSeverity}; }
+LoggerFork Logger::fork() { return LoggerFork(this); }
/* Class LoggerFork */
-void LoggerFork::processMessage(Message msg)
+void LoggerFork::processMessage(const Message &msg)
{
calls.push_back(Call(CallType::MESSAGE, messages.size()));
messages.push_back(msg);
}
-void LoggerFork::processPushFile(File file)
+void LoggerFork::processPushFile(const File &file)
{
calls.push_back(Call(CallType::PUSH_FILE, files.size()));
files.push_back(file);
@@ -62,25 +56,139 @@ void LoggerFork::processPopFile()
calls.push_back(Call(CallType::POP_FILE, 0));
}
+void LoggerFork::processSetDefaultLocation(const SourceLocation &loc)
+{
+ // Check whether setDefaultLocation was called immediately before, if yes,
+ // simply override the data
+ if (!calls.empty() && calls.back().type == CallType::SET_DEFAULT_LOCATION) {
+ locations.back() = loc;
+ } else {
+ calls.push_back(Call(CallType::SET_DEFAULT_LOCATION, locations.size()));
+ locations.push_back(loc);
+ }
+}
+
+void LoggerFork::purge()
+{
+ calls.clear();
+ messages.clear();
+ files.clear();
+ locations.clear();
+}
+
void LoggerFork::commit()
{
for (const Call &call : calls) {
switch (call.type) {
case CallType::MESSAGE: {
- const Message &msg = messages[call.dataIdx];
- parent->log(msg.severity, msg.msg, msg.pos, msg.ctx);
+ if (parent->filterMessage(messages[call.dataIdx])) {
+ parent->processMessage(messages[call.dataIdx]);
+ }
break;
}
case CallType::PUSH_FILE: {
- const File &file = files[call.dataIdx];
- parent->pushFile(file.file, file.pos, file.ctx);
+ parent->processPushFile(files[call.dataIdx]);
break;
}
case CallType::POP_FILE:
- parent->popFile();
+ parent->processPopFile();
break;
+ case CallType::SET_DEFAULT_LOCATION:
+ parent->processSetDefaultLocation(locations[call.dataIdx]);
+ break;
+ }
+ }
+ purge();
+}
+
+/* Class ConcreteLogger */
+
+static const Logger::File EMPTY_FILE{"", SourceLocation{}, nullptr, nullptr};
+
+void ConcreteLogger::processPushFile(const File &file)
+{
+ files.push_back(file);
+}
+
+void ConcreteLogger::processPopFile() { files.pop_back(); }
+
+bool ConcreteLogger::filterMessage(const Message &msg)
+{
+ // Increment the message count for this severity
+ uint8_t sev = static_cast<uint8_t>(msg.severity);
+ if (sev >= messageCounts.size()) {
+ messageCounts.resize(sev + 1);
+ }
+ messageCounts[sev]++;
+
+ // Filter messages with too small severity
+ return sev >= static_cast<uint8_t>(minSeverity);
+}
+
+void ConcreteLogger::processSetDefaultLocation(const SourceLocation &loc)
+{
+ defaultLocation = loc;
+}
+
+const Logger::File &ConcreteLogger::currentFile() const
+{
+ if (!files.empty()) {
+ return files.back();
+ }
+ return EMPTY_FILE;
+}
+
+const std::string &ConcreteLogger::currentFilename() const
+{
+ return currentFile().file;
+}
+
+const SourceLocation &ConcreteLogger::messageLocation(const Message &msg) const
+{
+ if (msg.loc.valid()) {
+ return msg.loc;
+ }
+ return defaultLocation;
+}
+
+SourceContext ConcreteLogger::messageContext(const Message &msg) const
+{
+ const Logger::File &file = currentFile();
+ if (file.ctxCallback) {
+ return file.ctxCallback(messageLocation(msg), file.ctxCallbackData);
+ }
+ return SourceContext{};
+}
+
+Severity ConcreteLogger::getMaxEncounteredSeverity()
+{
+ for (ssize_t i = messageCounts.size() - 1; i >= 0; i--) {
+ if (messageCounts[i] > 0) {
+ return static_cast<Severity>(i);
}
}
+ return Severity::DEBUG;
+}
+
+size_t ConcreteLogger::getSeverityCount(Severity severity)
+{
+ uint8_t sev = static_cast<uint8_t>(severity);
+ if (sev >= messageCounts.size()) {
+ return 0;
+ }
+ return messageCounts[sev];
+}
+
+void ConcreteLogger::reset()
+{
+ files.clear();
+ messageCounts.clear();
+}
+
+bool ConcreteLogger::hasError()
+{
+ return getSeverityCount(Severity::ERROR) > 0 ||
+ getSeverityCount(Severity::FATAL_ERROR) > 0;
}
/* Class Terminal */
@@ -200,38 +308,34 @@ public:
/* Class TerminalLogger */
-std::string TerminalLogger::currentFilename()
-{
- if (!files.empty()) {
- return files.top().file;
- }
- return std::string{};
-}
-
-void TerminalLogger::processMessage(Message msg)
+void TerminalLogger::processMessage(const Message &msg)
{
Terminal t(useColor);
+ // Fetch filename, position and context
+ const std::string filename = currentFilename();
+ const SourceLocation pos = messageLocation(msg);
+ const SourceContext ctx = messageContext(msg);
+
// Print the file name
- std::string filename = currentFilename();
bool hasFile = !filename.empty();
if (hasFile) {
os << t.bright() << filename << t.reset();
}
// Print line and column number
- if (msg.pos.hasLine()) {
+ if (pos.hasLine()) {
if (hasFile) {
os << ':';
}
- os << t.bright() << msg.pos.line << t.reset();
- if (msg.pos.hasColumn()) {
- os << ':' << msg.pos.column;
+ os << t.bright() << pos.line << t.reset();
+ if (pos.hasColumn()) {
+ os << ':' << pos.column;
}
}
// Print the optional seperator
- if (hasFile || msg.pos.hasLine()) {
+ if (hasFile || pos.hasLine()) {
os << ": ";
}
@@ -258,26 +362,30 @@ void TerminalLogger::processMessage(Message msg)
os << msg.msg << std::endl;
// Print the error message context if available
- if (msg.ctx.valid()) {
- size_t relPos = msg.ctx.relPos;
- if (msg.ctx.truncatedStart) {
+ if (ctx.valid()) {
+ size_t relPos = ctx.relPos;
+ if (ctx.truncatedStart) {
os << "[...] ";
- relPos += 6;
}
- os << msg.ctx.text;
- if (msg.ctx.truncatedEnd) {
+ os << ctx.text;
+ if (ctx.truncatedEnd) {
os << " [...]";
}
os << std::endl;
+
+ if (ctx.truncatedStart) {
+ os << " ";
+ }
+
for (size_t i = 0; i < relPos; i++) {
- os << ' ';
+ if (i < ctx.text.size() && ctx.text[i] == '\t') {
+ os << '\t';
+ } else {
+ os << ' ';
+ }
}
os << t.color(Terminal::GREEN) << '^' << t.reset() << std::endl;
}
}
-
-void TerminalLogger::processPushFile(File file) { files.push(file); }
-
-void TerminalLogger::processPopFile() { files.pop(); }
}