<div dir="ltr">This is great!<div><br></div><div>-- Sean Silva</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Nov 13, 2013 at 8:00 PM, Nick Kledzik <span dir="ltr"><<a href="mailto:kledzik@apple.com" target="_blank">kledzik@apple.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: kledzik<br>
Date: Wed Nov 13 18:59:59 2013<br>
New Revision: 194644<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=194644&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=194644&view=rev</a><br>
Log:<br>
Add simple support for tags in YAML I/O<br>
<br>
Modified:<br>
llvm/trunk/docs/YamlIO.rst<br>
llvm/trunk/include/llvm/Support/YAMLTraits.h<br>
llvm/trunk/lib/Support/YAMLTraits.cpp<br>
llvm/trunk/unittests/Support/YAMLIOTest.cpp<br>
<br>
Modified: llvm/trunk/docs/YamlIO.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/YamlIO.rst?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/YamlIO.rst?rev=194644&r1=194643&r2=194644&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/docs/YamlIO.rst (original)<br>
+++ llvm/trunk/docs/YamlIO.rst Wed Nov 13 18:59:59 2013<br>
@@ -633,6 +633,20 @@ This works for both reading and writing.<br>
};<br>
<br>
<br>
+Tags<br>
+----<br>
+<br>
+The YAML syntax supports tags as a way to specify the type of a node before<br>
+it is parsed. This allows dynamic types of nodes. But the YAML I/O model uses<br>
+static typing, so there are limits to how you can use tags with the YAML I/O<br>
+model. Recently, we added support to YAML I/O for checking/setting the optional<br>
+tag on a map. Using this functionality it is even possbile to support differnt<br>
+mappings, as long as they are convertable.<br>
+<br>
+To check a tag, inside your mapping() method you can use io.mapTag() to specify<br>
+what the tag should be. This will also add that tag when writing yaml.<br>
+<br>
+<br>
Sequence<br>
========<br>
<br>
<br>
Modified: llvm/trunk/include/llvm/Support/YAMLTraits.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/YAMLTraits.h?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/YAMLTraits.h?rev=194644&r1=194643&r2=194644&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/Support/YAMLTraits.h (original)<br>
+++ llvm/trunk/include/llvm/Support/YAMLTraits.h Wed Nov 13 18:59:59 2013<br>
@@ -330,6 +330,7 @@ public:<br>
virtual void postflightFlowElement(void*) = 0;<br>
virtual void endFlowSequence() = 0;<br>
<br>
+ virtual bool mapTag(StringRef Tag, bool Default=false) = 0;<br>
virtual void beginMapping() = 0;<br>
virtual void endMapping() = 0;<br>
virtual bool preflightKey(const char*, bool, bool, bool &, void *&) = 0;<br>
@@ -404,8 +405,7 @@ public:<br>
void mapOptional(const char* Key, T& Val, const T& Default) {<br>
this->processKeyWithDefault(Key, Val, Default, false);<br>
}<br>
-<br>
-<br>
+<br>
private:<br>
template <typename T><br>
void processKeyWithDefault(const char *Key, T &Val, const T& DefaultValue,<br>
@@ -696,6 +696,7 @@ public:<br>
<br>
private:<br>
virtual bool outputting();<br>
+ virtual bool mapTag(StringRef, bool);<br>
virtual void beginMapping();<br>
virtual void endMapping();<br>
virtual bool preflightKey(const char *, bool, bool, bool &, void *&);<br>
@@ -819,6 +820,7 @@ public:<br>
virtual ~Output();<br>
<br>
virtual bool outputting();<br>
+ virtual bool mapTag(StringRef, bool);<br>
virtual void beginMapping();<br>
virtual void endMapping();<br>
virtual bool preflightKey(const char *key, bool, bool, bool &, void *&);<br>
<br>
Modified: llvm/trunk/lib/Support/YAMLTraits.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLTraits.cpp?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLTraits.cpp?rev=194644&r1=194643&r2=194644&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Support/YAMLTraits.cpp (original)<br>
+++ llvm/trunk/lib/Support/YAMLTraits.cpp Wed Nov 13 18:59:59 2013<br>
@@ -81,6 +81,16 @@ bool Input::setCurrentDocument() {<br>
void Input::nextDocument() {<br>
++DocIterator;<br>
}<br>
+<br>
+bool Input::mapTag(StringRef Tag, bool Default) {<br>
+ StringRef foundTag = CurrentNode->_node->getVerbatimTag();<br>
+ if (foundTag.empty()) {<br>
+ // If no tag found and 'Tag' is the default, say it was found.<br>
+ return Default;<br>
+ }<br>
+ // Return true iff found tag matches supplied tag.<br>
+ return Tag.equals(foundTag);<br>
+}<br>
<br>
void Input::beginMapping() {<br>
if (EC)<br>
@@ -381,6 +391,14 @@ void Output::beginMapping() {<br>
NeedsNewLine = true;<br>
}<br>
<br>
+bool Output::mapTag(StringRef Tag, bool Use) {<br>
+ if (Use) {<br>
+ this->output(" ");<br>
+ this->output(Tag);<br>
+ }<br>
+ return Use;<br>
+}<br>
+<br>
void Output::endMapping() {<br>
StateStack.pop_back();<br>
}<br>
<br>
Modified: llvm/trunk/unittests/Support/YAMLIOTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/YAMLIOTest.cpp?rev=194644&r1=194643&r2=194644&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Support/YAMLIOTest.cpp?rev=194644&r1=194643&r2=194644&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/Support/YAMLIOTest.cpp (original)<br>
+++ llvm/trunk/unittests/Support/YAMLIOTest.cpp Wed Nov 13 18:59:59 2013<br>
@@ -989,6 +989,91 @@ TEST(YAMLIO, TestSequenceDocListWriteAnd<br>
}<br>
}<br>
<br>
+//===----------------------------------------------------------------------===//<br>
+// Test document tags<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+struct MyDouble {<br>
+ MyDouble() : value(0.0) { }<br>
+ MyDouble(double x) : value(x) { }<br>
+ double value;<br>
+};<br>
+<br>
+LLVM_YAML_IS_DOCUMENT_LIST_VECTOR(MyDouble);<br>
+<br>
+<br>
+namespace llvm {<br>
+namespace yaml {<br>
+ template <><br>
+ struct MappingTraits<MyDouble> {<br>
+ static void mapping(IO &io, MyDouble &d) {<br>
+ if (io.mapTag("!decimal", true)) {<br>
+ mappingDecimal(io, d);<br>
+ } else if (io.mapTag("!fraction")) {<br>
+ mappingFraction(io, d);<br>
+ }<br>
+ }<br>
+ static void mappingDecimal(IO &io, MyDouble &d) {<br>
+ io.mapRequired("value", d.value);<br>
+ }<br>
+ static void mappingFraction(IO &io, MyDouble &d) {<br>
+ double num, denom;<br>
+ io.mapRequired("numerator", num);<br>
+ io.mapRequired("denominator", denom);<br>
+ // convert fraction to double<br>
+ d.value = num/denom;<br>
+ }<br>
+ };<br>
+ }<br>
+}<br>
+<br>
+<br>
+//<br>
+// Test the reading of two different tagged yaml documents.<br>
+//<br>
+TEST(YAMLIO, TestTaggedDocuments) {<br>
+ std::vector<MyDouble> docList;<br>
+ Input yin("--- !decimal\nvalue: 3.0\n"<br>
+ "--- !fraction\nnumerator: 9.0\ndenominator: 2\n...\n");<br>
+ yin >> docList;<br>
+ EXPECT_FALSE(yin.error());<br>
+ EXPECT_EQ(docList.size(), 2UL);<br>
+ EXPECT_EQ(docList[0].value, 3.0);<br>
+ EXPECT_EQ(docList[1].value, 4.5);<br>
+}<br>
+<br>
+<br>
+<br>
+//<br>
+// Test writing then reading back tagged documents<br>
+//<br>
+TEST(YAMLIO, TestTaggedDocumentsWriteAndRead) {<br>
+ std::string intermediate;<br>
+ {<br>
+ MyDouble a(10.25);<br>
+ MyDouble b(-3.75);<br>
+ std::vector<MyDouble> docList;<br>
+ docList.push_back(a);<br>
+ docList.push_back(b);<br>
+<br>
+ llvm::raw_string_ostream ostr(intermediate);<br>
+ Output yout(ostr);<br>
+ yout << docList;<br>
+ }<br>
+<br>
+ {<br>
+ Input yin(intermediate);<br>
+ std::vector<MyDouble> docList2;<br>
+ yin >> docList2;<br>
+<br>
+ EXPECT_FALSE(yin.error());<br>
+ EXPECT_EQ(docList2.size(), 2UL);<br>
+ EXPECT_EQ(docList2[0].value, 10.25);<br>
+ EXPECT_EQ(docList2[1].value, -3.75);<br>
+ }<br>
+}<br>
+<br>
+<br>
<br>
//===----------------------------------------------------------------------===//<br>
// Test error handling<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>