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

source code of lldb/unittests/DataFormatter/StringPrinterTests.cpp