1 //===-- StringPrinterTests.cpp --------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "lldb/DataFormatters/StringPrinter.h" 10 #include "lldb/Utility/DataExtractor.h" 11 #include "lldb/Utility/Endian.h" 12 #include "lldb/Utility/StreamString.h" 13 #include "llvm/ADT/Optional.h" 14 #include "llvm/ADT/StringRef.h" 15 #include "llvm/Support/raw_ostream.h" 16 #include "gtest/gtest.h" 17 #include <string> 18 19 using namespace lldb; 20 using namespace lldb_private; 21 using lldb_private::formatters::StringPrinter; 22 using llvm::Optional; 23 using llvm::StringRef; 24 25 #define QUOTE(x) std::string("\"" x "\"") 26 27 /// Format \p input according to the specified string encoding and special char 28 /// escape style. 29 template <StringPrinter::StringElementType elem_ty> 30 static Optional<std::string> format(StringRef input, 31 StringPrinter::EscapeStyle escape_style) { 32 StreamString out; 33 StringPrinter::ReadBufferAndDumpToStreamOptions opts; 34 opts.SetStream(&out); 35 opts.SetSourceSize(input.size()); 36 opts.SetNeedsZeroTermination(true); 37 opts.SetEscapeNonPrintables(true); 38 opts.SetIgnoreMaxLength(false); 39 opts.SetEscapeStyle(escape_style); 40 opts.SetData(DataExtractor(input.data(), input.size(), 41 endian::InlHostByteOrder(), sizeof(void *))); 42 const bool success = StringPrinter::ReadBufferAndDumpToStream<elem_ty>(opts); 43 if (!success) 44 return llvm::None; 45 return out.GetString().str(); 46 } 47 48 // Test ASCII formatting for C++. This behaves exactly like UTF8 formatting for 49 // C++, although that's questionable (see FIXME in StringPrinter.cpp). 50 TEST(StringPrinterTests, CxxASCII) { 51 auto fmt = [](StringRef str) { 52 return format<StringPrinter::StringElementType::ASCII>( 53 str, StringPrinter::EscapeStyle::CXX); 54 }; 55 56 // Special escapes. 57 EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); 58 EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); 59 EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); 60 EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); 61 EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); 62 EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); 63 EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); 64 EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); 65 EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); 66 EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); 67 EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); 68 69 // Printable characters. 70 EXPECT_EQ(fmt("'"), QUOTE("'")); 71 EXPECT_EQ(fmt("a"), QUOTE("a")); 72 EXPECT_EQ(fmt("Z"), QUOTE("Z")); 73 EXPECT_EQ(fmt(""), QUOTE("")); 74 75 // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). 76 EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); 77 EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); 78 79 EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. 80 EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. 81 } 82 83 // Test UTF8 formatting for C++. 84 TEST(StringPrinterTests, CxxUTF8) { 85 auto fmt = [](StringRef str) { 86 return format<StringPrinter::StringElementType::UTF8>( 87 str, StringPrinter::EscapeStyle::CXX); 88 }; 89 90 // Special escapes. 91 EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); 92 EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); 93 EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); 94 EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); 95 EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); 96 EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); 97 EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); 98 EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); 99 EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); 100 EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); 101 EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); 102 103 // Printable characters. 104 EXPECT_EQ(fmt("'"), QUOTE("'")); 105 EXPECT_EQ(fmt("a"), QUOTE("a")); 106 EXPECT_EQ(fmt("Z"), QUOTE("Z")); 107 EXPECT_EQ(fmt(""), QUOTE("")); 108 109 // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). 110 EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); 111 EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); 112 113 EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. 114 EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. 115 } 116 117 // Test UTF8 formatting for Swift. 118 TEST(StringPrinterTests, SwiftUTF8) { 119 auto fmt = [](StringRef str) { 120 return format<StringPrinter::StringElementType::UTF8>( 121 str, StringPrinter::EscapeStyle::Swift); 122 }; 123 124 // Special escapes. 125 EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); 126 EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); 127 EXPECT_EQ(fmt("\b"), QUOTE(R"(\u{8})")); 128 EXPECT_EQ(fmt("\f"), QUOTE(R"(\u{c})")); 129 EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); 130 EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); 131 EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); 132 EXPECT_EQ(fmt("\v"), QUOTE(R"(\u{b})")); 133 EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); 134 EXPECT_EQ(fmt("\'"), QUOTE(R"(\')")); 135 EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); 136 137 // Printable characters. 138 EXPECT_EQ(fmt("'"), QUOTE(R"(\')")); 139 EXPECT_EQ(fmt("a"), QUOTE("a")); 140 EXPECT_EQ(fmt("Z"), QUOTE("Z")); 141 EXPECT_EQ(fmt(""), QUOTE("")); 142 143 // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). 144 EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); 145 EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); 146 147 EXPECT_EQ(fmt("\376"), QUOTE(R"(\u{fe})")); // \376 is 254 in decimal. 148 EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\u{fe})")); // \xfe is 254 in decimal. 149 } 150