diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-22 02:49:09 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-01-22 02:49:09 +0100 |
commit | 9b9c7439b6cb1b711901ad49cd4855e1b0964652 (patch) | |
tree | 4509d4ff644896f680156ccb4c42e4a1edf6f4da /src/core/common | |
parent | 4df98e9ae04dd077e47f0a5539aeb68b96c710c4 (diff) |
Backup
Diffstat (limited to 'src/core/common')
-rw-r--r-- | src/core/common/Location.hpp | 375 |
1 files changed, 316 insertions, 59 deletions
diff --git a/src/core/common/Location.hpp b/src/core/common/Location.hpp index 39e1011..f3a30b2 100644 --- a/src/core/common/Location.hpp +++ b/src/core/common/Location.hpp @@ -16,91 +16,310 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +/** + * @file Location.hpp + * + * Types used for describing positions, ranges and excerpts of source files used + * for describing log messages. + * + * @author Andreas Stöckel (astoecke@techfak.uni-bielefeld.de) + */ + #ifndef _OUSIA_LOCATION_HPP_ #define _OUSIA_LOCATION_HPP_ +#include <cstdint> +#include <limits> #include <string> namespace ousia { /** - * Struct representing a location within a source file. A position is defined by - * a byte offset (which is always reproducable), a line number and a column - * number (which may differ depending on the encoding used). + * Type used for referencing a source file currently opened in a Project. + */ +using SourceId = uint32_t; + +/** + * Type used for specifying an offset within a source file. + */ +using SourceOffset = uint32_t; + +/** + * Maximum value for a SourceOffset. As SourceOffset is a 32 Bit unsigned + * integer, the maximum value is 2^32-1, which means that 4 GiB are addressable + * by SourceOffset. */ -struct SourceLocation { +constexpr SourceOffset SourceOffsetMax = + std::numeric_limits<SourceOffset>::max(); + +/** + * Function for clamping a size_t to a valid SourceOffset value. + * + * @param pos is the size_t value that should be converted to a SourceOffset + * value. If pos is larger than the maximum value that can be represented by + * SourceOffset, the result is set to this maximum value, which is interpreted + * as "invalid" by functions dealing with the SourceOffset type. + * @return the clamped position value. + */ +inline SourceOffset clampToSourcePosition(size_t pos) +{ + return pos > SourceOffsetMax ? SourceOffsetMax : pos; +} + +/** + * Class specifying a position within an (unspecified) source file. + */ +class SourcePosition { +private: /** - * Current line, starting with one. + * Offset position in bytes relative to the start of the document. */ - int line; + SourceOffset pos; +public: /** - * Current column, starting with one. + * Default constructor of the SourcePosition class. Sets the position to + * SourceOffsetMax and thus marks the SourcePosition as invalid. */ - int column; + SourcePosition() : pos(SourceOffsetMax) {} /** - * Current byte offset. + * Creates a new SourcePosition instance with the given byte offset. */ - size_t offs; + SourcePosition(size_t pos) : pos(clampToSourcePosition(pos)) {} /** - * Default constructor of the SourceLocation struct, initializes all - * memebers with zero. + * Sets the position of the SourcePosition value to the given value. Clamps + * the given size_t to the valid range. + * + * @param pos is the position value that should be set. */ - SourceLocation() : line(0), column(0), offs(0) {} + void setPosition(size_t pos) { this->pos = clampToSourcePosition(pos); } /** - * Creates a new SourceLocation struct with only a line and no column. + * Returns the position value. Only use the value if "valid" returns true. * - * @param line is the line number. - * @param column is the column number. + * @return the current position. */ - SourceLocation(int line) : line(line), column(0), offs(0) {} + SourceOffset getPosition() const { return pos; } /** - * Creates a new SourceLocation struct with a line and column. + * Returns true if the source position is valid, false otherwise. Invalid + * positions are set to the maximum representable number. * - * @param line is the line number. - * @param column is the column number. + * @return true if the SourcePosition instance is value, false otherwise. */ - SourceLocation(int line, int column) : line(line), column(column), offs(0) + bool isValid() { return pos != SourceOffsetMax; } +}; + +/** + * The SourceRange class represents a range within an (unspecified) source file. + */ +class SourceRange { +private: + /** + * Start byte offset. + */ + SourcePosition start; + + /** + * End byte offset. + */ + SourcePosition end; + +public: + /** + * Default constructor. Creates an invalid range. + */ + SourceRange(){}; + + /** + * Constructor for a zero-length range. + * + * @param pos is the byte offset at which the SourceRange instance should be + * located. + */ + SourceRange(SourcePosition pos) : start(pos), end(pos) {} + + /** + * Constructor of a SourceRange instance. + * + * @param start is the byte offset of the first character in the range + * (start is inclusive). + * @param end points at the end of the range (end is non-inclusive). + */ + SourceRange(SourcePosition start, SourcePosition end) + : start(start), end(end) { } /** - * Creates a new SourceLocation struct with a line, column and byte offset. + * Sets the start of the SourceRange value to the given value. This + * operation might render the SourceRange invalid (if the given position is + * larger than the end position). + * + * @param pos is the start position value that should be set. + */ + void setStart(SourcePosition pos) { this->start = pos; } + + /** + * Sets the end of the SourceRange value to the given value. This operation + * might render the SourceRange invalid (if the given position is smaller + * than the start position). * - * @param line is the line number. - * @param column is the column number. - * @param offs is the byte offset. + * @param pos is the end position that should be set. */ - SourceLocation(int line, int column, size_t offs) - : line(line), column(column), offs(offs) + void setEnd(SourcePosition pos) { this->end = pos; } + + /** + * Sets the start and end of the SourceRange value to the given values. + * This operation might render the SourceRange invalid (if the given end + * position is smaller than the start position). + * + * @param start is the start position that should be set. + * @param end is the end position that should be set. + */ + void setRange(SourcePosition start, SourcePosition end) { + this->start = start; + this->end = end; } /** - * Returns true, if the line number is valid, false otherwise. + * Makes the Range represent a zero-length range that is located at the + * given position. The given position should be interpreted as being located + * "between the character just before the start offset and the start + * offset". * - * @return true for valid line numbers. + * @param pos is the position to which start and end should be set. */ - bool hasLine() const { return line > 0; } + void setPosition(SourcePosition pos) + { + this->start = pos; + this->end = pos; + } /** - * Returns true, if the column number is valid, false otherwise. + * Returns the start position of the SourceRange instance. * - * @return true for valid column numbers. + * @return the start offset in bytes. */ - bool hasColumn() const { return column > 0; } + SourceOffset getStart() const { return start.getPosition(); } /** - * Returns true, if the position is valid, false otherwise. This function is - * equivalent to the hasLine() function. + * Returns the end position of the SourceRange instance. * - * @return true if the Position struct is valid. + * @return the end offset in bytes (non-inclusive). */ - bool valid() const { return hasLine(); } + SourceOffset getEnd() const { return end.getPosition(); } + + /** + * Returns a copy of the underlying SourcePosition instance representing the + * start position. + * + * @return a copy of the start SourcePosition instance. + */ + SourcePosition getStartPosition() const { return start; } + + /** + * Returns a copy of the underlying SourcePosition instance representing the + * end position. + * + * @return a copy of the end SourcePosition instance. + */ + SourcePosition getEndPosition() const { return end; } + + /** + * Returns the length of the range. A range may have a zero value length, in + * which case it should be interpreted as "between the character before + * the start offset and the start offset". The returned value is only valid + * if the isValid() method returns true! + * + * @return the length of the range in bytes. + */ + size_t getLength() const { return end.getPosition() - start.getPosition(); } + + /** + * Returns true if this range is actually valid. This is the case if the + * start position is smaller or equal to the end position and start and end + * position themself are valid. + * + * @return true if the Range is valid. + */ + bool isValid() + { + return start.isValid() && end.isValid() && + start.getPosition() <= end.getPosition(); + } +}; + +/** + * The SourceLocation class describes a range within a specific source file. + */ +class SourceLocation : public SourceRange { +private: + /** + * Id of the source file. + */ + SourceId sourceId; + +public: + /** + * Constructor, binds the SourceLocation to the given source file. + * + * @param sourceId is the sourceId to which the SourceLocation instance + * should be bound. The sourceId cannot be overriden after construction. + */ + SourceLocation(SourceId sourceId) : sourceId(sourceId){}; + + /** + * Constructor for a zero-length range. + * + * @param sourceId is the sourceId to which the SourceLocation instance + * should be bound. The sourceId cannot be overriden after construction. + * @param pos is the byte offset at which the SourceRange instance should be + * located. + */ + SourceLocation(SourceId sourceId, SourcePosition pos) + : SourceRange(pos), sourceId(sourceId) + { + } + + /** + * Constructor of a SourceRange instance. + * + * @param sourceId is the sourceId to which the SourceLocation instance + * should be bound. The sourceId cannot be overriden after construction. + * @param start is the byte offset of the first character in the range + * (start is inclusive). + * @param end points at the end of the range (end is non-inclusive). + */ + SourceLocation(SourceId sourceId, SourcePosition start, SourcePosition end) + : SourceRange(start, end), sourceId(sourceId) + { + } + + /** + * Constructor of a SourceRange instance. + * + * @param sourceId is the sourceId to which the SourceLocation instance + * should be bound. The sourceId cannot be overriden after construction. + * @param start is the byte offset of the first character in the range + * (start is inclusive). + * @param end points at the end of the range (end is non-inclusive). + */ + SourceLocation(SourceId sourceId, const SourceRange &range) + : SourceRange(range), sourceId(sourceId) + { + } + + /** + * Returns the id of the source file this SourceLocation instance is bound + * to. + * + * @return the id of the source file this instance is bound to. + */ + SourceId getSourceId() { return sourceId; } }; /** @@ -109,6 +328,37 @@ struct SourceLocation { */ struct SourceContext { /** + * Underlying source range (contains the byte start and end offsets in + * bytes). + */ + SourceRange range; + + /** + * Name of the underlying resource. + */ + std::string filename; + + /** + * Start line, starting with one. + */ + int startLine; + + /** + * Start column, starting with one. + */ + int startColumn; + + /** + * End line, starting with one. + */ + int endLine; + + /** + * End column, starting with one. + */ + int endColumn; + + /** * Set to the content of the current line. */ std::string text; @@ -120,6 +370,12 @@ struct SourceContext { int relPos; /** + * Relative length (in characters) within that line. May end beyond the + * text given in the context. + */ + int relLen; + + /** * 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). @@ -134,39 +390,40 @@ struct SourceContext { bool truncatedEnd; /** - * Default constructor, initializes all members with zero values. + * Default constructor, initializes primitive members with zero values. */ SourceContext() - : text(), relPos(0), truncatedStart(false), truncatedEnd(false) + : startLine(0), + startColumn(0), + endLine(0), + endColumn(0), + relPos(0), + relLen(0), + truncatedStart(false), + truncatedEnd(false) { } /** - * Constructor of the SourceContext class. + * Returns true the context text is not empty. * - * @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. - */ - SourceContext(std::string text, size_t relPos, bool truncatedStart, - bool truncatedEnd) - : text(std::move(text)), - relPos(relPos), - truncatedStart(truncatedStart), - truncatedEnd(truncatedEnd) - { - } + * @return true if the context is valid and e.g. should be printed. + */ + bool isValid() const { return range.isValid() && hasLine() && hasColumn(); } /** - * Returns true the context text is not empty. + * Returns true, if the start line number is valid, false otherwise. * - * @return true if the context is valid and e.g. should be printed. + * @return true for valid line numbers. + */ + bool hasLine() const { return startLine > 0; } + + /** + * Returns true, if the start column number is valid, false otherwise. + * + * @return true for valid column numbers. */ - bool valid() const { return !text.empty(); } + bool hasColumn() const { return startColumn > 0; } }; /** |