summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Support/raw_ostream.h4
-rw-r--r--lib/Support/raw_ostream.cpp34
-rw-r--r--unittests/Support/raw_ostream_test.cpp16
3 files changed, 54 insertions, 0 deletions
diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h
index 8012b6fdfc..e67ff85a79 100644
--- a/include/llvm/Support/raw_ostream.h
+++ b/include/llvm/Support/raw_ostream.h
@@ -216,6 +216,10 @@ public:
/// write_hex - Output \arg N in hexadecimal, without any prefix or padding.
raw_ostream &write_hex(unsigned long long N);
+ /// write_escaped - Output \arg Str, turning '\\', '\t', '\n', '"', and
+ /// anything that doesn't satisfy std::isprint into an escape sequence.
+ raw_ostream &write_escaped(StringRef Str);
+
raw_ostream &write(unsigned char C);
raw_ostream &write(const char *Ptr, size_t Size);
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 0a82cc1d10..31451ccfdb 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -168,6 +168,40 @@ raw_ostream &raw_ostream::write_hex(unsigned long long N) {
return write(CurPtr, EndPtr-CurPtr);
}
+raw_ostream &raw_ostream::write_escaped(StringRef Str) {
+ for (unsigned i = 0, e = Str.size(); i != e; ++i) {
+ unsigned char c = Str[i];
+
+ switch (c) {
+ case '\\':
+ *this << '\\' << '\\';
+ break;
+ case '\t':
+ *this << '\\' << 't';
+ break;
+ case '\n':
+ *this << '\\' << 'n';
+ break;
+ case '"':
+ *this << '\\' << '"';
+ break;
+ default:
+ if (std::isprint(c)) {
+ *this << c;
+ break;
+ }
+
+ // Always expand to a 3-character octal escape.
+ *this << '\\';
+ *this << char('0' + ((c >> 6) & 7));
+ *this << char('0' + ((c >> 3) & 7));
+ *this << char('0' + ((c >> 0) & 7));
+ }
+ }
+
+ return *this;
+}
+
raw_ostream &raw_ostream::operator<<(const void *P) {
*this << '0' << 'x';
diff --git a/unittests/Support/raw_ostream_test.cpp b/unittests/Support/raw_ostream_test.cpp
index bd2e95cbb5..2b797b4366 100644
--- a/unittests/Support/raw_ostream_test.cpp
+++ b/unittests/Support/raw_ostream_test.cpp
@@ -127,4 +127,20 @@ TEST(raw_ostreamTest, TinyBuffer) {
EXPECT_EQ("hello1world", OS.str());
}
+TEST(raw_ostreamTest, WriteEscaped) {
+ std::string Str;
+
+ Str = "";
+ raw_string_ostream(Str).write_escaped("hi");
+ EXPECT_EQ("hi", Str);
+
+ Str = "";
+ raw_string_ostream(Str).write_escaped("\\\t\n\"");
+ EXPECT_EQ("\\\\\\t\\n\\\"", Str);
+
+ Str = "";
+ raw_string_ostream(Str).write_escaped("\1\10\200");
+ EXPECT_EQ("\\001\\010\\200", Str);
+}
+
}