# HG changeset patch # User František Kučera # Date 1607686482 -3600 # Node ID e753a7f967c8a6afb6054160a70b8a0dc9fcdb03 # Parent e04e5bbc147b617af272c8d068c1537a7dc33b80 implement --style standard diff -r e04e5bbc147b -r e753a7f967c8 src/INIStandardHandler.h --- a/src/INIStandardHandler.h Wed Dec 09 23:53:30 2020 +0100 +++ b/src/INIStandardHandler.h Fri Dec 11 12:34:42 2020 +0100 @@ -39,22 +39,80 @@ class INIStandardHandler : public relpipe::reader::handlers::RelationalReaderStringHandler { private: INIWriter& writer; + size_t currentAttributeIndex = 0; + std::vector currentAttributes; + relpipe::common::type::StringX previousSection; + relpipe::common::type::StringX currentSection; + relpipe::common::type::StringX currentKey; + relpipe::common::type::StringX currentSubKey; + relpipe::common::type::StringX currentValue; + relpipe::common::type::StringX currentComment; + relpipe::common::type::StringX currentWhitespace; + bool hasSections = false; public: INIStandardHandler(INIWriter& writer) : writer(writer) { } virtual ~INIStandardHandler() { - } void startRelation(relpipe::common::type::StringX name, std::vector attributes) override { + currentAttributes = attributes; + currentSection.clear(); + currentKey.clear(); + currentSubKey.clear(); + currentValue.clear(); + currentComment.clear(); + currentWhitespace.clear(); } void attribute(const relpipe::common::type::StringX& value) override { + auto name = currentAttributes[currentAttributeIndex % currentAttributes.size()].getAttributeName(); + if (name == L"section") currentSection = value; + else if (name == L"key") currentKey = value; + else if (name == L"sub_key") currentSubKey = value; + else if (name == L"value") currentValue = value; + else if (name == L"comment") currentComment = value; + else if (name == L"whitespace") currentWhitespace = value; + + currentAttributeIndex++; + + if (currentAttributeIndex == currentAttributes.size()) { + currentAttributeIndex = 0; + + if (currentSection != previousSection) { + if (previousSection.size()) writer.endSection(); + writer.startSection({ + .comment = currentKey.empty() ? currentComment : L"", + .name = currentSection, + .tag = L"", + }); + previousSection = currentSection; + hasSections = true; + } + + if (currentKey.size()) { + writer.entry({ + .comment = currentComment, + .key = currentKey, + .subKey = currentSubKey, + .value = currentValue, + }); + } else if (currentComment.size()) { + writer.comment({ + .comment = currentComment, + }); + } else if (currentWhitespace.size()) { + writer.whitespace({ + .whitespace = currentWhitespace, + }); + } + } } void endOfPipe() { + if (hasSections) writer.endSection(); } }; diff -r e04e5bbc147b -r e753a7f967c8 src/INIWriter.h --- a/src/INIWriter.h Wed Dec 09 23:53:30 2020 +0100 +++ b/src/INIWriter.h Fri Dec 11 12:34:42 2020 +0100 @@ -35,6 +35,8 @@ std::string commentSeparatorForSections = " ; "; std::string commentSeparatorForEntries = " ; "; std::string commentSeparatorStandalone = "; "; + + bool hasContent = false; enum class TokenType { SectionName, @@ -117,14 +119,15 @@ } void startSection(const SectionStartEvent& event) { + if (hasContent) output << std::endl; output << "[" << escape(TokenType::SectionName, event.name) << "]"; if (event.tag.size()) output << "[" << escape(TokenType::SectionTag, event.tag) << "]"; if (event.comment.size()) output << commentSeparatorForSections << escape(TokenType::SectionComment, event.comment); output << std::endl; + hasContent = true; } void endSection() { - output << std::endl; output.flush(); } @@ -134,10 +137,13 @@ output << keyValueSeparator << escape(TokenType::EntryValue, event.value); if (event.comment.size()) output << commentSeparatorForEntries << escape(TokenType::EntryComment, event.comment); output << std::endl; + hasContent = true; } void comment(const CommentEvent& event) { output << commentSeparatorStandalone << escape(TokenType::StandaloneComment, event.comment); + output << std::endl; + hasContent = true; } void whitespace(const WhitespaceEvent& event) { @@ -148,6 +154,7 @@ else if (ch == L'\r'); // TODO: keep CR? else; // TODO: throw exception if whitespace contains unexpected data? (should not happen) } + hasContent = true; }