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 DataExtractor extractor(input.data(), input.size(), 41 endian::InlHostByteOrder(), sizeof(void *)); 42 opts.SetData(extractor); 43 const bool success = StringPrinter::ReadBufferAndDumpToStream<elem_ty>(opts); 44 if (!success) 45 return llvm::None; 46 return out.GetString().str(); 47 } 48 49 // Test ASCII formatting for C++. This behaves exactly like UTF8 formatting for 50 // C++, although that's questionable (see FIXME in StringPrinter.cpp). 51 TEST(StringPrinterTests, CxxASCII) { 52 auto fmt = [](StringRef str) { 53 return format<StringPrinter::StringElementType::ASCII>( 54 str, StringPrinter::EscapeStyle::CXX); 55 }; 56 57 // Special escapes. 58 EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); 59 EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); 60 EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); 61 EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); 62 EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); 63 EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); 64 EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); 65 EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); 66 EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); 67 EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); 68 EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); 69 70 // Printable characters. 71 EXPECT_EQ(fmt("'"), QUOTE("'")); 72 EXPECT_EQ(fmt("a"), QUOTE("a")); 73 EXPECT_EQ(fmt("Z"), QUOTE("Z")); 74 EXPECT_EQ(fmt(""), QUOTE("")); 75 76 // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). 77 EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); 78 EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); 79 80 EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. 81 EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. 82 } 83 84 // Test UTF8 formatting for C++. 85 TEST(StringPrinterTests, CxxUTF8) { 86 auto fmt = [](StringRef str) { 87 return format<StringPrinter::StringElementType::UTF8>( 88 str, StringPrinter::EscapeStyle::CXX); 89 }; 90 91 // Special escapes. 92 EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); 93 EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); 94 EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)")); 95 EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)")); 96 EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); 97 EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); 98 EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); 99 EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)")); 100 EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); 101 EXPECT_EQ(fmt("\'"), QUOTE(R"(')")); 102 EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); 103 104 // Printable characters. 105 EXPECT_EQ(fmt("'"), QUOTE("'")); 106 EXPECT_EQ(fmt("a"), QUOTE("a")); 107 EXPECT_EQ(fmt("Z"), QUOTE("Z")); 108 EXPECT_EQ(fmt(""), QUOTE("")); 109 110 // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). 111 EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); 112 EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); 113 114 EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal. 115 EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal. 116 } 117 118 // Test UTF8 formatting for Swift. 119 TEST(StringPrinterTests, SwiftUTF8) { 120 auto fmt = [](StringRef str) { 121 return format<StringPrinter::StringElementType::UTF8>( 122 str, StringPrinter::EscapeStyle::Swift); 123 }; 124 125 // Special escapes. 126 EXPECT_EQ(fmt({"\0", 1}), QUOTE("")); 127 EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)")); 128 EXPECT_EQ(fmt("\b"), QUOTE(R"(\u{8})")); 129 EXPECT_EQ(fmt("\f"), QUOTE(R"(\u{c})")); 130 EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)")); 131 EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)")); 132 EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)")); 133 EXPECT_EQ(fmt("\v"), QUOTE(R"(\u{b})")); 134 EXPECT_EQ(fmt("\""), QUOTE(R"(\")")); 135 EXPECT_EQ(fmt("\'"), QUOTE(R"(\')")); 136 EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)")); 137 138 // Printable characters. 139 EXPECT_EQ(fmt("'"), QUOTE(R"(\')")); 140 EXPECT_EQ(fmt("a"), QUOTE("a")); 141 EXPECT_EQ(fmt("Z"), QUOTE("Z")); 142 EXPECT_EQ(fmt(""), QUOTE("")); 143 144 // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn). 145 EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C")); 146 EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348")); 147 148 EXPECT_EQ(fmt("\376"), QUOTE(R"(\u{fe})")); // \376 is 254 in decimal. 149 EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\u{fe})")); // \xfe is 254 in decimal. 150 } 151