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>
format(StringRef input,StringPrinter::EscapeStyle escape_style)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).
TEST(StringPrinterTests,CxxASCII)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++.
TEST(StringPrinterTests,CxxUTF8)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.
TEST(StringPrinterTests,SwiftUTF8)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