diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-23 12:09:14 +0100 |
---|---|---|
committer | Andreas Stöckel <andreas@somweyr.de> | 2015-01-23 12:09:14 +0100 |
commit | a7e40c1f1572b05e9608e0ed43ac54c1f7e7d84b (patch) | |
tree | 90883fc212a5aae73563c965fb89a5ae2a227d0d /src/core | |
parent | 7610f2d1bc6c7b263ef41e765d571ac460709a7e (diff) |
Adapted Logger class
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/common/Logger.cpp | 168 | ||||
-rw-r--r-- | src/core/common/Logger.hpp | 447 |
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 ¤tFile() const; - - /** - * Returns the current filename or an empty string if no surch file is - * available. - */ - const std::string ¤tFilename() 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, |