//===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/YAMLTraits.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
#include <cstring>
using namespace llvm;
using namespace yaml;
//===----------------------------------------------------------------------===//
// IO
//===----------------------------------------------------------------------===//
IO::IO(void *Context) : Ctxt(Context) {
}
IO::~IO() {
}
void *IO::getContext() {
return Ctxt;
}
void IO::setContext(void *Context) {
Ctxt = Context;
}
//===----------------------------------------------------------------------===//
// Input
//===----------------------------------------------------------------------===//
Input::Input(StringRef InputContent, void *Ctxt)
: IO(Ctxt),
Strm(new Stream(InputContent, SrcMgr)),
CurrentNode(NULL) {
DocIterator = Strm->begin();
}
Input::~Input() {
}
error_code Input::error() {
return EC;
}
void Input::setDiagHandler(SourceMgr::DiagHandlerTy Handler, void *Ctxt) {
SrcMgr.setDiagHandler(Handler, Ctxt);
}
bool Input::outputting() {
return false;
}
bool Input::setCurrentDocument() {
if (DocIterator != Strm->end()) {
Node *N = DocIterator->getRoot();
if (isa<NullNode>(N)) {
// Empty files are allowed and ignored
++DocIterator;
return setCurrentDocument();
}
TopNode.reset(this->createHNodes(N));
CurrentNode = TopNode.get();
return true;
}
return false;
}
void Input::nextDocument() {
++DocIterator;
}
void Input::beginMapping() {
if (EC)
return;
MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
if (MN) {
MN->ValidKeys.clear();
}
}
bool Input::preflightKey(const char *Key, bool Required, bool, bool &UseDefault,
void *&SaveInfo) {
UseDefault = false;
if (EC)
return false;
MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
if (!MN) {
setError(CurrentNode, "not a mapping");
return false;
}
MN->ValidKeys.push_back(Key);
HNode *Value = MN->Mapping[Key];
if (!Value) {
if (Required)
setError(CurrentNode, Twine("missing required key '") + Key + "'");
else
UseDefault = true;
return false;
}
SaveInfo = CurrentNode;
CurrentNode = Value;
return true;
}
void Input::postflightKey(void *saveInfo) {
CurrentNode = reinterpret_cast<HNode *>(saveInfo);
}
void Input::endMapping() {
if (EC)
return;
MapHNode *MN = dyn_cast<MapHNode>(CurrentNode);
if (!MN)
return;
for (MapHNode::NameToNode::iterator i = MN->Mapping.begin(),
End = MN->Mapping.end(); i != End; ++i) {
if (!MN->isValidKey(i->first)) {
setError(i->second, Twine("unknown key '") + i->first + "'");
break;
}
}
}
unsigned Input::beginSequence() {
if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
return SQ->Entries.size();
}
return 0;
}
void Input::endSequence() {
}
bool Input::preflightElement(unsigned Index, void *&SaveInfo) {
if (EC)
return false;
if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
SaveInfo = CurrentNode;
CurrentNode = SQ->Entries[Index];
return true;
}
return false;
}
void Input::postflightElement(void *SaveInfo) {
CurrentNode = reinterpret_cast<HNode *>(SaveInfo);
}
unsigned Input::beginFlowSequence() {
if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
return SQ->Entries.size();
}
return 0;
}
bool Input::preflightFlowElement(unsigned index, void *&SaveInfo) {
if (EC)
return false;
if (SequenceHNode *SQ = dyn_cast<SequenceHNode>(CurrentNode)) {
SaveInfo = CurrentNode;
CurrentNode = SQ->Entries[