[PATCH] YAML: Add error resetting functionality to the yaml input class.
Alex Lorenz
arphaman at gmail.com
Mon May 11 17:18:59 PDT 2015
Hi bogner, bob.wilson,
This patch adds a 'resetError' method to the YAML 'Input' class.
This method is useful in cases where a semantic error occurs in one of the
yaml documents but we still want to parse the remaining documents.
REPOSITORY
rL LLVM
http://reviews.llvm.org/D9690
Files:
include/llvm/Support/YAMLTraits.h
lib/Support/YAMLTraits.cpp
unittests/Support/YAMLIOTest.cpp
Index: include/llvm/Support/YAMLTraits.h
===================================================================
--- include/llvm/Support/YAMLTraits.h
+++ include/llvm/Support/YAMLTraits.h
@@ -1092,6 +1092,10 @@
/// \brief Returns the current node that's being parsed by the YAML Parser.
const Node *getCurrentNode();
+ /// \brief Resets the error code so that we can skip and parse the other
+ /// documents in a YAML file.
+ void resetError();
+
private:
llvm::SourceMgr SrcMgr; // must be before Strm
std::unique_ptr<llvm::yaml::Stream> Strm;
Index: lib/Support/YAMLTraits.cpp
===================================================================
--- lib/Support/YAMLTraits.cpp
+++ lib/Support/YAMLTraits.cpp
@@ -101,6 +101,10 @@
return CurrentNode ? CurrentNode->_node : nullptr;
}
+void Input::resetError() {
+ EC = std::error_code();
+}
+
bool Input::mapTag(StringRef Tag, bool Default) {
std::string foundTag = CurrentNode->_node->getVerbatimTag();
if (foundTag.empty()) {
Index: unittests/Support/YAMLIOTest.cpp
===================================================================
--- unittests/Support/YAMLIOTest.cpp
+++ unittests/Support/YAMLIOTest.cpp
@@ -1593,6 +1593,56 @@
}
//===----------------------------------------------------------------------===//
+// Test error recovery
+//===----------------------------------------------------------------------===//
+
+//
+// Test that the parsing of documents still works when they follow documents
+// that have semantic errors.
+//
+
+struct ErrorMapping {
+ std::string Test;
+ std::string Test2;
+};
+
+namespace llvm {
+namespace yaml {
+ template <>
+ struct MappingTraits<ErrorMapping> {
+ static void mapping(IO &YamlIO, ErrorMapping &Map) {
+ YamlIO.mapRequired("test", Map.Test);
+ YamlIO.mapRequired("test2", Map.Test2);
+ }
+ };
+}
+}
+
+TEST(YAMLIO, DocumentErrorRecovery) {
+ ErrorMapping Map[3];
+ Input In("---\n"
+ "test2: 10\n"
+ "...\n"
+ "---\n"
+ "test: ad\n"
+ "test2: bc\n"
+ "...\n"
+ "---\n"
+ "test: da\n"
+ "test2: cb\n",
+ /*Ctxt=*/ nullptr, suppressErrorMessages);
+ for (size_t I = 0; In.setCurrentDocument(); ++I) {
+ llvm::yaml::yamlize(In, Map[I], true);
+ In.resetError();
+ In.nextDocument();
+ }
+ EXPECT_EQ(Map[1].Test, "ad");
+ EXPECT_EQ(Map[1].Test2, "bc");
+ EXPECT_EQ(Map[2].Test, "da");
+ EXPECT_EQ(Map[2].Test2, "cb");
+}
+
+//===----------------------------------------------------------------------===//
// Test error handling
//===----------------------------------------------------------------------===//
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9690.25532.patch
Type: text/x-patch
Size: 2706 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150512/b4b84e4c/attachment.bin>
More information about the llvm-commits
mailing list