From 7eb8b0fd84474f6a77ffa6211c0c753ed3142277 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 11 Sep 2013 00:45:48 +0000 Subject: [PATCH] YAMLIO: Fix string quoting logic. YAMLIO printed a string as is without quotes unless it contains a newline character. That did not suffice. We also need to quote a string if it starts with a backquote, quote, double quote or atsign, or it's the empty string. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190469 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/YAMLTraits.cpp | 12 +++++-- unittests/Support/YAMLIOTest.cpp | 57 ++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/lib/Support/YAMLTraits.cpp b/lib/Support/YAMLTraits.cpp index ae7f7dcb0d0..1a6adbf559b 100644 --- a/lib/Support/YAMLTraits.cpp +++ b/lib/Support/YAMLTraits.cpp @@ -510,8 +510,16 @@ void Output::endBitSetScalar() { void Output::scalarString(StringRef &S) { this->newLineCheck(); - if (S.find('\n') == StringRef::npos) { - // No embedded new-line chars, just print string. + + if (S.empty()) { + // Print '' for the empty string because leaving the field empty is not + // allowed. + this->outputUpToEndOfLine("''"); + return; + } + if (!strchr("'`@\"", S.front()) && S.find('\n') == StringRef::npos) { + // Plain string cannot start with double quote or single quote. Backquote + // and atsign are reserved characters. Newline is not allowed. this->outputUpToEndOfLine(S); return; } diff --git a/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp index 3b4bb9d94ec..9da16c6ed6a 100644 --- a/unittests/Support/YAMLIOTest.cpp +++ b/unittests/Support/YAMLIOTest.cpp @@ -273,7 +273,64 @@ TEST(YAMLIO, TestReadWriteBuiltInTypes) { } } +struct StringTypes { + llvm::StringRef str1; + llvm::StringRef str2; + llvm::StringRef str3; + llvm::StringRef str4; + llvm::StringRef str5; +}; +namespace llvm { +namespace yaml { + template <> + struct MappingTraits { + static void mapping(IO &io, StringTypes& st) { + io.mapRequired("str1", st.str1); + io.mapRequired("str2", st.str2); + io.mapRequired("str3", st.str3); + io.mapRequired("str4", st.str4); + io.mapRequired("str5", st.str5); + } + }; +} +} + +TEST(YAMLIO, TestReadWriteStringTypes) { + std::string intermediate; + { + StringTypes map; + map.str1 = "'aaa"; + map.str2 = "\"bbb"; + map.str3 = "`ccc"; + map.str4 = "@ddd"; + map.str5 = ""; + + llvm::raw_string_ostream ostr(intermediate); + Output yout(ostr); + yout << map; + } + + llvm::StringRef flowOut(intermediate); + EXPECT_NE(llvm::StringRef::npos, flowOut.find("'''aaa")); + EXPECT_NE(llvm::StringRef::npos, flowOut.find("'\"bbb'")); + EXPECT_NE(llvm::StringRef::npos, flowOut.find("'`ccc'")); + EXPECT_NE(llvm::StringRef::npos, flowOut.find("'@ddd'")); + EXPECT_NE(llvm::StringRef::npos, flowOut.find("''\n")); + + { + Input yin(intermediate); + StringTypes map; + yin >> map; + + EXPECT_FALSE(yin.error()); + EXPECT_TRUE(map.str1.equals("'aaa")); + EXPECT_TRUE(map.str2.equals("\"bbb")); + EXPECT_TRUE(map.str3.equals("`ccc")); + EXPECT_TRUE(map.str4.equals("@ddd")); + EXPECT_TRUE(map.str5.equals("")); + } +} //===----------------------------------------------------------------------===// // Test ScalarEnumerationTraits -- 2.34.1