From 7c9298d8b10b5f4e69e24e3eb933e93e0d92fc37 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 18 Jun 2019 19:49:34 -0400 Subject: StringUtil::extractLine (#989) * Added extractLine line parsing to StringUtil. Use for matching lines instead of calcLines. calcLines uses extractLine to extract lines. Fixed problems found in output of some tests- due to how a how final line is handled. Now a final line has a \r or \n\r combination, but nothing else after it, it is considered the last line (not the line after it). * Use StringUtil::extractLine in slang-generate. * Improved comment on extractLine * Remove test code from StringUtil::extractLine * Made StringUtil::extractLine act as if line terminators are 'separators'. Added unit-test-string.cpp - to check behavior. * Adding LineParser - not entirely necessary, but slightly easier to use. * Improved LineParser::Iterator end testing. Added improved tests for LineParser. * Move line comparson after termination case - to fix problem with gcc release build. * Make UnownedStringSlice handle comparison when begin is nullptr - as it uses memcmp and passing nullptr to memcmp is undefined, leading to optimizer being able to do some unfortunate optimizations on gcc. --- source/core/slang-string-util.h | 47 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'source/core/slang-string-util.h') diff --git a/source/core/slang-string-util.h b/source/core/slang-string-util.h index 6a3b60240..b9618c17f 100644 --- a/source/core/slang-string-util.h +++ b/source/core/slang-string-util.h @@ -78,6 +78,16 @@ struct StringUtil /// Create a blob from a string static ComPtr createStringBlob(const String& string); + /// Returns a line extracted from the start of ioText. + /// + /// At the end of all the text a 'special' null UnownedStringSlice with a null 'begin' pointer is returned. + /// The slice passed in will be modified on output to contain the remaining text, starting at the beginning of the next line. + /// As en empty final line is still a line, the special null UnownedStringSlice is the last value ioText after the last valid line is returned. + /// + /// NOTE! That behavior is as if line terminators (like \n) act as separators. Thus input of "\n" will return *two* lines - an empty line + /// before and then after the \n. + static UnownedStringSlice extractLine(UnownedStringSlice& ioText); + /// Given text, splits into lines stored in outLines. NOTE! That lines is only valid as long as textIn remains valid static void calcLines(const UnownedStringSlice& textIn, List& lines); @@ -85,6 +95,43 @@ struct StringUtil static bool areLinesEqual(const UnownedStringSlice& a, const UnownedStringSlice& b); }; +/* A helper class that allows parsing of lines from text with iteration. Uses StringUtil::extractLine for the actual underlying implementation. */ +class LineParser +{ +public: + struct Iterator + { + const UnownedStringSlice& operator*() const { return m_line; } + const UnownedStringSlice* operator->() const { return &m_line; } + Iterator& operator++() + { + m_line = StringUtil::extractLine(m_remaining); + return *this; + } + Iterator operator++(int) { Iterator rs = *this; operator++(); return rs; } + + /// Equal if both are at the same m_line address exactly. Handles termination case correctly where line.begin() == nullptr. + bool operator==(const Iterator& rhs) const { return m_line.begin() == rhs.m_line.begin(); } + bool operator !=(const Iterator& rhs) const { return !(*this == rhs); } + + /// Ctor + Iterator(const UnownedStringSlice& line, const UnownedStringSlice& remaining) : m_line(line), m_remaining(remaining) {} + + protected: + UnownedStringSlice m_line; + UnownedStringSlice m_remaining; + }; + + Iterator begin() const { UnownedStringSlice remaining(m_text); UnownedStringSlice line = StringUtil::extractLine(remaining); return Iterator(line, remaining); } + Iterator end() const { UnownedStringSlice term(nullptr, nullptr); return Iterator(term, term); } + + /// Ctor + LineParser(const UnownedStringSlice& text) : m_text(text) {} + +protected: + UnownedStringSlice m_text; +}; + } // namespace Slang #endif // SLANG_STRING_UTIL_H -- cgit v1.2.3