[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