From 68e787bdb0bfe493bd11f493d4e81299fa0845cd Mon Sep 17 00:00:00 2001 From: Alex Lorenz Date: Thu, 14 May 2015 23:08:22 +0000 Subject: YAML: Add support for literal block scalar I/O. This commit gives the users of the YAML Traits I/O library the ability to serialize scalars using the YAML literal block scalar notation by allowing them to implement a specialization of the `BlockScalarTraits` struct for their custom types. Reviewers: Duncan P. N. Exon Smith Differential Revision: http://reviews.llvm.org/D9613 llvm-svn: 237404 --- llvm/lib/Support/YAMLTraits.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'llvm/lib/Support') diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp index 8ef36a33280..90f34f6e232 100644 --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -14,6 +14,7 @@ #include "llvm/Support/Errc.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/LineIterator.h" #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include @@ -309,6 +310,8 @@ void Input::scalarString(StringRef &S, bool) { } } +void Input::blockScalarString(StringRef &S) { scalarString(S, false); } + void Input::setError(HNode *hnode, const Twine &message) { assert(hnode && "HNode must not be NULL"); this->setError(hnode->_node, message); @@ -331,6 +334,11 @@ std::unique_ptr Input::createHNodes(Node *N) { KeyStr = StringRef(Buf, Len); } return llvm::make_unique(N, KeyStr); + } else if (BlockScalarNode *BSN = dyn_cast(N)) { + StringRef Value = BSN->getValue(); + char *Buf = StringAllocator.Allocate(Value.size()); + memcpy(Buf, Value.data(), Value.size()); + return llvm::make_unique(N, StringRef(Buf, Value.size())); } else if (SequenceNode *SQ = dyn_cast(N)) { auto SQHNode = llvm::make_unique(N); for (Node &SN : *SQ) { @@ -609,6 +617,24 @@ void Output::scalarString(StringRef &S, bool MustQuote) { this->outputUpToEndOfLine("'"); // Ending single quote. } +void Output::blockScalarString(StringRef &S) { + if (!StateStack.empty()) + newLineCheck(); + output(" |"); + outputNewLine(); + + unsigned Indent = StateStack.empty() ? 1 : StateStack.size(); + + auto Buffer = MemoryBuffer::getMemBuffer(S, "", false); + for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) { + for (unsigned I = 0; I < Indent; ++I) { + output(" "); + } + output(*Lines); + outputNewLine(); + } +} + void Output::setError(const Twine &message) { } -- cgit v1.2.3