//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/Errc.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Casting.h"
+#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/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <cstring>
return ++DocIterator != Strm->end();
}
+const Node *Input::getCurrentNode() const {
+ return CurrentNode ? CurrentNode->_node : nullptr;
+}
+
bool Input::mapTag(StringRef Tag, bool Default) {
std::string foundTag = CurrentNode->_node->getVerbatimTag();
if (foundTag.empty()) {
}
}
+void Input::beginFlowMapping() { beginMapping(); }
+
+void Input::endFlowMapping() { endMapping(); }
+
unsigned Input::beginSequence() {
- if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
+ if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode))
return SQ->Entries.size();
+ if (isa<EmptyHNode>(CurrentNode))
+ return 0;
+ // Treat case where there's a scalar "null" value as an empty sequence.
+ if (ScalarHNode *SN = dyn_cast<ScalarHNode>(CurrentNode)) {
+ if (isNull(SN->value()))
+ return 0;
}
+ // Any other type of HNode is an error.
+ setError(CurrentNode, "not a sequence");
return 0;
}
CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
}
-unsigned Input::beginFlowSequence() {
- if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
- return SQ->Entries.size();
- }
- return 0;
-}
+unsigned Input::beginFlowSequence() { return beginSequence(); }
bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
if (EC)
}
}
+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);
StringRef KeyStr = SN->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
- unsigned Len = StringStorage.size();
- char *Buf = StringAllocator.Allocate<char>(Len);
- memcpy(Buf, &StringStorage[0], Len);
- KeyStr = StringRef(Buf, Len);
+ KeyStr = StringStorage.str().copy(StringAllocator);
}
return llvm::make_unique<ScalarHNode>(N, KeyStr);
+ } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
+ StringRef ValueCopy = BSN->getValue().copy(StringAllocator);
+ return llvm::make_unique<ScalarHNode>(N, ValueCopy);
} else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
auto SQHNode = llvm::make_unique<SequenceHNode>(N);
for (Node &SN : *SQ) {
StringRef KeyStr = KeyScalar->getValue(StringStorage);
if (!StringStorage.empty()) {
// Copy string to permanent storage
- unsigned Len = StringStorage.size();
- char *Buf = StringAllocator.Allocate<char>(Len);
- memcpy(Buf, &StringStorage[0], Len);
- KeyStr = StringRef(Buf, Len);
+ KeyStr = StringStorage.str().copy(StringAllocator);
}
auto ValueHNode = this->createHNodes(KVN.getValue());
if (EC)
// Output
//===----------------------------------------------------------------------===//
-Output::Output(raw_ostream &yout, void *context)
+Output::Output(raw_ostream &yout, void *context, int WrapColumn)
: IO(context),
Out(yout),
+ WrapColumn(WrapColumn),
Column(0),
ColumnAtFlowStart(0),
+ ColumnAtMapFlowStart(0),
NeedBitValueComma(false),
NeedFlowSequenceComma(false),
EnumerationMatchFound(false),
bool &UseDefault, void *&) {
UseDefault = false;
if (Required || !SameAsDefault) {
- this->newLineCheck();
- this->paddedKey(Key);
+ auto State = StateStack.back();
+ if (State == inFlowMapFirstKey || State == inFlowMapOtherKey) {
+ flowKey(Key);
+ } else {
+ this->newLineCheck();
+ this->paddedKey(Key);
+ }
return true;
}
return false;
if (StateStack.back() == inMapFirstKey) {
StateStack.pop_back();
StateStack.push_back(inMapOtherKey);
+ } else if (StateStack.back() == inFlowMapFirstKey) {
+ StateStack.pop_back();
+ StateStack.push_back(inFlowMapOtherKey);
}
}
+void Output::beginFlowMapping() {
+ StateStack.push_back(inFlowMapFirstKey);
+ this->newLineCheck();
+ ColumnAtMapFlowStart = Column;
+ output("{ ");
+}
+
+void Output::endFlowMapping() {
+ StateStack.pop_back();
+ this->outputUpToEndOfLine(" }");
+}
+
void Output::beginDocuments() {
this->outputUpToEndOfLine("---");
}
bool Output::preflightFlowElement(unsigned, void *&) {
if (NeedFlowSequenceComma)
output(", ");
- if (Column > 70) {
+ if (WrapColumn && Column > WrapColumn) {
output("\n");
for (int i = 0; i < ColumnAtFlowStart; ++i)
output(" ");
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) {
}
void Output::outputUpToEndOfLine(StringRef s) {
this->output(s);
- if (StateStack.empty() || StateStack.back() != inFlowSeq)
+ if (StateStack.empty() || (StateStack.back() != inFlowSeq &&
+ StateStack.back() != inFlowMapFirstKey &&
+ StateStack.back() != inFlowMapOtherKey))
NeedsNewLine = true;
}
if (StateStack.back() == inSeq) {
OutputDash = true;
- } else if ((StateStack.size() > 1) && (StateStack.back() == inMapFirstKey) &&
+ } else if ((StateStack.size() > 1) && ((StateStack.back() == inMapFirstKey) ||
+ (StateStack.back() == inFlowSeq) ||
+ (StateStack.back() == inFlowMapFirstKey)) &&
(StateStack[StateStack.size() - 2] == inSeq)) {
--Indent;
OutputDash = true;
output(" ");
}
+void Output::flowKey(StringRef Key) {
+ if (StateStack.back() == inFlowMapOtherKey)
+ output(", ");
+ if (WrapColumn && Column > WrapColumn) {
+ output("\n");
+ for (int I = 0; I < ColumnAtMapFlowStart; ++I)
+ output(" ");
+ Column = ColumnAtMapFlowStart;
+ output(" ");
+ }
+ output(Key);
+ output(": ");
+}
+
//===----------------------------------------------------------------------===//
// traits for built-in types
//===----------------------------------------------------------------------===//
Val = Scalar;
return StringRef();
}
-
+
void ScalarTraits<std::string>::output(const std::string &Val, void *,
raw_ostream &Out) {
Out << Val;