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