aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/position.hh
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-01-29 06:19:23 +0100
committereldritch horrors <pennae@lix.systems>2024-03-18 16:12:46 +0100
commit4c072c7c5f5e574ace6a3c3a1e07cb5db25a4487 (patch)
tree9b40b241d9f139c5684633d95652acaf333b5aa3 /src/libutil/position.hh
parent9cf92c012d81bdd8df60a51f7cbcdb4812544c46 (diff)
match line endings used by parser and error reports
the parser treats a plain \r as a newline, error reports do not. this can lead to interesting divergences if anything makes use of this feature, with error reports pointing to wrong locations in the input (or even outside the input altogether). (cherry picked from commit 2be6b143289e5479cc4a2667bb84e879116c2447) Change-Id: Ieb7f7655bac8cb0cf5734c60bd41723388f2973c
Diffstat (limited to 'src/libutil/position.hh')
-rw-r--r--src/libutil/position.hh42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/libutil/position.hh b/src/libutil/position.hh
index a184997ed..9bdf3b4b5 100644
--- a/src/libutil/position.hh
+++ b/src/libutil/position.hh
@@ -67,6 +67,48 @@ struct Pos
bool operator==(const Pos & rhs) const = default;
bool operator!=(const Pos & rhs) const = default;
bool operator<(const Pos & rhs) const;
+
+ struct LinesIterator {
+ using difference_type = size_t;
+ using value_type = std::string_view;
+ using reference = const std::string_view &;
+ using pointer = const std::string_view *;
+ using iterator_category = std::input_iterator_tag;
+
+ LinesIterator(): pastEnd(true) {}
+ explicit LinesIterator(std::string_view input): input(input), pastEnd(input.empty()) {
+ if (!pastEnd)
+ bump(true);
+ }
+
+ LinesIterator & operator++() {
+ bump(false);
+ return *this;
+ }
+ LinesIterator operator++(int) {
+ auto result = *this;
+ ++*this;
+ return result;
+ }
+
+ reference operator*() const { return curLine; }
+ pointer operator->() const { return &curLine; }
+
+ bool operator!=(const LinesIterator & other) const {
+ return !(*this == other);
+ }
+ bool operator==(const LinesIterator & other) const {
+ return (pastEnd && other.pastEnd)
+ || (std::forward_as_tuple(input.size(), input.data())
+ == std::forward_as_tuple(other.input.size(), other.input.data()));
+ }
+
+ private:
+ std::string_view input, curLine;
+ bool pastEnd = false;
+
+ void bump(bool atFirst);
+ };
};
std::ostream & operator<<(std::ostream & str, const Pos & pos);