149 lines · cpp
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-exception6//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 char27/// 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 for48// 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 str, 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 str, 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 str, 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