diff options
author | Rui Ueyama <ruiu@google.com> | 2013-09-11 04:00:08 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2013-09-11 04:00:08 +0000 |
commit | 106ededc4ed5a3f1cd899f13f3b7e7f1b200dd30 (patch) | |
tree | 6a2b1082a35e9469848713fc1bfa6e9f53b6d14b | |
parent | aa76981400a6b0dee6e42b4d456f2b605140f090 (diff) | |
download | bcm5719-llvm-106ededc4ed5a3f1cd899f13f3b7e7f1b200dd30.tar.gz bcm5719-llvm-106ededc4ed5a3f1cd899f13f3b7e7f1b200dd30.zip |
Re-submit r190469: YAMLIO: Fix string quoting logic.
llvm-svn: 190485
-rw-r--r-- | llvm/lib/Support/YAMLTraits.cpp | 16 | ||||
-rw-r--r-- | llvm/unittests/Support/YAMLIOTest.cpp | 57 |
2 files changed, 71 insertions, 2 deletions
diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp index cf19509ee88..19eaed1ac7a 100644 --- a/llvm/lib/Support/YAMLTraits.cpp +++ b/llvm/lib/Support/YAMLTraits.cpp @@ -15,6 +15,7 @@ #include "llvm/Support/YAMLParser.h" #include "llvm/Support/raw_ostream.h" #include <cstring> +#include <cctype> using namespace llvm; using namespace yaml; @@ -508,9 +509,20 @@ void Output::endBitSetScalar() { } void Output::scalarString(StringRef &S) { + const char ScalarSafeChars[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-/^., \t"; + 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 (S.find_first_not_of(ScalarSafeChars) == StringRef::npos && + !isspace(S.front()) && !isspace(S.back())) { + // If the string consists only of safe characters, print it out without + // quotes. this->outputUpToEndOfLine(S); return; } diff --git a/llvm/unittests/Support/YAMLIOTest.cpp b/llvm/unittests/Support/YAMLIOTest.cpp index 43d8397d1ed..8ae05f4b606 100644 --- a/llvm/unittests/Support/YAMLIOTest.cpp +++ b/llvm/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<StringTypes> { + 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 |