//===- lib/Support/YAMLTraits.cpp -----------------------------------------===//
//
// The LLVM Linker
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#define BUILDING_YAMLIO
#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>
namespace llvm {
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), CurrentNode(NULL) {
Strm = new Stream(InputContent, SrcMgr);
DocIterator = Strm->begin();
}
llvm::error_code Input::error() {
return EC;
}
void Input::setDiagHandler(llvm::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 (llvm::isa<NullNode>(N)) {
// Empty files are allowed and ignored
++DocIterator;
return setCurrentDocument();
}
CurrentNode = this->createHNodes(N);
return true;
}
return false;
}
void Input::nextDocument() {
++DocIterator;
}
void Input::beginMapping() {
if ( EC )
return;
MapHNode *MN = llvm::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 = llvm::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 = llvm::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 = llvm::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 = llvm::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 = llvm::dyn_cast&