summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/common/Logger.cpp168
-rw-r--r--src/core/common/Logger.hpp447
2 files changed, 336 insertions, 279 deletions
diff --git a/src/core/common/Logger.cpp b/src/core/common/Logger.cpp
index fa4b5c8..9f070f9 100644
--- a/src/core/common/Logger.cpp
+++ b/src/core/common/Logger.cpp
@@ -27,10 +27,11 @@ namespace ousia {
/* Class Logger */
void Logger::log(Severity severity, const std::string &msg,
- const SourceLocation &loc)
+ const SourceLocation &loc,
+ MessageMode mode = MessageMode::DEFAULT)
{
// Assemble the message and pass it through the filter, then process it
- Message message { severity, std::move(msg), loc };
+ Message message{severity, std::move(msg), loc, mode};
if (filterMessage(message)) {
processMessage(message);
}
@@ -42,30 +43,37 @@ LoggerFork Logger::fork() { return LoggerFork(this); }
void LoggerFork::processMessage(const Message &msg)
{
- calls.push_back(Call(CallType::MESSAGE, messages.size()));
+ calls.emplace_back(CallType::MESSAGE, messages.size());
messages.push_back(msg);
}
-void LoggerFork::processPushFile(const File &file)
+void LoggerFork::processPushDefaultLocation(const SourceLocation &loc)
{
- calls.push_back(Call(CallType::PUSH_FILE, files.size()));
- files.push_back(file);
+ calls.emplace_back(CallType::PUSH_LOCATION, locations.size());
+ locations.push_back(loc);
}
-void LoggerFork::processPopFile()
+void LoggerFork::processPopDefaultLocation()
{
- calls.push_back(Call(CallType::POP_FILE, 0));
+ calls.emplace_back(CallType::POP_LOCATION, 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;
+ calls.emplace_back(CallType : SET_LOCATION, locations.size());
+ locations.push_back(loc);
+}
+
+void LoggerFork::processSetSourceContextCallback(
+ SourceContextCallback sourceContextCallback)
+{
+ // Check whether setSourceContextCallback was called immediately before,
+ // if yes, simply override the data
+ if (!calls.empty() && calls.back().type == CallType::SET_CONTEXT_CALLBACK) {
+ callbacks.back() = loc;
} else {
- calls.push_back(Call(CallType::SET_DEFAULT_LOCATION, locations.size()));
- locations.push_back(loc);
+ calls.emplace_back(CallType::SET_CONTEXT_CALLBACK, callbacks.size());
+ callbacks.emplace_back(sourceContextCallback);
}
}
@@ -73,45 +81,91 @@ void LoggerFork::purge()
{
calls.clear();
messages.clear();
- files.clear();
locations.clear();
+ callbacks.clear();
}
void LoggerFork::commit()
{
for (const Call &call : calls) {
switch (call.type) {
- case CallType::MESSAGE: {
+ case CallType::MESSAGE:
if (parent->filterMessage(messages[call.dataIdx])) {
parent->processMessage(messages[call.dataIdx]);
}
break;
- }
- case CallType::PUSH_FILE: {
- parent->processPushFile(files[call.dataIdx]);
+ case CallType::PUSH_LOCATION:
+ parent->processPushDefaultLocation(locations[call.dataIdx]);
break;
- }
- case CallType::POP_FILE:
- parent->processPopFile();
+ case CallType::POP_LOCATION:
+ parent->processPopDefaultLocation();
break;
- case CallType::SET_DEFAULT_LOCATION:
+ case CallType::SET_LOCATION:
parent->processSetDefaultLocation(locations[call.dataIdx]);
break;
+ case CallType::SET_CONTEXT_CALLBACK:
+ parent->processSetSourceContextCallback(
+ callbacks[call.dataIdx]);
+ break;
}
}
purge();
}
-/* Class ConcreteLogger */
+/* Class ScopedLogger */
+
+ScopedLogger::ScopedLogger(Logger &parent, SourceLocation loc = SourceLocation{})
+ : Logger(), parent(parent), depth(0)
+{
+ pushDefaultLocation(loc);
+}
+
+ScopedLogger::~ScopedLogger()
+{
+ while (depth > 0) {
+ popDefaultLocation();
+ }
+}
+
+void ScopedLogger::processMessage(const Message &msg)
+{
+ parent.processMessage(msg);
+}
+
+bool ScopedLogger::filterMessage(const Message &msg)
+{
+ return parent.filterMessage(msg);
+}
+
+void ScopedLogger::processPushDefaultLocation(const SourceLocation &loc)
+{
+ parent.processPushDefaultLocation(loc);
+ depth++;
+}
+
+void ScopedLogger::processPopDefaultLocation()
+{
+ depth--;
+ parent.processPopDefaultLocation();
+}
-static const Logger::File EMPTY_FILE{"", SourceLocation{}, nullptr, nullptr};
+void ScopedLogger::processSetDefaultLocation(const SourceLocation &loc)
+{
+ parent.processSetDefaultLocation(loc);
+}
-void ConcreteLogger::processPushFile(const File &file)
+void ScopedLogger::processSetSourceContextCallback(
+ SourceContextCallback sourceContextCallback)
{
- files.push_back(file);
+ parent.processSetContextCallback(sourceContextCallback);
}
-void ConcreteLogger::processPopFile() { files.pop_back(); }
+/* Class ConcreteLogger */
+
+ConcreteLogger(Severity minSeverity = Severity::DEFAULT_MIN_SEVERITY)
+ : minSeverity(minSeverity), sourceContextCallback(NullSourceContextCallback)
+{
+}
bool ConcreteLogger::filterMessage(const Message &msg)
{
@@ -126,40 +180,38 @@ bool ConcreteLogger::filterMessage(const Message &msg)
return sev >= static_cast<uint8_t>(minSeverity);
}
-void ConcreteLogger::processSetDefaultLocation(const SourceLocation &loc)
-{
- defaultLocation = loc;
+void ConcreteLogger::processPushDefaultLocation(const SourceLocation &loc) {
+ locations.emplace_back(loc);
}
-const Logger::File &ConcreteLogger::currentFile() const
-{
- if (!files.empty()) {
- return files.back();
+void ConcreteLogger::processPopDefaultLocation() {
+ if (!locations.empty()) {
+ locations.pop_back();
}
- return EMPTY_FILE;
}
-const std::string &ConcreteLogger::currentFilename() const
+void ConcreteLogger::processSetDefaultLocation(const SourceLocation &loc)
{
- return currentFile().file;
+ if (!locations.empty()) {
+ locations.back() = loc;
+ } else {
+ locations.emplace_back(loc);
+ }
}
const SourceLocation &ConcreteLogger::messageLocation(const Message &msg) const
{
if (msg.loc.valid()) {
return msg.loc;
+ } else if (!locatios.empty()) {
+ return locations.back();
}
- return defaultLocation;
+ return NullSourceLocation;
}
SourceContext ConcreteLogger::messageContext(const Message &msg) const
{
- const Logger::File &file = currentFile();
- const SourceLocation &loc = messageLocation(msg);
- if (file.ctxCallback && loc.valid()) {
- return file.ctxCallback(loc, file.ctxCallbackData);
- }
- return SourceContext{};
+ return sourceContextCallback(messageLocation(msg));
}
Severity ConcreteLogger::getMaxEncounteredSeverity()
@@ -193,6 +245,11 @@ bool ConcreteLogger::hasError()
getSeverityCount(Severity::FATAL_ERROR) > 0;
}
+bool ConcreteLogger::hasFatalError()
+{
+ return getSeverityCount(Severity::FATAL_ERROR) > 0;
+}
+
/* Class TerminalLogger */
void TerminalLogger::processMessage(const Message &msg)
@@ -200,29 +257,26 @@ 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
- bool hasFile = !filename.empty();
- if (hasFile) {
- os << t.bright() << filename << t.reset();
+ if (ctx.hasFile()) {
+ os << t.bright() << ctx.filename << t.reset();
}
// Print line and column number
- if (pos.hasLine()) {
+ if (ctx.hasLine()) {
if (hasFile) {
os << ':';
}
- os << t.bright() << pos.line << t.reset();
- if (pos.hasColumn()) {
- os << ':' << pos.column;
+ os << t.bright() << ctx.startLine << t.reset();
+ if (ctx.hasColumn()) {
+ os << ':' << ctx.startColumn;
}
}
// Print the optional seperator
- if (hasFile || pos.hasLine()) {
+ if (ctx.hasFile() || ctx.hasLine()) {
os << ": ";
}
@@ -249,7 +303,7 @@ void TerminalLogger::processMessage(const Message &msg)
os << msg.msg << std::endl;
// Print the error message context if available
- if (ctx.valid()) {
+/* if (ctx.valid()) {
size_t relPos = ctx.relPos;
if (ctx.truncatedStart) {
os << "[...] ";
@@ -272,7 +326,7 @@ void TerminalLogger::processMessage(const Message &msg)
}
}
os << t.color(Terminal::GREEN) << '^' << t.reset() << std::endl;
- }
+ }*/
}
}
diff --git a/src/core/common/Logger.hpp b/src/core/common/Logger.hpp
index 767d8ab..092bd3a 100644
--- a/src/core/common/Logger.hpp
+++ b/src/core/common/Logger.hpp
@@ -73,6 +73,40 @@ enum class Severity : uint8_t {
FATAL_ERROR = 4
};
+/**
+ * Enum signifying how the message should be displayed. MessageMode constants
+ * can be combined using the bitwise or (|) operator.
+ */
+enum class MessageMode : uint8_t {
+ /**
+ * Default display mode.
+ */
+ DEFAULT = 0,
+
+ /**
+ * Do not display a context.
+ */
+ NO_CONTEXT = 1,
+
+ /**
+ * Do not display a file backtrace.
+ */
+ NO_TRACE = 2
+};
+
+/**
+ * Bitwise or for the MessageMode class.
+ *
+ * @param a is the first MessageMode.
+ * @param b is the second MessageMode.
+ * @return the two message modes combined using bitwise or.
+ */
+inline MessageMode operator|(MessageMode a, MessageMode b)
+{
+ return static_cast<MessageMode>(static_cast<uint8_t>(a) |
+ static_cast<uint8_t>(b));
+}
+
// Forward declaration
class LoggerFork;
class ScopedLogger;
@@ -92,51 +126,6 @@ public:
friend ScopedLogger;
/**
- * Describes a file inclusion.
- */
- struct File {
- /**
- * Current filename.
- */
- std::string file;
-
- /**
- * Location at which the file was included.
- */
- SourceLocation loc;
-
- /**
- * Callback used to retrieve the context for a certain location
- */
- SourceContextCallback ctxCallback;
-
- /**
- * Data to be passed to the callback.
- */
- void *ctxCallbackData;
-
- /**
- * Constructor of the Scope struct.
- *
- * @param type is the type of
- * @param file is the name of the current file.
- * @param loc is the location at which the file was included.
- * @param ctxCallback is the callback function that should be called
- * for looking up the context belonging to a SourceLocation instance.
- * @param ctxCallbackData is additional data that should be passed to
- * the callback function.
- */
- File(std::string file, SourceLocation loc,
- SourceContextCallback ctxCallback, void *ctxCallbackData)
- : file(std::move(file)),
- loc(loc),
- ctxCallback(ctxCallback),
- ctxCallbackData(ctxCallbackData)
- {
- }
- };
-
- /**
* The message struct represents a single log message and all information
* attached to it.
*/
@@ -147,6 +136,11 @@ public:
Severity severity;
/**
+ * Message mode.
+ */
+ MessageMode mode;
+
+ /**
* Actual log message.
*/
std::string msg;
@@ -157,15 +151,51 @@ public:
SourceLocation loc;
/**
+ * Default constructor of the Message struct.
+ */
+ Message() : severity(Severity::DEBUG), mode(MessageMode::DEFAULT) {}
+
+ /**
* Constructor of the Message struct.
*
* @param severity describes the message severity.
+ * @param mode is the mode in which the message should be displayed.
* @param msg contains the actual message.
+ * @param loc is the location at which the message should be displayed.
*/
- Message(Severity severity, std::string msg, const SourceLocation &loc)
- : severity(severity), msg(std::move(msg)), loc(loc){};
+ Message(Severity severity, MessageMode mode, std::string msg,
+ const SourceLocation &loc)
+ : severity(severity), mode(mode), msg(std::move(msg)), loc(loc)
+ {
+ }
};
+ /**
+ * Calls the getLocation function on the given reference.
+ *
+ * @param obj is the object on which the getLocation function should be
+ * called.
+ * @return the SourceLocation returned by the getLocation function.
+ */
+ template <typename T>
+ static SourceLocation location(const T &obj)
+ {
+ return obj.getLocation();
+ }
+
+ /**
+ * Calls the getLocation function on the given pointer.
+ *
+ * @param obj is the object on which the getLocation function should be
+ * called.
+ * @return the SourceLocation returned by the getLocation function.
+ */
+ template <typename T>
+ static SourceLocation location(const T *obj)
+ {
+ return obj->getLocation();
+ }
+
protected:
/**
* Function to be overriden by child classes to actually display or store
@@ -188,24 +218,37 @@ protected:
virtual bool filterMessage(const Message &msg) { return true; }
/**
- * Called whenever a new file is pushed onto the stack.
+ * Called whenever the pushDefaultLocation function is called.
*
- * @param file is the file structure that should be stored on the stack.
+ * @param loc is the default location that should be pushed onto the stack.
*/
- virtual void processPushFile(const File &file) {}
+ virtual void processPushDefaultLocation(const SourceLocation &loc) {}
/**
- * Called whenever a scope is popped from the stack.
+ * Called whenever the popDefaultLocation function is called.
+ *
+ * @param loc is the default location that should be popped from the stack.
*/
- virtual void processPopFile() {}
+ virtual void processPopDefaultLocation() {}
/**
* Called whenever the setDefaultLocation function is called.
*
- * @param loc is the default location that should be set.
+ * @param loc is the default location that shuold replace the current one on
+ * the stack.
*/
virtual void processSetDefaultLocation(const SourceLocation &loc) {}
+ /**
+ * Called whenever the setSourceContextCallback function is called.
+ *
+ * @param sourceContextCallback is the callback function that should be set.
+ */
+ virtual void processSetSourceContextCallback(
+ SourceContextCallback sourceContextCallback)
+ {
+ }
+
public:
/**
* Virtual destructor.
@@ -228,28 +271,25 @@ public:
* @param severity is the severity of the log message.
* @param msg is the actual log message.
* @param loc is the location in the source file the message refers to.
+ * @param mode specifies how the message should be displayed.
*/
void log(Severity severity, const std::string &msg,
- const SourceLocation &loc = SourceLocation{});
+ const SourceLocation &loc = SourceLocation{},
+ MessageMode mode = MessageMode::DEFAULT);
/**
* Logs the given loggable exception.
*
* @param ex is the exception that should be logged.
+ * @param loc is a location which (if valid overrides the location given in
+ * the exception.
+ * @param mode specifies how the message should be displayed.
*/
- void log(const LoggableException &ex)
- {
- log(Severity::ERROR, ex.msg, ex.getLocation());
- }
-
- /**
- * Logs the given loggable exception at the given location.
- *
- * @param ex is the exception that should be logged.
- */
- void log(const LoggableException &ex, const SourceLocation &loc)
+ void log(const LoggableException &ex,
+ const SourceLocation &loc = SourceLocation{},
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::ERROR, ex.msg, loc.valid() ? loc : ex.getLocation());
+ log(Severity::ERROR, ex.msg, loc.isValid() ? loc : ex.getLocation());
}
/**
@@ -260,11 +300,13 @@ public:
* @param msg is the actual log message.
* @param loc is a reference to a variable which provides location
* information.
+ * @param mode specifies how the message should be displayed.
*/
template <class LocationType>
- void log(Severity severity, const std::string &msg, LocationType &loc)
+ void log(Severity severity, const std::string &msg, LocationType loc,
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(severity, msg, loc.getLocation());
+ log(severity, msg, location(loc), mode);
}
/**
@@ -275,10 +317,11 @@ public:
* @param loc is the location in the source file the message refers to.
*/
void debug(const std::string &msg,
- const SourceLocation &loc = SourceLocation{})
+ const SourceLocation &loc = SourceLocation{},
+ MessageMode mode = MessageMode::DEFAULT)
{
#ifndef NDEBUG
- log(Severity::DEBUG, msg, loc);
+ log(Severity::DEBUG, msg, loc, mode);
#endif
}
@@ -291,10 +334,11 @@ public:
* information.
*/
template <class LocationType>
- void debug(const std::string &msg, LocationType &loc)
+ void debug(const std::string &msg, LocationType loc,
+ MessageMode mode = MessageMode::DEFAULT)
{
#ifndef NDEBUG
- log(Severity::DEBUG, msg, loc);
+ log(Severity::DEBUG, msg, loc, mode);
#endif
}
@@ -305,9 +349,10 @@ public:
* @param loc is the location in the source file the message refers to.
*/
void note(const std::string &msg,
- const SourceLocation &loc = SourceLocation{})
+ const SourceLocation &loc = SourceLocation{},
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::NOTE, msg, loc);
+ log(Severity::NOTE, msg, loc, mode);
}
/**
@@ -318,9 +363,10 @@ public:
* information.
*/
template <class LocationType>
- void note(const std::string &msg, LocationType &loc)
+ void note(const std::string &msg, LocationType loc,
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::NOTE, msg, loc);
+ log(Severity::NOTE, msg, loc, mode);
}
/**
@@ -330,9 +376,10 @@ public:
* @param loc is a reference to a variable which provides position
*/
void warning(const std::string &msg,
- const SourceLocation &loc = SourceLocation{})
+ const SourceLocation &loc = SourceLocation{},
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::WARNING, msg, loc);
+ log(Severity::WARNING, msg, loc, mode);
}
/**
@@ -343,9 +390,10 @@ public:
* information.
*/
template <class LocationType>
- void warning(const std::string &msg, LocationType &loc)
+ void warning(const std::string &msg, LocationType loc,
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::WARNING, msg, loc);
+ log(Severity::WARNING, msg, location(loc), mode);
}
/**
@@ -355,9 +403,10 @@ public:
* @param loc is a reference to a variable which provides position
*/
void error(const std::string &msg,
- const SourceLocation &loc = SourceLocation{})
+ const SourceLocation &loc = SourceLocation{},
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::ERROR, msg, std::move(loc));
+ log(Severity::ERROR, msg, loc, mode);
}
/**
@@ -368,9 +417,10 @@ public:
* information.
*/
template <class LocationType>
- void error(const std::string &msg, LocationType &loc)
+ void error(const std::string &msg, LocationType loc,
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::ERROR, msg, loc);
+ log(Severity::ERROR, msg, location(loc), mode);
}
/**
@@ -380,9 +430,10 @@ public:
* @param loc is a reference to a variable which provides position
*/
void fatalError(const std::string &msg,
- const SourceLocation &loc = SourceLocation{})
+ const SourceLocation &loc = SourceLocation{},
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::FATAL_ERROR, msg, loc);
+ log(Severity::FATAL_ERROR, msg, loc, mode);
}
/**
@@ -393,41 +444,44 @@ public:
* information.
*/
template <class LocationType>
- void fatalError(const std::string &msg, LocationType &loc)
+ void fatalError(const std::string &msg, LocationType loc,
+ MessageMode mode = MessageMode::DEFAULT)
{
- log(Severity::FATAL_ERROR, msg, loc);
+ log(Severity::FATAL_ERROR, msg, location(loc), mode);
}
/**
- * Pushes a new file name onto the internal filename stack.
+ * Sets the source context callback to be used to resolve SourceLocation
+ * instances to SourceContext instances. The sourceContextCallback should be
+ * set as early as possible when using the logger.
*
- * @param name is the name of the file to be added to the stack.
- * @param loc is the position from which the new file is included.
- * @param ctxCallback is the callback function that should be called if a
- * SourceLocation needs to be resolved to a SourceContext.
- * @param ctxCallbackData is the data that should be passed to the callback.
+ * @param sourceContextCallback is the new sourceContextCallback to be used.
*/
- void pushFile(std::string name, SourceLocation loc = SourceLocation{},
- SourceContextCallback ctxCallback = nullptr,
- void *ctxCallbackData = nullptr)
+ void setSourceContextCallback(SourceContextCallback sourceContextCallback)
{
- processPushFile(
- File(std::move(name), loc, ctxCallback, ctxCallbackData));
+ processSetSourceContextCallback(sourceContextCallback);
}
/**
- * Pops the filename from the internal filename stack. Resets any location
- * set by the setDefaultLocation() method.
+ * Pushes a new default location onto the default location stack.
+ *
+ * @param loc is the location that should be used if no (valid) location is
+ * specified in the Logger.
*/
- void popFile()
+ void pushDefaultLocation(const SourceLocation &loc)
{
- processPopFile();
- resetDefaultLocation();
+ processPushDefaultLocation(loc);
}
/**
- * Sets the default location. The default location is automatically reset
- * once the popFile() method is called.
+ * Pops the last default location from the default location stack.
+ */
+ void popDefaultLocation() { processPopDefaultLocation(); }
+
+ /**
+ * Replaces the topmost default location on the location stack with the
+ * given location. Creates a new entry in the location stack if the stack
+ * was empty.
*
* @param loc is the location that should be used if no (valid) location is
* specified in the Logger.
@@ -438,12 +492,6 @@ public:
}
/**
- * Resets the default location, a previously set default location will be
- * no longer used.
- */
- void resetDefaultLocation() { processSetDefaultLocation(SourceLocation{}); }
-
- /**
* Returns a forked logger instance which can be used to collect log
* messages for which it is not sure whether they will be used.
*
@@ -469,7 +517,13 @@ private:
/**
* Intanally used to store the incomming function calls.
*/
- enum class CallType { MESSAGE, PUSH_FILE, POP_FILE, SET_DEFAULT_LOCATION };
+ enum class CallType {
+ MESSAGE,
+ PUSH_LOCATION,
+ POP_LOCATION,
+ SET_LOCATION,
+ SET_CONTEXT_CALLBACK
+ };
/**
* Datastructure used to represent a logger function call.
@@ -506,14 +560,14 @@ private:
std::vector<Message> messages;
/**
- * Vector storing all incomming pushed Scope instances.
+ * Vector storing all incomming location instances.
*/
- std::vector<File> files;
+ std::vector<SourceLocation> locations;
/**
- * Vector storing all incomming location instances.
+ * Vector storing all incomming source context callbacks.
*/
- std::vector<SourceLocation> locations;
+ std::vector<SourceContextCallback> callbacks;
/**
* Parent logger instance.
@@ -529,9 +583,11 @@ private:
protected:
void processMessage(const Message &msg) override;
- void processPushFile(const File &file) override;
- void processPopFile() override;
+ void processPushDefaultLocation(const SourceLocation &loc) override;
+ void processPopDefaultLocation() override;
void processSetDefaultLocation(const SourceLocation &loc) override;
+ void processSetSourceContextCallback(
+ SourceContextCallback sourceContextCallback) override;
public:
// Default move constructor
@@ -578,93 +634,54 @@ protected:
*
* @param msg is the message to be relayed to the parent logger.
*/
- void processMessage(const Message &msg) override
- {
- parent.processMessage(msg);
- }
+ void processMessage(const Message &msg) override;
/**
* Relays the filterMessage call to the parent logger.
*
* @param msg is the message to be relayed to the parent logger.
*/
- bool filterMessage(const Message &msg) override
- {
- return parent.filterMessage(msg);
- }
+ bool filterMessage(const Message &msg) override;
/**
- * Relays the processPushFile call to the parent logger and increments the
- * stack depth counter.
- *
- * @param file is the File instance to be relayed to the parent logger.
+ * Relays the processPushDefaultLocation call to the parent logger and
+ * increments the stack depth counter.
*/
- void processPushFile(const File &file)
- {
- parent.processPushFile(file);
- depth++;
- }
+ void processPushDefaultLocation(const SourceLocation &loc) override;
/**
- * Relays the processPopFile call to the parent logger and decrements the
- * stack depth counter.
+ * Relays the processPopDefaultLocation call to the parent logger and
+ * decrements the stack depth counter.
*/
- void processPopFile()
- {
- depth--;
- parent.processPopFile();
- }
+ void processPopDefaultLocation() override;
/**
* Relays the processSetDefaultLocation call to the parent logger.
- *
- * @param loc is the location to be passed to the parent logger.
*/
- void processSetDefaultLocation(const SourceLocation &loc)
- {
- parent.processSetDefaultLocation(loc);
- }
+ void processSetDefaultLocation(const SourceLocation &loc) override;
-public:
/**
- * Constructor of the ScopedLogger class.
- *
- * @param parent is the parent logger instance to which all calls should
- * be relayed.
+ * Relays the processSetSourceContextCallback call to the parent logger.
*/
- ScopedLogger(Logger &parent) : Logger(), parent(parent) {}
+ void processSetSourceContextCallback(
+ SourceContextCallback sourceContextCallback) override;
+public:
/**
* Constructor of the ScopedLogger class, pushes a first file instance onto
* the file stack.
*
* @param parent is the parent logger instance to which all calls should
* be relayed.
- * @param name is the name of the file to be added to the stack.
- * @param loc is the position from which the new file is included.
- * @param ctxCallback is the callback function that should be called if a
- * SourceLocation needs to be resolved to a SourceContext.
- * @param ctxCallbackData is the data that should be passed to the callback.
- */
- ScopedLogger(Logger &parent, std::string name,
- SourceLocation loc = SourceLocation{},
- SourceContextCallback ctxCallback = nullptr,
- void *ctxCallbackData = nullptr)
- : Logger(), parent(parent), depth(0)
- {
- pushFile(name, loc, ctxCallback, ctxCallbackData);
- }
+ * @param loc specifies the first source location.
+ */
+ ScopedLogger(Logger &parent, SourceLocation loc = SourceLocation{});
/**
* Destructor of the ScopedLogger class, automatically unwinds the file
* stack.
*/
- ~ScopedLogger()
- {
- while (depth > 0) {
- processPopFile();
- }
- }
+ ~ScopedLogger();
};
/**
@@ -681,7 +698,7 @@ protected:
{
if (msg.severity == Severity::ERROR ||
msg.severity == Severity::FATAL_ERROR) {
- throw LoggableException(msg.msg);
+ throw LoggableException(msg.msg, msg.loc);
}
}
};
@@ -701,9 +718,9 @@ constexpr Severity DEFAULT_MIN_SEVERITY = Severity::DEBUG;
class ConcreteLogger : public Logger {
private:
/**
- * Stack containing the current file instance.
+ * Current source context callback.
*/
- std::vector<File> files;
+ SourceContextCallback sourceContextCallback;
/**
* Vector used to store the counts of each message type.
@@ -711,14 +728,19 @@ private:
std::vector<size_t> messageCounts;
/**
+ * Vector used to store the current default locations.
+ */
+ std::vector<SourceLocation> locations;
+
+ /**
* Minimum severity to be used for filtering messages.
*/
Severity minSeverity;
/**
- * Current default location.
+ * Current source context callback.
*/
- SourceLocation defaultLocation;
+ SourceContextCallback callback;
protected:
/**
@@ -730,25 +752,11 @@ protected:
*/
bool filterMessage(const Message &msg) override;
- /**
- * Pushes the given file descriptor onto the internal file stack.
- *
- * @param file is the File descriptor to be pushed onto the internal file
- * stack.
- */
- void processPushFile(const File &file) override;
-
- /**
- * Pops the given file descriptor from the internal file stack.
- */
- void processPopFile() override;
-
- /**
- * Sets the default location.
- *
- * @param loc is the new default location.
- */
+ void processPushDefaultLocation(const SourceLocation &loc) override;
+ void processPopDefaultLocation() override;
void processSetDefaultLocation(const SourceLocation &loc) override;
+ void processSetSourceContextCallback(
+ SourceContextCallback sourceContextCallback) override;
public:
/**
@@ -757,24 +765,7 @@ public:
* @param minSeverity is the severity below which message should be
* discarded.
*/
- ConcreteLogger(Severity minSeverity = DEFAULT_MIN_SEVERITY)
- : minSeverity(minSeverity)
- {
- }
-
- /**
- * Returns the name of the current file or an empty instance of the File
- * instance if no current file is available.
- *
- * @return the name of the current file.
- */
- const File &currentFile() const;
-
- /**
- * Returns the current filename or an empty string if no surch file is
- * available.
- */
- const std::string &currentFilename() const;
+ ConcreteLogger(Severity minSeverity = Severity::DEFAULT_MIN_SEVERITY);
/**
* Returns the current cursor location.
@@ -800,7 +791,8 @@ public:
/**
* Returns the number of messages for the given severity.
*
- * @param severity is the log severity for which the message count should
+ * @param severity is the log severity for which the message count
+ *should
* be returned.
* @return the number of messages for this severity. Returns zero for
* invalid arguments.
@@ -808,22 +800,32 @@ public:
size_t getSeverityCount(Severity severity);
/**
- * Resets the statistics gathered by the ConcreteLogger instance (the number
+ * Resets the statistics gathered by the ConcreteLogger instance (the
+ * number
* of messages per log severity) and the internal file stack.
*/
void reset();
/**
- * Returns true if at least one message with either a fatal error or error
- * severity was logged.
+ * Returns true if at least one message with either a fatal error or
+ * error severity was logged.
*
* @return true if an error or fatal error was logged.
*/
bool hasError();
+
+ /**
+ * Returns true if at least one message with either a fatal error was
+ * logged.
+ *
+ * @return true if a fatal error was logged.
+ */
+ bool hasFatalError();
};
/**
- * Class extending the Logger class and printing the log messages to the given
+ * Class extending the Logger class and printing the log messages to the
+ * given
* stream.
*/
class TerminalLogger : public ConcreteLogger {
@@ -850,7 +852,8 @@ public:
* 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
+ * @param minSeverity is the minimum severity below which log messages
+ *are
* discarded.
*/
TerminalLogger(std::ostream &os, bool useColor = false,