aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRui Ueyama <ruiu@google.com>2013-09-11 04:00:08 +0000
committerRui Ueyama <ruiu@google.com>2013-09-11 04:00:08 +0000
commit2e942d5402ddfadb04853a6f9dab2128af7a1d5e (patch)
tree09d6c36c75afd8a4405c3c64720c74c405058678
parent90c782a9ca9bc9325e9a1f075890311c15dfeb0e (diff)
downloadexternal_llvm-2e942d5402ddfadb04853a6f9dab2128af7a1d5e.zip
external_llvm-2e942d5402ddfadb04853a6f9dab2128af7a1d5e.tar.gz
external_llvm-2e942d5402ddfadb04853a6f9dab2128af7a1d5e.tar.bz2
Re-submit r190469: YAMLIO: Fix string quoting logic.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190485 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Support/YAMLTraits.cpp16
-rw-r--r--unittests/Support/YAMLIOTest.cpp57
2 files changed, 71 insertions, 2 deletions
diff --git a/lib/Support/YAMLTraits.cpp b/lib/Support/YAMLTraits.cpp
index cf19509..19eaed1 100644
--- a/lib/Support/YAMLTraits.cpp
+++ b/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/unittests/Support/YAMLIOTest.cpp b/unittests/Support/YAMLIOTest.cpp
index 43d8397..8ae05f4 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<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