mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-27 17:31:33 +00:00
Add simple support for tags in YAML I/O
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194644 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4bd0224887
commit
4e7c22a90b
@ -633,6 +633,20 @@ This works for both reading and writing. For example:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Tags
|
||||||
|
----
|
||||||
|
|
||||||
|
The YAML syntax supports tags as a way to specify the type of a node before
|
||||||
|
it is parsed. This allows dynamic types of nodes. But the YAML I/O model uses
|
||||||
|
static typing, so there are limits to how you can use tags with the YAML I/O
|
||||||
|
model. Recently, we added support to YAML I/O for checking/setting the optional
|
||||||
|
tag on a map. Using this functionality it is even possbile to support differnt
|
||||||
|
mappings, as long as they are convertable.
|
||||||
|
|
||||||
|
To check a tag, inside your mapping() method you can use io.mapTag() to specify
|
||||||
|
what the tag should be. This will also add that tag when writing yaml.
|
||||||
|
|
||||||
|
|
||||||
Sequence
|
Sequence
|
||||||
========
|
========
|
||||||
|
|
||||||
|
@ -330,6 +330,7 @@ public:
|
|||||||
virtual void postflightFlowElement(void*) = 0;
|
virtual void postflightFlowElement(void*) = 0;
|
||||||
virtual void endFlowSequence() = 0;
|
virtual void endFlowSequence() = 0;
|
||||||
|
|
||||||
|
virtual bool mapTag(StringRef Tag, bool Default=false) = 0;
|
||||||
virtual void beginMapping() = 0;
|
virtual void beginMapping() = 0;
|
||||||
virtual void endMapping() = 0;
|
virtual void endMapping() = 0;
|
||||||
virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
|
virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;
|
||||||
@ -405,7 +406,6 @@ public:
|
|||||||
this->processKeyWithDefault(Key, Val, Default, false);
|
this->processKeyWithDefault(Key, Val, Default, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
|
void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,
|
||||||
@ -696,6 +696,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
virtual bool outputting();
|
virtual bool outputting();
|
||||||
|
virtual bool mapTag(StringRef, bool);
|
||||||
virtual void beginMapping();
|
virtual void beginMapping();
|
||||||
virtual void endMapping();
|
virtual void endMapping();
|
||||||
virtual bool preflightKey(const char *, bool, bool, bool &, void *&);
|
virtual bool preflightKey(const char *, bool, bool, bool &, void *&);
|
||||||
@ -819,6 +820,7 @@ public:
|
|||||||
virtual ~Output();
|
virtual ~Output();
|
||||||
|
|
||||||
virtual bool outputting();
|
virtual bool outputting();
|
||||||
|
virtual bool mapTag(StringRef, bool);
|
||||||
virtual void beginMapping();
|
virtual void beginMapping();
|
||||||
virtual void endMapping();
|
virtual void endMapping();
|
||||||
virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);
|
virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);
|
||||||
|
@ -82,6 +82,16 @@ void Input::nextDocument() {
|
|||||||
++DocIterator;
|
++DocIterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Input::mapTag(StringRef Tag, bool Default) {
|
||||||
|
StringRef foundTag = CurrentNode->_node->getVerbatimTag();
|
||||||
|
if (foundTag.empty()) {
|
||||||
|
// If no tag found and 'Tag' is the default, say it was found.
|
||||||
|
return Default;
|
||||||
|
}
|
||||||
|
// Return true iff found tag matches supplied tag.
|
||||||
|
return Tag.equals(foundTag);
|
||||||
|
}
|
||||||
|
|
||||||
void Input::beginMapping() {
|
void Input::beginMapping() {
|
||||||
if (EC)
|
if (EC)
|
||||||
return;
|
return;
|
||||||
@ -381,6 +391,14 @@ void Output::beginMapping() {
|
|||||||
NeedsNewLine = true;
|
NeedsNewLine = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Output::mapTag(StringRef Tag, bool Use) {
|
||||||
|
if (Use) {
|
||||||
|
this->output(" ");
|
||||||
|
this->output(Tag);
|
||||||
|
}
|
||||||
|
return Use;
|
||||||
|
}
|
||||||
|
|
||||||
void Output::endMapping() {
|
void Output::endMapping() {
|
||||||
StateStack.pop_back();
|
StateStack.pop_back();
|
||||||
}
|
}
|
||||||
|
@ -989,6 +989,91 @@ TEST(YAMLIO, TestSequenceDocListWriteAndRead) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Test document tags
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
struct MyDouble {
|
||||||
|
MyDouble() : value(0.0) { }
|
||||||
|
MyDouble(double x) : value(x) { }
|
||||||
|
double value;
|
||||||
|
};
|
||||||
|
|
||||||
|
LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble);
|
||||||
|
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace yaml {
|
||||||
|
template <>
|
||||||
|
struct MappingTraits<MyDouble> {
|
||||||
|
static void mapping(IO &io, MyDouble &d) {
|
||||||
|
if (io.mapTag("!decimal", true)) {
|
||||||
|
mappingDecimal(io, d);
|
||||||
|
} else if (io.mapTag("!fraction")) {
|
||||||
|
mappingFraction(io, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static void mappingDecimal(IO &io, MyDouble &d) {
|
||||||
|
io.mapRequired("value", d.value);
|
||||||
|
}
|
||||||
|
static void mappingFraction(IO &io, MyDouble &d) {
|
||||||
|
double num, denom;
|
||||||
|
io.mapRequired("numerator", num);
|
||||||
|
io.mapRequired("denominator", denom);
|
||||||
|
// convert fraction to double
|
||||||
|
d.value = num/denom;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test the reading of two different tagged yaml documents.
|
||||||
|
//
|
||||||
|
TEST(YAMLIO, TestTaggedDocuments) {
|
||||||
|
std::vector<MyDouble> docList;
|
||||||
|
Input yin("--- !decimal\nvalue: 3.0\n"
|
||||||
|
"--- !fraction\nnumerator: 9.0\ndenominator: 2\n...\n");
|
||||||
|
yin >> docList;
|
||||||
|
EXPECT_FALSE(yin.error());
|
||||||
|
EXPECT_EQ(docList.size(), 2UL);
|
||||||
|
EXPECT_EQ(docList[0].value, 3.0);
|
||||||
|
EXPECT_EQ(docList[1].value, 4.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Test writing then reading back tagged documents
|
||||||
|
//
|
||||||
|
TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {
|
||||||
|
std::string intermediate;
|
||||||
|
{
|
||||||
|
MyDouble a(10.25);
|
||||||
|
MyDouble b(-3.75);
|
||||||
|
std::vector<MyDouble> docList;
|
||||||
|
docList.push_back(a);
|
||||||
|
docList.push_back(b);
|
||||||
|
|
||||||
|
llvm::raw_string_ostream ostr(intermediate);
|
||||||
|
Output yout(ostr);
|
||||||
|
yout << docList;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Input yin(intermediate);
|
||||||
|
std::vector<MyDouble> docList2;
|
||||||
|
yin >> docList2;
|
||||||
|
|
||||||
|
EXPECT_FALSE(yin.error());
|
||||||
|
EXPECT_EQ(docList2.size(), 2UL);
|
||||||
|
EXPECT_EQ(docList2[0].value, 10.25);
|
||||||
|
EXPECT_EQ(docList2[1].value, -3.75);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Test error handling
|
// Test error handling
|
||||||
|
Loading…
x
Reference in New Issue
Block a user