From 522b113a752a8e86932eebdc41ba07e058950e41 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 17 Oct 2009 20:43:08 +0000 Subject: [PATCH] Add raw_ostream::write_escaped, for writing escaped strings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84355 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Support/raw_ostream.h | 4 +++ lib/Support/raw_ostream.cpp | 34 ++++++++++++++++++++++++++ unittests/Support/raw_ostream_test.cpp | 16 ++++++++++++ 3 files changed, 54 insertions(+) diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index 8012b6fdfc0..e67ff85a792 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 0a82cc1d10c..31451ccfdb1 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 bd2e95cbb53..2b797b43666 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); +} + }