summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-11 21:46:11 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2014-12-11 21:46:11 +0100
commit741463dd18efd8d126bcc70224025703858fdef7 (patch)
tree82f83172a3229f14957b6c3f90fd10180c6b2612
parent3f62168ed0b088eec3cb2903f03966f7d501f564 (diff)
refactored logger
-rw-r--r--src/core/common/CharReader.cpp6
-rw-r--r--src/core/common/CharReader.hpp86
-rw-r--r--src/core/common/Exceptions.cpp18
-rw-r--r--src/core/common/Exceptions.hpp77
-rw-r--r--src/core/common/Logger.cpp114
-rw-r--r--src/core/common/Logger.hpp465
-rw-r--r--src/core/common/TextCursor.hpp168
-rw-r--r--src/core/common/VariantReader.cpp18
-rw-r--r--src/plugins/xml/XmlParser.cpp10
-rw-r--r--test/core/common/CharReaderTest.cpp44
-rw-r--r--test/core/common/LoggerTest.cpp48
-rw-r--r--test/plugins/xml/XmlParserTest.cpp2
12 files changed, 557 insertions, 499 deletions
diff --git a/src/core/common/CharReader.cpp b/src/core/common/CharReader.cpp
index 373c0c1..4bd81ed 100644
--- a/src/core/common/CharReader.cpp
+++ b/src/core/common/CharReader.cpp
@@ -83,7 +83,7 @@ Buffer::Buffer(const std::string &str)
Buffer::~Buffer()
{
// Make sure all cursors have been deleted
- for (bool cursor_alive: alive) {
+ for (bool cursor_alive : alive) {
assert(!cursor_alive);
}
}
@@ -516,7 +516,7 @@ CharReaderFork CharReader::fork()
return CharReaderFork(buffer, readCursor, peekCursor, coherent);
}
-CharReader::Context CharReader::getContext(ssize_t maxSize)
+TextCursor::Context CharReader::getContext(ssize_t maxSize)
{
// Clone the current read cursor
Buffer::CursorId cur = buffer->createCursor(readCursor.cursor);
@@ -612,7 +612,7 @@ CharReader::Context CharReader::getContext(ssize_t maxSize)
// Delete the newly created cursor
buffer->deleteCursor(cur);
- return CharReader::Context{ss.str(), relPos, !foundBegin || tStart != start,
+ return TextCursor::Context{ss.str(), relPos, !foundBegin || tStart != start,
!foundEnd || tEnd != end};
}
diff --git a/src/core/common/CharReader.hpp b/src/core/common/CharReader.hpp
index 3cbe4b4..7be5e08 100644
--- a/src/core/common/CharReader.hpp
+++ b/src/core/common/CharReader.hpp
@@ -32,6 +32,8 @@
#include <memory>
#include <vector>
+#include "TextCursor.hpp"
+
namespace ousia {
/**
@@ -359,52 +361,6 @@ class CharReaderFork;
* of linebreaks and converts these to a single '\n'.
*/
class CharReader {
-public:
- /**
- * The context struct is used to represent the current context the char
- * reader is in. This context can for example be used when building error
- * messages.
- */
- struct Context {
- /**
- * Set to the content of the current line.
- */
- std::string line;
-
- /**
- * Relative position (in characters) within that line.
- */
- size_t relPos;
-
- /**
- * Set to true if the beginning of the line has been truncated (because
- * the reader position is too far away from the actual position of the
- * line).
- */
- bool truncatedStart;
-
- /**
- * Set to true if the end of the line has been truncated (because the
- * reader position is too far away from the actual end position of the
- * line.
- */
- bool truncatedEnd;
-
- Context()
- : line(), relPos(0), truncatedStart(false), truncatedEnd(false)
- {
- }
-
- Context(std::string line, size_t relPos, bool truncatedStart,
- bool truncatedEnd)
- : line(std::move(line)),
- relPos(relPos),
- truncatedStart(truncatedStart),
- truncatedEnd(truncatedEnd)
- {
- }
- };
-
protected:
/**
* Internally used cursor structure for managing the read and the peek
@@ -419,19 +375,20 @@ protected:
/**
* Current line the cursor is in.
*/
- uint32_t line;
+ TextCursor::PosType line;
/**
* Current column the cursor is in.
*/
- uint32_t column;
+ TextCursor::PosType column;
/**
* Constructor of the Cursor class.
*
* @param cursor is the underlying cursor in the Buffer instance.
*/
- Cursor(Buffer::CursorId cursor, size_t line, size_t column)
+ Cursor(Buffer::CursorId cursor, TextCursor::PosType line,
+ TextCursor::PosType column)
: cursor(cursor), line(line), column(column)
{
}
@@ -591,31 +548,35 @@ public:
bool atEnd() const { return buffer->atEnd(readCursor.cursor); }
/**
- * Returns the current line (starting with one).
- *
- * @return the current line number.
+ * Returns the offset of the read cursor in bytes.
*/
- uint32_t getLine() const { return readCursor.line; }
+ size_t getOffset() const { return buffer->offset(readCursor.cursor); }
/**
- * Returns the current column (starting with one).
- *
- * @return the current column number.
+ * Returns the line number the read cursor currently is at.
*/
- uint32_t getColumn() const { return readCursor.column; }
+ TextCursor::PosType getLine() const { return readCursor.line; }
/**
- * Returns the current byte offset of the read cursor.
- *
- * @return the byte position within the stream.
+ * Returns the column the read cursor currently is at.
*/
- size_t getOffset() const { return buffer->offset(readCursor.cursor); };
+ TextCursor::PosType getColumn() const { return readCursor.column; }
+
+ /**
+ * Returns the current position of the read cursor (line and column).
+ */
+ TextCursor::Position getPosition() const
+ {
+ return TextCursor::Position(getLine(), getColumn(), getOffset());
+ }
/**
* Returns the line the read cursor currently is in, but at most the
* given number of characters in the form of a Context structure.
+ *
+ * @param maxSize is the maximum length of the extracted context
*/
- Context getContext(ssize_t maxSize);
+ TextCursor::Context getContext(ssize_t maxSize = 60);
};
/**
@@ -658,7 +619,6 @@ public:
*/
void commit();
};
-
}
#endif /* _OUSIA_CHAR_READER_HPP_ */
diff --git a/src/core/common/Exceptions.cpp b/src/core/common/Exceptions.cpp
index d064f35..30c5626 100644
--- a/src/core/common/Exceptions.cpp
+++ b/src/core/common/Exceptions.cpp
@@ -25,21 +25,21 @@ namespace ousia {
/* Class LoggableException */
std::string LoggableException::formatMessage(const std::string &msg,
- const std::string &file,
- int line, int column)
+ const TextCursor::Position &pos,
+ const TextCursor::Context &ctx)
{
std::stringstream ss;
ss << "error ";
- if (!file.empty()) {
- ss << "while processing \"" << file << "\" ";
- }
- if (line >= 0) {
- ss << "at line " << line << ", ";
- if (column >= 0) {
- ss << "column " << column << " ";
+ if (pos.hasLine()) {
+ ss << "at line " << pos.line << ", ";
+ if (pos.hasColumn()) {
+ ss << "column " << pos.column << " ";
}
}
ss << "with message: " << msg;
+ if (ctx.valid()) {
+ ss << " in context \"" << ctx.text << "\"";
+ }
return ss.str();
}
}
diff --git a/src/core/common/Exceptions.hpp b/src/core/common/Exceptions.hpp
index 00d6106..443c176 100644
--- a/src/core/common/Exceptions.hpp
+++ b/src/core/common/Exceptions.hpp
@@ -27,6 +27,8 @@
#ifndef _OUSIA_EXCEPTIONS_HPP_
#define _OUSIA_EXCEPTIONS_HPP_
+#include "TextCursor.hpp"
+
namespace ousia {
/**
@@ -81,80 +83,81 @@ private:
* reported to the runtime environment.
*/
static std::string formatMessage(const std::string &msg,
- const std::string &file, int line,
- int column);
+ const TextCursor::Position &pos,
+ const TextCursor::Context &ctx);
public:
/**
- * Message describing the error that occured.
+ * Reported error message.
*/
const std::string msg;
/**
- * Name of the file in which the error occured. May be empty.
+ * Position in the document at which the exception occurred.
*/
- const std::string file;
+ const TextCursor::Position pos;
/**
- * Line at which the exception occured. Negative values are ignored.
+ * Context in the document text in which the exception occurred.
*/
- const int line;
-
- /**
- * Column at which the exception occured. Negative values are ignored.
- */
- const int column;
+ const TextCursor::Context ctx;
/**
* Constructor of the LoggableException class.
*
* @param msg contains the error message.
- * @param file provides the context the message refers to. May be empty.
- * @param line is the line in the above file the message refers to.
- * @param column is the column in the above file the message refers to.
+ * @param pos is the position at which the error occured.
+ * @param ctx describes the context in which the error occured.
*/
- LoggableException(std::string msg, std::string file, int line = -1,
- int column = -1)
- : OusiaException(formatMessage(msg, file, line, column)),
+ LoggableException(std::string msg,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
+ : OusiaException(formatMessage(msg, pos, ctx)),
msg(std::move(msg)),
- file(std::move(file)),
- line(line),
- column(column)
+ pos(std::move(pos)),
+ ctx(std::move(ctx))
{
}
/**
- * Constructor of the LoggableException class with empty file.
+ * Constructor of the LoggableException class.
*
* @param msg contains the error message.
* @param line is the line in the above file the message refers to.
* @param column is the column in the above file the message refers to.
+ * @param offs is the byte offset.
*/
- LoggableException(std::string msg, int line = -1, int column = -1)
- : OusiaException(formatMessage(msg, "", line, column)),
- msg(std::move(msg)),
- line(line),
- column(column)
+ LoggableException(std::string msg, TextCursor::PosType line,
+ TextCursor::PosType column, size_t offs)
+ : LoggableException(msg, TextCursor::Position(line, column, offs))
{
}
/**
- * Constructor of the LoggableException class with empty file and an
- * position object.
+ * Constructor of LoggableException for arbitrary position objects.
*
* @param msg is the actual log message.
- * @param pos is a const reference to a variable which provides position
- * information.
+ * @param pos is a reference to a variable with position and context data.
*/
template <class PosType>
- LoggableException(std::string msg, const PosType &pos)
- : OusiaException(
- formatMessage(msg, "", pos.getLine(), pos.getColumn())),
- msg(std::move(msg)),
- line(pos.getLine()),
- column(pos.getColumn())
+ LoggableException(std::string msg, PosType &pos)
+ : LoggableException(std::move(msg), pos.getPosition(), pos.getContext())
{
}
+
+ /**
+ * Returns the position at which the exception occured in the text.
+ *
+ * @return the position descriptor.
+ */
+ TextCursor::Position getPosition() const { return pos; }
+
+ /**
+ * Returns the context in which the exception occured in the text.
+ *
+ * @return the context descriptor.
+ */
+ TextCursor::Context getContext() const { return ctx; }
};
}
diff --git a/src/core/common/Logger.cpp b/src/core/common/Logger.cpp
index 17f55a6..913594f 100644
--- a/src/core/common/Logger.cpp
+++ b/src/core/common/Logger.cpp
@@ -23,50 +23,8 @@
namespace ousia {
-/* Class Logger */
+/* Class Terminal */
-void Logger::log(Severity severity, const std::string &msg,
- const std::string &file, int line, int column)
-{
- // Copy the current severity level
- if (static_cast<int>(severity) > static_cast<int>(maxEncounteredSeverity)) {
- maxEncounteredSeverity = severity;
- }
-
- // Call the actual log message function if the severity is larger or equal
- // to the minimum severity
- if (static_cast<int>(severity) >= static_cast<int>(minSeverity)) {
- process(Message{severity, msg, file, line, column});
- }
-}
-
-unsigned int Logger::pushFilename(const std::string &name)
-{
- filenameStack.push(name);
- return filenameStack.size();
-}
-
-unsigned int Logger::popFilename()
-{
- filenameStack.pop();
- return filenameStack.size();
-}
-
-void Logger::unwindFilenameStack(unsigned int pos)
-{
- while (filenameStack.size() > pos && !filenameStack.empty()) {
- filenameStack.pop();
- }
-}
-
-/* Class TerminalLogger */
-
-/**
- * Small class used internally for formated terminal output using ANSI/VT100
- * escape codes on supported terminals.
- *
- * TODO: Deactivate if using windows or use the corresponding API function.
- */
class Terminal {
private:
/**
@@ -109,29 +67,49 @@ public:
}
};
-void TerminalLogger::process(const Message &msg)
+
+/* Class TerminalLogger */
+
+/**
+ * Small class used internally for formated terminal output using ANSI/VT100
+ * escape codes on supported terminals.
+ *
+ * TODO: Deactivate if using windows or use the corresponding API function.
+ */
+
+std::string TerminalLogger::currentFilename()
+{
+ if (!files.empty()) {
+ return files.top().file;
+ }
+ return std::string{};
+}
+
+void TerminalLogger::processMessage(Message msg)
{
Terminal t(useColor);
// Print the file name
- if (msg.hasFile()) {
- os << t.color(Terminal::WHITE, true) << msg.file << t.reset();
+ std::string filename = currentFilename();
+ bool hasFile = !filename.empty();
+ if (hasFile) {
+ os << t.color(Terminal::WHITE, true) << filename << t.reset();
}
// Print line and column number
- if (msg.hasLine()) {
- if (msg.hasFile()) {
+ if (msg.pos.hasLine()) {
+ if (hasFile) {
os << ':';
}
- os << t.color(Terminal::WHITE, true) << msg.line
+ os << t.color(Terminal::WHITE, true) << msg.pos.line
<< t.reset();
- if (msg.hasColumn()) {
- os << ':' << msg.column;
+ if (msg.pos.hasColumn()) {
+ os << ':' << msg.pos.column;
}
}
// Print the optional seperator
- if (msg.hasFile() || msg.hasLine()) {
+ if (hasFile || msg.pos.hasLine()) {
os << ": ";
}
@@ -156,6 +134,38 @@ void TerminalLogger::process(const Message &msg)
// Print the actual message
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) {
+ os << "[...] ";
+ relPos += 6;
+ }
+ os << msg.ctx.text;
+ if (msg.ctx.truncatedEnd) {
+ os << " [...]";
+ }
+ os << std::endl;
+ for (size_t i = 0; i < relPos; i++) {
+ os << ' ';
+ }
+ os << t.color(Terminal::GREEN) << '^' << t.reset() << std::endl;
+ }
+}
+
+size_t TerminalLogger::processPushFile(File file)
+{
+ files.push(file);
+ return files.size();
+}
+
+size_t TerminalLogger::processPopFile()
+{
+ files.pop();
+ return files.size();
}
+
+
}
diff --git a/src/core/common/Logger.hpp b/src/core/common/Logger.hpp
index e6b97f4..6366f9a 100644
--- a/src/core/common/Logger.hpp
+++ b/src/core/common/Logger.hpp
@@ -35,6 +35,7 @@
#include <vector>
#include "Exceptions.hpp"
+#include "TextCursor.hpp"
namespace ousia {
@@ -90,6 +91,40 @@ static constexpr Severity DEFAULT_MIN_SEVERITY = Severity::DEBUG;
class Logger {
public:
/**
+ * Describes an included file.
+ */
+ struct File {
+ /**
+ * Is the name of the file.
+ */
+ std::string file;
+
+ /**
+ * Position at which the file was included.
+ */
+ TextCursor::Position pos;
+
+ /**
+ * Context in which the file was included.
+ */
+ TextCursor::Context ctx;
+
+ /**
+ * Constructor of the File struct.
+ *
+ * @param file is the name of the included file.
+ * @param pos is the position in the parent file, at which this file
+ * was included.
+ * @param ctx is the context in which the feil was included.
+ */
+ File(std::string file, TextCursor::Position pos,
+ TextCursor::Context ctx)
+ : file(file), pos(pos), ctx(ctx)
+ {
+ }
+ };
+
+ /**
* The message struct represents a single log message and all information
* attached to it.
*/
@@ -105,80 +140,42 @@ public:
std::string msg;
/**
- * Refers to the file which provides the context for this error message.
- * May be empty.
+ * Position in the text the message refers to.
*/
- std::string file;
+ TextCursor::Position pos;
/**
- * Line in the above file the error message refers to. Ignored if
- * smaller than zero.
+ * Context the message refers to.
*/
- int line;
-
- /**
- * Column in the above file the error message refers to. Ignored if
- * smaller than zero.
- */
- int column;
+ TextCursor::Context ctx;
/**
* Constructor of the Message struct.
*
* @param severity describes the message severity.
* @param msg contains the actual message.
- * @param file provides the context the message refers to. May be empty.
* @param line is the line in the above file the message refers to.
* @param column is the column in the above file the message refers to.
*/
- Message(Severity severity, std::string msg, std::string file, int line,
- int column)
+ Message(Severity severity, std::string msg, TextCursor::Position pos,
+ TextCursor::Context ctx)
: severity(severity),
msg(std::move(msg)),
- file(std::move(file)),
- line(line),
- column(column){};
-
- /**
- * Returns true if the file string is set.
- *
- * @return true if the file string is set.
- */
- bool hasFile() const { return !file.empty(); }
-
- /**
- * Returns true if the line is set.
- *
- * @return true if the line number is a non-negative integer.
- */
- bool hasLine() const { return line >= 0; }
-
- /**
- * Returns true if column and line are set (since a column has no
- * significance without a line number).
- *
- * @return true if line number and column number are non-negative
- * integers.
- */
- bool hasColumn() const { return hasLine() && column >= 0; }
+ pos(std::move(pos)),
+ ctx(std::move(ctx)){};
};
private:
/**
* Minimum severity a log message should have before it is discarded.
*/
- Severity minSeverity;
+ const Severity minSeverity;
/**
* Maximum encountered log message severity.
*/
Severity maxEncounteredSeverity;
- /**
- * Stack containing the current file names that have been processed.
- */
- std::stack<std::string> filenameStack;
-
protected:
/**
* Function to be overriden by child classes to actually display or store
@@ -188,7 +185,23 @@ protected:
* @param msg is an instance of the Message struct containing the data that
* should be logged.
*/
- virtual void process(const Message &msg){};
+ virtual void processMessage(Message msg) {}
+
+ /**
+ * Called whenever a new file is pushed onto the stack.
+ *
+ * @param file is the file that should be pushed onto the stack.
+ * @return the stack depth after the file has been pushed.
+ */
+ virtual size_t processPushFile(File file) { return 0; }
+
+ /**
+ * Called whenever a file is popped from the stack.
+ *
+ * @return the stack depth after the current file has been removed from the
+ * stack.
+ */
+ virtual size_t processPopFile() { return 0; }
public:
/**
@@ -210,51 +223,30 @@ public:
virtual ~Logger(){};
/**
- * Logs the given message. Most generic log function.
- *
- * @param severity is the severity of the log message.
- * @param msg is the actual log message.
- * @param file is the name of the file the message refers to. May be empty.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
- */
- void log(Severity severity, const std::string &msg, const std::string &file,
- int line = -1, int column = -1);
-
- /**
* Logs the given message. The file name is set to the topmost file name on
* the file name stack.
*
* @param severity is the severity of the log message.
* @param msg is the actual log message.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
+ * @param pos is the position the log message refers to.
+ * @param ctx describes the context of the log message.
*/
- void log(Severity severity, const std::string &msg, int line = -1,
- int column = -1)
+ void log(Severity severity, std::string msg,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
{
- log(severity, msg, currentFilename(), line, column);
- }
-
- /**
- * Logs the given message. The file name is set to the topmost file name on
- * the file name stack.
- *
- * @param severity is the severity of the log message.
- * @param msg is the actual log message.
- * @param pos is a const reference to a variable which provides position
- * information.
- * @tparam PosType is the actual type of pos and must implement a getLine
- * and getColumn function.
- */
- template <class PosType>
- void logAt(Severity severity, const std::string &msg, const PosType &pos)
- {
- log(severity, msg, pos.getLine(), pos.getColumn());
+ // 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)});
+ }
}
/**
@@ -264,278 +256,188 @@ public:
*/
void log(const LoggableException &ex)
{
- log(Severity::ERROR, ex.msg,
- ex.file.empty() ? currentFilename() : ex.file, ex.line, ex.column);
- }
-
- /**
- * Logs a debug message. The file name is set to the topmost file name on
- * the file name stack.
- *
- * @param msg is the actual log message.
- * @param file is the name of the file the message refers to. May be empty.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
- */
- void debug(const std::string &msg, const std::string &file, int line = -1,
- int column = -1)
- {
- log(Severity::DEBUG, msg, file, line, column);
- }
-
- /**
- * Logs a debug message. The file name is set to the topmost file name on
- * the file name stack.
- *
- * @param msg is the actual log message.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
- */
- void debug(const std::string &msg, int line = -1, int column = -1)
- {
- debug(msg, currentFilename(), line, column);
+ log(Severity::ERROR, ex.msg, ex.getPosition(), ex.getContext());
}
/**
- * Logs a debug message. The file name is set to the topmost file name on
+ * Logs the given message. The file name is set to the topmost file name on
* the file name stack.
*
* @param severity is the severity of the log message.
* @param msg is the actual log message.
- * @param pos is a const reference to a variable which provides position
- * information.
+ * @param pos is a reference to a variable which provides position and
+ * context information.
*/
template <class PosType>
- void debugAt(const std::string &msg, const PosType &pos)
+ void logAt(Severity severity, std::string msg, PosType &pos)
{
- debug(msg, pos.getLine(), pos.getColumn());
+ log(severity, std::move(msg), pos.getPosition(), pos.getContext());
}
/**
- * Logs a note. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a debug message. Debug messages will be discarded if the software
+ * is compiled in the release mode (with the NDEBUG flag).
*
* @param msg is the actual log message.
- * @param file is the name of the file the message refers to. May be empty.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
- */
- void note(const std::string &msg, const std::string &file, int line = -1,
- int column = -1)
+ * @param pos describes the position of the debug message.
+ * @param ctx describes the context of the debug message.
+ */
+ void debug(std::string msg,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
{
- log(Severity::NOTE, msg, file, line, column);
+#ifndef NDEBUG
+ log(Severity::DEBUG, std::move(msg), std::move(pos), std::move(ctx));
+#endif
}
/**
- * Logs a note. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a debug message. Debug messages will be discarded if the software
+ * is compiled in the release mode.
*
* @param msg is the actual log message.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
+ * @param pos is a reference to a variable which provides position and
+ * context information.
*/
- void note(const std::string &msg, int line = -1, int column = -1)
+ template<class PosType>
+ void debug(std::string msg, PosType &pos)
{
- note(msg, currentFilename(), line, column);
+#ifndef NDEBUG
+ logAt(Severity::DEBUG, std::move(msg), pos);
+#endif
}
/**
- * Logs a note. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a note.
*
* @param msg is the actual log message.
- * @param pos is a const reference to a variable which provides position
- * information.
+ * @param pos describes the position of the note.
+ * @param ctx describes the context of the note.
*/
- template <class PosType>
- void noteAt(const std::string &msg, const PosType &pos)
+ void note(std::string msg,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
{
- note(msg, pos.getLine(), pos.getColumn());
+ log(Severity::NOTE, std::move(msg), std::move(pos), std::move(ctx));
}
/**
- * Logs a warning. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a note.
*
* @param msg is the actual log message.
- * @param file is the name of the file the message refers to. May be empty.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
- */
- void warning(const std::string &msg, const std::string &file, int line = -1,
- int column = -1)
+ * @param pos is a reference to a variable which provides position and
+ * context information.
+ */
+ template<class PosType>
+ void note(std::string msg, PosType &pos)
{
- log(Severity::WARNING, msg, file, line, column);
+ logAt(Severity::NOTE, std::move(msg), pos);
}
/**
- * Logs a warning. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a warning.
*
* @param msg is the actual log message.
- * @param pos is a const reference to a variable which provides position
- * information.
+ * @param pos describes the position of the warning.
+ * @param ctx describes the context of the warning.
*/
- template <class PosType>
- void warningAt(const std::string &msg, const PosType &pos)
+ void warning(std::string msg,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
{
- warning(msg, pos.getLine(), pos.getColumn());
+ log(Severity::WARNING, std::move(msg), std::move(pos), std::move(ctx));
}
/**
- * Logs a warning. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a warning.
*
* @param msg is the actual log message.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
+ * @param pos is a reference to a variable which provides position and
+ * context information.
*/
- void warning(const std::string &msg, int line = -1, int column = -1)
+ template<class PosType>
+ void warning(std::string msg, PosType &pos)
{
- warning(msg, currentFilename(), line, column);
+ logAt(Severity::WARNING, std::move(msg), pos);
}
/**
- * Logs an error message. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs an error message.
*
* @param msg is the actual log message.
- * @param file is the name of the file the message refers to. May be empty.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
- */
- void error(const std::string &msg, const std::string &file, int line = -1,
- int column = -1)
+ * @param pos is the position at which the error occured.
+ * @param ctx describes the context in which the error occured.
+ */
+ void error(std::string msg,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
{
- log(Severity::ERROR, msg, file, line, column);
+ log(Severity::ERROR, std::move(msg), std::move(pos), std::move(ctx));
}
/**
- * Logs an error message. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs an error message.
*
* @param msg is the actual log message.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
+ * @param pos is a reference to a variable which provides position and
+ * context information.
*/
- void error(const std::string &msg, int line = -1, int column = -1)
+ template<class PosType>
+ void error(std::string msg, PosType &pos)
{
- error(msg, currentFilename(), line, column);
+ logAt(Severity::ERROR, std::move(msg), pos);
}
/**
- * Logs an error message. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a fatal error message.
*
* @param msg is the actual log message.
- * @param pos is a const reference to a variable which provides position
- * information.
+ * @param pos is the position at which the error occured.
+ * @param ctx describes the context in which the error occured.
*/
- template <class PosType>
- void errorAt(const std::string &msg, const PosType &pos)
+ void fatalError(std::string msg,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
{
- error(msg, pos.getLine(), pos.getColumn());
+ log(Severity::FATAL_ERROR, std::move(msg), std::move(pos),
+ std::move(ctx));
}
- /**
- * Logs a fatal error. The file name is set to the topmost file name on
- * the file name stack.
- *
- * @param msg is the actual log message.
- * @param file is the name of the file the message refers to. May be empty.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
- */
- void fatalError(const std::string &msg, const std::string &file,
- int line = -1, int column = -1)
- {
- log(Severity::FATAL_ERROR, msg, file, line, column);
- }
/**
- * Logs a fatal error. The file name is set to the topmost file name on
- * the file name stack.
+ * Logs a fatal error message.
*
* @param msg is the actual log message.
- * @param line is the line in the above file at which the error occured.
- * Ignored if negative.
- * @param column is the column in the above file at which the error occured.
- * Ignored if negative.
+ * @param pos is a reference to a variable which provides position and
+ * context information.
*/
- void fatalError(const std::string &msg, int line = -1, int column = -1)
+ template<class PosType>
+ void fatalError(std::string msg, PosType &pos)
{
- fatalError(msg, currentFilename(), line, column);
+ logAt(Severity::FATAL_ERROR, std::move(msg), pos);
}
/**
- * Logs a fatal error. The file name is set to the topmost file name on
- * the file name stack.
+ * Pushes a new file name onto the internal filename stack.
*
- * @param msg is the actual log message.
- * @param pos is a const reference to a variable which provides position
- * information.
+ * @param name is the name of the file to be added to the stack.
+ * @param pos is the position from which the new file is included.
+ * @param ctx is the context in which the new file is included.
*/
- template <class PosType>
- void fatalErrorAt(const std::string &msg, const PosType &pos)
+ size_t pushFile(std::string name,
+ TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
{
- fatalError(msg, pos.getLine(), pos.getColumn());
+ return processPushFile(
+ File(std::move(name), std::move(pos), std::move(ctx)));
}
/**
- * Pushes a new file name onto the internal filename stack.
- *
- * @param name is the name of the file that should be added to the filename
- * stack.
- * @return the size of the filename stack. This number can be passed to the
- * "unwindFilenameStack" method in order to return the stack to state it was
- * in after this function has been called.
- */
- unsigned int pushFilename(const std::string &name);
-
- /**
* Pops the filename from the internal filename stack.
*
* @return the current size of the filename stack.
*/
- unsigned int popFilename();
-
- /**
- * Pops elements from the filename stack while it has more elements than
- * the given number and the stack is non-empty.
- *
- * @param pos is the position the filename stack should be unwound to. Use
- * a number returned by pushFilename.
- */
- void unwindFilenameStack(unsigned int pos);
-
- /**
- * Returns the topmost filename from the internal filename stack.
- *
- * @return the topmost filename from the filename stack or an empty string
- * if the filename stack is empty.
- */
- std::string currentFilename()
- {
- return filenameStack.empty() ? std::string{} : filenameStack.top();
- }
+ size_t popFile() { return processPopFile(); }
/**
* Returns the maximum severity that was encountered by the Logger but at
@@ -553,14 +455,6 @@ public:
* @return the minimum severity.
*/
Severity getMinSeverity() { return minSeverity; }
-
- /**
- * Sets the minimum severity. Messages with a smaller severity will be
- * discarded. Only new messages will be filtered according to the new value.
- *
- * @param severity is the minimum severity for new log messages.
- */
- void setMinSeverity(Severity severity) { minSeverity = severity; }
};
/**
@@ -580,11 +474,20 @@ private:
*/
bool useColor;
-protected:
/**
- * Implements the process function and logs the messages to the output.
+ * Stack used to keep the file references.
*/
- void process(const Message &msg) override;
+ std::stack<File> files;
+
+ /**
+ * The size of the stack the last time a file backtrace was printed.
+ */
+ size_t lastFilePrinted = 0;
+
+protected:
+ void processMessage(Message msg) override;
+ size_t processPushFile(File file) override;
+ size_t processPopFile() override;
public:
/**
@@ -602,6 +505,12 @@ public:
: Logger(minSeverity), os(os), useColor(useColor)
{
}
+
+ /**
+ * Returns the name of the topmost file.
+ */
+ std::string currentFilename();
+
};
}
diff --git a/src/core/common/TextCursor.hpp b/src/core/common/TextCursor.hpp
new file mode 100644
index 0000000..2633345
--- /dev/null
+++ b/src/core/common/TextCursor.hpp
@@ -0,0 +1,168 @@
+/*
+ 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/>.
+*/
+
+#ifndef _OUSIA_TEXT_CURSOR_HPP_
+#define _OUSIA_TEXT_CURSOR_HPP_
+
+namespace ousia {
+namespace TextCursor {
+
+/**
+ * Type used for representing line or column positions.
+ */
+using PosType = unsigned int;
+
+/**
+ * Struct representing a position within the text. A position is defined by a
+ * byte offset (which is always reproducable), a line number and a column
+ * number.
+ */
+struct Position {
+ /**
+ * Current line, starting with one.
+ */
+ PosType line;
+
+ /**
+ * Current column, starting with one.
+ */
+ PosType column;
+
+ /**
+ * Current byte offset.
+ */
+ size_t offs;
+
+ /**
+ * Default constructor of the Position struct, initializes all memebers
+ * with zero.
+ */
+ Position() : line(0), column(0), offs(0) {}
+
+ /**
+ * Creates a new Position struct with only a line and no column.
+ *
+ * @param line is the line number.
+ * @param column is the column number.
+ */
+ Position(PosType line) : line(line), column(0), offs(0) {}
+
+ /**
+ * Creates a new Position struct with a line and column.
+ *
+ * @param line is the line number.
+ * @param column is the column number.
+ */
+ Position(PosType line, PosType column) : line(line), column(column), offs(0)
+ {
+ }
+
+ /**
+ * Creates a new Position struct with a line, column and byte offset.
+ *
+ * @param line is the line number.
+ * @param column is the column number.
+ * @param offs is the byte offset.
+ */
+ Position(PosType line, PosType column, size_t offs)
+ : line(line), column(column), offs(offs)
+ {
+ }
+
+ /**
+ * Returns true, if the line number is valid, false otherwise.
+ *
+ * @return true for valid line numbers.
+ */
+ bool hasLine() const { return line > 0; }
+
+ /**
+ * Returns true, if the column number is valid, false otherwise.
+ *
+ * @return true for valid column numbers.
+ */
+ bool hasColumn() const { return column > 0; }
+};
+
+/**
+ * Represents the current context a CharReader is in. Used for building error
+ * messages.
+ */
+struct Context {
+ /**
+ * Set to the content of the current line.
+ */
+ std::string text;
+
+ /**
+ * Relative position (in characters) within that line. May point to
+ * locations beyond the text content.
+ */
+ PosType relPos;
+
+ /**
+ * Set to true if the beginning of the line has been truncated (because
+ * the reader position is too far away from the actual position of the
+ * line).
+ */
+ bool truncatedStart;
+
+ /**
+ * Set to true if the end of the line has been truncated (because the
+ * reader position is too far away from the actual end position of the
+ * line.
+ */
+ bool truncatedEnd;
+
+ /**
+ * Default constructor, initializes all members with zero values.
+ */
+ Context() : text(), relPos(0), truncatedStart(false), truncatedEnd(false) {}
+
+ /**
+ * Constructor of the Context class.
+ *
+ * @param text is the current line the text cursor is at.
+ * @param relPos is the relative position of the text cursor within that
+ * line.
+ * @param truncatedStart specifies whether the text was truncated at the
+ * beginning.
+ * @param truncatedEnd specifies whether the text was truncated at the
+ * end.
+ */
+ Context(std::string text, size_t relPos, bool truncatedStart,
+ bool truncatedEnd)
+ : text(std::move(text)),
+ relPos(relPos),
+ truncatedStart(truncatedStart),
+ truncatedEnd(truncatedEnd)
+ {
+ }
+
+ /**
+ * Returns true the context text is not empty.
+ *
+ * @return true if the context is valid and e.g. should be printed.
+ */
+ bool valid() const { return !text.empty(); }
+};
+}
+}
+
+#endif /* _OUSIA_TEXT_CURSOR_HPP_ */
+
diff --git a/src/core/common/VariantReader.cpp b/src/core/common/VariantReader.cpp
index e611842..a31a658 100644
--- a/src/core/common/VariantReader.cpp
+++ b/src/core/common/VariantReader.cpp
@@ -101,7 +101,7 @@ private:
// Check whether the given character is valid
int v = charValue(c);
if (v < 0 || v >= base) {
- logger.errorAt(ERR_UNEXPECTED_CHAR, reader);
+ logger.error(ERR_UNEXPECTED_CHAR, reader);
return false;
}
@@ -121,7 +121,7 @@ private:
// Check for any overflows
if (a < 0 || n < 0 || d < 0 || e < 0) {
- logger.errorAt(ERR_TOO_LARGE, reader);
+ logger.error(ERR_TOO_LARGE, reader);
return false;
}
return true;
@@ -203,7 +203,7 @@ bool Number::parse(CharReader &reader, Logger &logger,
case '-':
// Do not allow multiple minus signs
if (state == State::HAS_MINUS) {
- logger.errorAt(ERR_UNEXPECTED_CHAR, reader);
+ logger.error(ERR_UNEXPECTED_CHAR, reader);
return false;
}
state = State::HAS_MINUS;
@@ -259,7 +259,7 @@ bool Number::parse(CharReader &reader, Logger &logger,
case 'e':
case 'E':
if (state == State::LEADING_POINT) {
- logger.errorAt(ERR_UNEXPECTED_CHAR, reader);
+ logger.error(ERR_UNEXPECTED_CHAR, reader);
return false;
}
state = State::EXP_INIT;
@@ -276,7 +276,7 @@ bool Number::parse(CharReader &reader, Logger &logger,
case State::EXP_INIT:
if (c == '-') {
if (state == State::EXP_HAS_MINUS) {
- logger.errorAt(ERR_UNEXPECTED_CHAR, reader);
+ logger.error(ERR_UNEXPECTED_CHAR, reader);
return false;
}
state = State::EXP_HAS_MINUS;
@@ -303,7 +303,7 @@ bool Number::parse(CharReader &reader, Logger &logger,
state == State::EXP) {
return true;
}
- logger.errorAt(ERR_UNEXPECTED_END, reader);
+ logger.error(ERR_UNEXPECTED_END, reader);
return false;
}
@@ -322,7 +322,7 @@ template <class T>
static std::pair<bool, T> error(CharReader &reader, Logger &logger,
const char *err, T res)
{
- logger.errorAt(err, reader);
+ logger.error(err, reader);
return std::make_pair(false, std::move(res));
}
@@ -410,7 +410,7 @@ std::pair<bool, std::string> VariantReader::parseString(
if (Utils::isNumeric(c)) {
// TODO: Parse octal 000 sequence
} else {
- logger.errorAt(ERR_INVALID_ESCAPE, reader);
+ logger.error(ERR_INVALID_ESCAPE, reader);
}
break;
}
@@ -476,7 +476,7 @@ std::pair<bool, Variant::arrayType> VariantReader::parseArray(
} else if (!Utils::isWhitespace(c)) {
hadError = true;
state = STATE_RESYNC;
- logger.errorAt(ERR_UNEXPECTED_CHAR, reader);
+ logger.error(ERR_UNEXPECTED_CHAR, reader);
}
reader.consumePeek();
break;
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp
index 9a7b4d8..824219a 100644
--- a/src/plugins/xml/XmlParser.cpp
+++ b/src/plugins/xml/XmlParser.cpp
@@ -204,11 +204,15 @@ Rooted<Node> XmlParser::parse(std::istream &is, ParserContext &ctx)
// Parse the data and handle any XML error
if (!XML_ParseBuffer(&p, bytesRead, bytesRead == 0)) {
- const int line = XML_GetCurrentLineNumber(&p);
- const int column = XML_GetCurrentColumnNumber(&p);
+ const TextCursor::PosType line =
+ static_cast<TextCursor::PosType>(XML_GetCurrentLineNumber(&p));
+ const TextCursor::PosType column = static_cast<TextCursor::PosType>(
+ XML_GetCurrentColumnNumber(&p));
+ const size_t offs = XML_GetCurrentByteIndex(&p);
const XML_Error code = XML_GetErrorCode(&p);
const std::string msg = std::string{XML_ErrorString(code)};
- throw ParserException{"XML Syntax Error: " + msg, line, column};
+ throw ParserException{"XML Syntax Error: " + msg, line, column,
+ offs};
}
// Abort once there are no more bytes in the stream
diff --git a/test/core/common/CharReaderTest.cpp b/test/core/common/CharReaderTest.cpp
index 06b9d45..9c1026c 100644
--- a/test/core/common/CharReaderTest.cpp
+++ b/test/core/common/CharReaderTest.cpp
@@ -660,8 +660,8 @@ TEST(CharReaderTest, context)
// Retrieval at beginning of stream
{
CharReader reader{testStr};
- CharReader::Context ctx = reader.getContext(80);
- ASSERT_EQ("first line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(80);
+ ASSERT_EQ("first line", ctx.text);
ASSERT_EQ(0U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -670,13 +670,13 @@ TEST(CharReaderTest, context)
// Retrieval in middle of line
{
CharReader reader{testStr};
- CharReader::Context ctx = reader.getContext(80);
+ TextCursor::Context ctx = reader.getContext(80);
char c;
for (int i = 0; i < 5; i++)
reader.read(c);
- ASSERT_EQ("first line", ctx.line);
+ ASSERT_EQ("first line", ctx.text);
ASSERT_EQ(0U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -690,8 +690,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 11; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(80);
- ASSERT_EQ("first line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(80);
+ ASSERT_EQ("first line", ctx.text);
ASSERT_EQ(10U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -705,8 +705,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 5; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(3);
- ASSERT_EQ("t l", ctx.line);
+ TextCursor::Context ctx = reader.getContext(3);
+ ASSERT_EQ("t l", ctx.text);
ASSERT_EQ(1U, ctx.relPos);
ASSERT_TRUE(ctx.truncatedStart);
ASSERT_TRUE(ctx.truncatedEnd);
@@ -720,8 +720,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 12; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(80);
- ASSERT_EQ("second line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(80);
+ ASSERT_EQ("second line", ctx.text);
ASSERT_EQ(0U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -735,8 +735,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 23; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(80);
- ASSERT_EQ("second line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(80);
+ ASSERT_EQ("second line", ctx.text);
ASSERT_EQ(11U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -750,8 +750,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 24; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(80);
- ASSERT_EQ("last line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(80);
+ ASSERT_EQ("last line", ctx.text);
ASSERT_EQ(0U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -765,8 +765,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 28; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(80);
- ASSERT_EQ("last line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(80);
+ ASSERT_EQ("last line", ctx.text);
ASSERT_EQ(4U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -780,8 +780,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 28; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(3);
- ASSERT_EQ("t l", ctx.line);
+ TextCursor::Context ctx = reader.getContext(3);
+ ASSERT_EQ("t l", ctx.text);
ASSERT_EQ(1U, ctx.relPos);
ASSERT_TRUE(ctx.truncatedStart);
ASSERT_TRUE(ctx.truncatedEnd);
@@ -795,8 +795,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 100; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(80);
- ASSERT_EQ("last line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(80);
+ ASSERT_EQ("last line", ctx.text);
ASSERT_EQ(9U, ctx.relPos);
ASSERT_FALSE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
@@ -810,8 +810,8 @@ TEST(CharReaderTest, context)
for (int i = 0; i < 100; i++)
reader.read(c);
- CharReader::Context ctx = reader.getContext(4);
- ASSERT_EQ("line", ctx.line);
+ TextCursor::Context ctx = reader.getContext(4);
+ ASSERT_EQ("line", ctx.text);
ASSERT_EQ(4U, ctx.relPos);
ASSERT_TRUE(ctx.truncatedStart);
ASSERT_FALSE(ctx.truncatedEnd);
diff --git a/test/core/common/LoggerTest.cpp b/test/core/common/LoggerTest.cpp
index 54c67f9..bb31fa6 100644
--- a/test/core/common/LoggerTest.cpp
+++ b/test/core/common/LoggerTest.cpp
@@ -25,31 +25,38 @@
namespace ousia {
struct Pos {
- int line, column;
- Pos(int line, int column) : line(line), column(column){};
- int getLine() const { return line; }
- int getColumn() const { return column; }
+ TextCursor::Position pos;
+ TextCursor::Context ctx;
+
+ Pos(TextCursor::Position pos = TextCursor::Position{},
+ TextCursor::Context ctx = TextCursor::Context{})
+ : pos(pos), ctx(ctx){};
+
+ TextCursor::Position getPosition() { return pos; }
+ TextCursor::Context getContext() { return ctx; }
};
TEST(TerminalLogger, log)
{
// Test for manual visual expection only -- no assertions
TerminalLogger logger{std::cerr, true};
- logger.pushFilename("test.odp");
+ logger.pushFile("test.odp");
- logger.debug("This is a test debug message", 10, 20);
- logger.debug("This is a test debug message with no column", 10);
+ logger.debug("This is a test debug message", TextCursor::Position{10, 20});
+ logger.debug("This is a test debug message with no column",
+ TextCursor::Position{10});
logger.debug("This is a test debug message with no line");
- logger.debug("This is a test debug message with no file", "");
- logger.debug("This is a test debug message with no file but a line", "",
- 10);
- logger.debug(
- "This is a test debug message with no file but a line and a column", "",
- 10, 20);
- logger.note("This is a test note", 10, 20);
- logger.warning("This is a test warning", 10, 20);
- logger.error("This is a test error", 10, 20);
- logger.fatalError("This is a test fatal error!", 10, 20);
+ logger.note("This is a test note", TextCursor::Position{10, 20});
+ logger.warning("This is a test warning", TextCursor::Position{10, 20});
+ logger.error("This is a test error", TextCursor::Position{10, 20});
+ logger.fatalError("This is a test fatal error!",
+ TextCursor::Position{10, 20});
+
+ logger.error("This is a test error with context",
+ TextCursor::Position{10, 20},
+ TextCursor::Context{"int bla = blub;", 10, true, false});
+
+ Pos pos(TextCursor::Position{10, 20});
try {
throw LoggableException{"An exception"};
@@ -59,16 +66,13 @@ TEST(TerminalLogger, log)
}
try {
- throw LoggableException{"An exception at position", Pos(10, 20)};
+ throw LoggableException{"An exception at position", pos};
}
catch (const LoggableException &ex) {
logger.log(ex);
}
- logger.logAt(Severity::ERROR, "This is a positioned log message",
- Pos(10, 20));
- logger.debugAt("This is a positioned debug message", Pos(10, 20));
- logger.noteAt("This is a positioned log error", Pos(10, 20));
+ logger.logAt(Severity::ERROR, "This is a positioned log message", pos);
}
}
diff --git a/test/plugins/xml/XmlParserTest.cpp b/test/plugins/xml/XmlParserTest.cpp
index 7dc8c24..39b1a9d 100644
--- a/test/plugins/xml/XmlParserTest.cpp
+++ b/test/plugins/xml/XmlParserTest.cpp
@@ -36,7 +36,7 @@ TEST(XmlParser, mismatchedTagException)
p.parse("<document>\n</document2>", ctx);
}
catch (ParserException ex) {
- ASSERT_EQ(2, ex.line);
+ ASSERT_EQ(2U, ex.pos.line);
hadException = true;
}
ASSERT_TRUE(hadException);