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/StringRef.h"
14a37caebcSVedant Kumar #include "llvm/Support/raw_ostream.h"
15a37caebcSVedant Kumar #include "gtest/gtest.h"
16f190ce62SKazu Hirata #include <optional>
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::StringRef;
23a37caebcSVedant Kumar
24a37caebcSVedant Kumar #define QUOTE(x) std::string("\"" x "\"")
25a37caebcSVedant Kumar
26a37caebcSVedant Kumar /// Format \p input according to the specified string encoding and special char
27a37caebcSVedant Kumar /// escape style.
28a37caebcSVedant Kumar template <StringPrinter::StringElementType elem_ty>
292fe83274SKazu Hirata static std::optional<std::string>
format(StringRef input,StringPrinter::EscapeStyle escape_style)302fe83274SKazu Hirata format(StringRef input, StringPrinter::EscapeStyle escape_style) {
31a37caebcSVedant Kumar StreamString out;
32a37caebcSVedant Kumar StringPrinter::ReadBufferAndDumpToStreamOptions opts;
33a37caebcSVedant Kumar opts.SetStream(&out);
34a37caebcSVedant Kumar opts.SetSourceSize(input.size());
35a37caebcSVedant Kumar opts.SetNeedsZeroTermination(true);
36a37caebcSVedant Kumar opts.SetEscapeNonPrintables(true);
37a37caebcSVedant Kumar opts.SetIgnoreMaxLength(false);
38a37caebcSVedant Kumar opts.SetEscapeStyle(escape_style);
3914f44303SJan Kratochvil opts.SetData(DataExtractor(input.data(), input.size(),
4014f44303SJan Kratochvil endian::InlHostByteOrder(), sizeof(void *)));
41a37caebcSVedant Kumar const bool success = StringPrinter::ReadBufferAndDumpToStream<elem_ty>(opts);
42a37caebcSVedant Kumar if (!success)
43d2a6114fSKazu Hirata return std::nullopt;
44a37caebcSVedant Kumar return out.GetString().str();
45a37caebcSVedant Kumar }
46a37caebcSVedant Kumar
47a37caebcSVedant Kumar // Test ASCII formatting for C++. This behaves exactly like UTF8 formatting for
48a37caebcSVedant Kumar // C++, although that's questionable (see FIXME in StringPrinter.cpp).
TEST(StringPrinterTests,CxxASCII)49a37caebcSVedant Kumar TEST(StringPrinterTests, CxxASCII) {
50a37caebcSVedant Kumar auto fmt = [](StringRef str) {
51a37caebcSVedant Kumar return format<StringPrinter::StringElementType::ASCII>(
52a37caebcSVedant Kumar str, StringPrinter::EscapeStyle::CXX);
53a37caebcSVedant Kumar };
54a37caebcSVedant Kumar
55a37caebcSVedant Kumar // Special escapes.
56a37caebcSVedant Kumar EXPECT_EQ(fmt({"\0", 1}), QUOTE(""));
57a37caebcSVedant Kumar EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)"));
58a37caebcSVedant Kumar EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)"));
59a37caebcSVedant Kumar EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)"));
60a37caebcSVedant Kumar EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)"));
61a37caebcSVedant Kumar EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)"));
62a37caebcSVedant Kumar EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)"));
63a37caebcSVedant Kumar EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)"));
64a37caebcSVedant Kumar EXPECT_EQ(fmt("\""), QUOTE(R"(\")"));
65a37caebcSVedant Kumar EXPECT_EQ(fmt("\'"), QUOTE(R"(')"));
66a37caebcSVedant Kumar EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)"));
67a37caebcSVedant Kumar
68a37caebcSVedant Kumar // Printable characters.
69a37caebcSVedant Kumar EXPECT_EQ(fmt("'"), QUOTE("'"));
70a37caebcSVedant Kumar EXPECT_EQ(fmt("a"), QUOTE("a"));
71a37caebcSVedant Kumar EXPECT_EQ(fmt("Z"), QUOTE("Z"));
72a37caebcSVedant Kumar EXPECT_EQ(fmt(""), QUOTE(""));
73a37caebcSVedant Kumar
74a37caebcSVedant Kumar // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn).
75*cfc9f369SAlexandre Ganea EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C"));
76c05f3544SVedant Kumar EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348"));
77a37caebcSVedant Kumar
784699a7e2SVedant Kumar EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal.
794699a7e2SVedant Kumar EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal.
80a37caebcSVedant Kumar }
81a37caebcSVedant Kumar
82a37caebcSVedant Kumar // Test UTF8 formatting for C++.
TEST(StringPrinterTests,CxxUTF8)83a37caebcSVedant Kumar TEST(StringPrinterTests, CxxUTF8) {
84a37caebcSVedant Kumar auto fmt = [](StringRef str) {
85a37caebcSVedant Kumar return format<StringPrinter::StringElementType::UTF8>(
86a37caebcSVedant Kumar str, StringPrinter::EscapeStyle::CXX);
87a37caebcSVedant Kumar };
88a37caebcSVedant Kumar
89a37caebcSVedant Kumar // Special escapes.
90a37caebcSVedant Kumar EXPECT_EQ(fmt({"\0", 1}), QUOTE(""));
91a37caebcSVedant Kumar EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)"));
92a37caebcSVedant Kumar EXPECT_EQ(fmt("\b"), QUOTE(R"(\b)"));
93a37caebcSVedant Kumar EXPECT_EQ(fmt("\f"), QUOTE(R"(\f)"));
94a37caebcSVedant Kumar EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)"));
95a37caebcSVedant Kumar EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)"));
96a37caebcSVedant Kumar EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)"));
97a37caebcSVedant Kumar EXPECT_EQ(fmt("\v"), QUOTE(R"(\v)"));
98a37caebcSVedant Kumar EXPECT_EQ(fmt("\""), QUOTE(R"(\")"));
99a37caebcSVedant Kumar EXPECT_EQ(fmt("\'"), QUOTE(R"(')"));
100a37caebcSVedant Kumar EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)"));
101a37caebcSVedant Kumar
102a37caebcSVedant Kumar // Printable characters.
103a37caebcSVedant Kumar EXPECT_EQ(fmt("'"), QUOTE("'"));
104a37caebcSVedant Kumar EXPECT_EQ(fmt("a"), QUOTE("a"));
105a37caebcSVedant Kumar EXPECT_EQ(fmt("Z"), QUOTE("Z"));
106a37caebcSVedant Kumar EXPECT_EQ(fmt(""), QUOTE(""));
107a37caebcSVedant Kumar
108a37caebcSVedant Kumar // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn).
109c05f3544SVedant Kumar EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C"));
110c05f3544SVedant Kumar EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348"));
111a37caebcSVedant Kumar
1124699a7e2SVedant Kumar EXPECT_EQ(fmt("\376"), QUOTE(R"(\xfe)")); // \376 is 254 in decimal.
1134699a7e2SVedant Kumar EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\xfe)")); // \xfe is 254 in decimal.
114a37caebcSVedant Kumar }
115a37caebcSVedant Kumar
116a37caebcSVedant Kumar // Test UTF8 formatting for Swift.
TEST(StringPrinterTests,SwiftUTF8)117a37caebcSVedant Kumar TEST(StringPrinterTests, SwiftUTF8) {
118a37caebcSVedant Kumar auto fmt = [](StringRef str) {
119a37caebcSVedant Kumar return format<StringPrinter::StringElementType::UTF8>(
120a37caebcSVedant Kumar str, StringPrinter::EscapeStyle::Swift);
121a37caebcSVedant Kumar };
122a37caebcSVedant Kumar
123a37caebcSVedant Kumar // Special escapes.
124a37caebcSVedant Kumar EXPECT_EQ(fmt({"\0", 1}), QUOTE(""));
125a37caebcSVedant Kumar EXPECT_EQ(fmt("\a"), QUOTE(R"(\a)"));
126a37caebcSVedant Kumar EXPECT_EQ(fmt("\b"), QUOTE(R"(\u{8})"));
127a37caebcSVedant Kumar EXPECT_EQ(fmt("\f"), QUOTE(R"(\u{c})"));
128a37caebcSVedant Kumar EXPECT_EQ(fmt("\n"), QUOTE(R"(\n)"));
129a37caebcSVedant Kumar EXPECT_EQ(fmt("\r"), QUOTE(R"(\r)"));
130a37caebcSVedant Kumar EXPECT_EQ(fmt("\t"), QUOTE(R"(\t)"));
131a37caebcSVedant Kumar EXPECT_EQ(fmt("\v"), QUOTE(R"(\u{b})"));
132a37caebcSVedant Kumar EXPECT_EQ(fmt("\""), QUOTE(R"(\")"));
133a37caebcSVedant Kumar EXPECT_EQ(fmt("\'"), QUOTE(R"(\')"));
134a37caebcSVedant Kumar EXPECT_EQ(fmt("\\"), QUOTE(R"(\\)"));
135a37caebcSVedant Kumar
136a37caebcSVedant Kumar // Printable characters.
137a37caebcSVedant Kumar EXPECT_EQ(fmt("'"), QUOTE(R"(\')"));
138a37caebcSVedant Kumar EXPECT_EQ(fmt("a"), QUOTE("a"));
139a37caebcSVedant Kumar EXPECT_EQ(fmt("Z"), QUOTE("Z"));
140a37caebcSVedant Kumar EXPECT_EQ(fmt(""), QUOTE(""));
141a37caebcSVedant Kumar
142a37caebcSVedant Kumar // Octal (\nnn), hex (\xnn), extended octal (\unnnn or \Unnnnnnnn).
143c05f3544SVedant Kumar EXPECT_EQ(fmt("\uD55C"), QUOTE("\uD55C"));
144c05f3544SVedant Kumar EXPECT_EQ(fmt("\U00010348"), QUOTE("\U00010348"));
145a37caebcSVedant Kumar
1464699a7e2SVedant Kumar EXPECT_EQ(fmt("\376"), QUOTE(R"(\u{fe})")); // \376 is 254 in decimal.
1474699a7e2SVedant Kumar EXPECT_EQ(fmt("\xfe"), QUOTE(R"(\u{fe})")); // \xfe is 254 in decimal.
148a37caebcSVedant Kumar }
149