Author: Jonas Devlieghere Date: 2026-06-30T12:47:06-07:00 New Revision: 6ae0aab16af4c692ac0834fbdcd3bc2ce74a4147
URL: https://github.com/llvm/llvm-project/commit/6ae0aab16af4c692ac0834fbdcd3bc2ce74a4147 DIFF: https://github.com/llvm/llvm-project/commit/6ae0aab16af4c692ac0834fbdcd3bc2ce74a4147.diff LOG: [ADT] Add printPercentEncoded to StringExtras (#206794) Hoist URL query-component percent-encoding into llvm/ADT alongside the other per-character string escapers (printEscapedString, printHTMLEscaped, printLowerCase). Several near-identical copies of this encoder exist across the tree, all using the same RFC 3986 charset. Added: Modified: lldb/source/Host/common/Host.cpp lldb/tools/lldb-dap/ClientLauncher.cpp llvm/include/llvm/ADT/StringExtras.h llvm/lib/Support/StringExtras.cpp llvm/unittests/ADT/StringExtrasTest.cpp Removed: ################################################################################ diff --git a/lldb/source/Host/common/Host.cpp b/lldb/source/Host/common/Host.cpp index b7a1020b4abd3..81d45f78559ce 100644 --- a/lldb/source/Host/common/Host.cpp +++ b/lldb/source/Host/common/Host.cpp @@ -660,13 +660,7 @@ llvm::Error Host::OpenURL(llvm::StringRef url) { std::string Host::URLEncode(llvm::StringRef str) { std::string out; llvm::raw_string_ostream os(out); - for (unsigned char c : str) { - if (std::isalnum(c) || llvm::StringRef("-_.~").contains(c)) - os << c; - else - os << '%' << llvm::hexdigit((c >> 4) & 0xF, /*LowerCase=*/false) - << llvm::hexdigit(c & 0xF, /*LowerCase=*/false); - } + llvm::printPercentEncoded(str, os); return out; } diff --git a/lldb/tools/lldb-dap/ClientLauncher.cpp b/lldb/tools/lldb-dap/ClientLauncher.cpp index 3244de9c5d0f0..7afedde8b8b0b 100644 --- a/lldb/tools/lldb-dap/ClientLauncher.cpp +++ b/lldb/tools/lldb-dap/ClientLauncher.cpp @@ -35,13 +35,8 @@ ClientLauncher::GetLauncher(ClientLauncher::Client client) { std::string VSCodeLauncher::URLEncode(llvm::StringRef str) { std::string out; llvm::raw_string_ostream os(out); - for (char c : str) { - if (std::isalnum(c) || llvm::StringRef("-_.~").contains(c)) - os << c; - else - os << '%' << llvm::utohexstr(c, false, 2); - } - return os.str(); + llvm::printPercentEncoded(str, os); + return out; } std::string diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h index e3cc6dcb25755..71e0c14c977a8 100644 --- a/llvm/include/llvm/ADT/StringExtras.h +++ b/llvm/include/llvm/ADT/StringExtras.h @@ -399,6 +399,12 @@ LLVM_ABI void printHTMLEscaped(StringRef String, raw_ostream &Out); /// printLowerCase - Print each character as lowercase if it is uppercase. LLVM_ABI void printLowerCase(StringRef String, raw_ostream &Out); +/// Print each character of \p String percent-encoded for use as a URL +/// query-component value (RFC 3986): unreserved characters (ALPHA, DIGIT, +/// '-' '_' '.' '~') are written directly; every other byte becomes an +/// uppercase %XX escape. Operates on raw bytes, so UTF-8 round-trips. +LLVM_ABI void printPercentEncoded(StringRef String, raw_ostream &Out); + /// Converts a string from camel-case to snake-case by replacing all uppercase /// letters with '_' followed by the letter in lowercase, except if the /// uppercase letter is the first character of the string. diff --git a/llvm/lib/Support/StringExtras.cpp b/llvm/lib/Support/StringExtras.cpp index bb2fa49bcbbc9..2d08012c9195f 100644 --- a/llvm/lib/Support/StringExtras.cpp +++ b/llvm/lib/Support/StringExtras.cpp @@ -79,6 +79,15 @@ void llvm::printLowerCase(StringRef String, raw_ostream &Out) { Out << toLower(C); } +void llvm::printPercentEncoded(StringRef String, raw_ostream &Out) { + for (unsigned char C : String) { + if (isAlnum(C) || StringRef("-_.~").contains(C)) + Out << C; + else + Out << '%' << hexdigit(C >> 4) << hexdigit(C & 0x0F); + } +} + std::string llvm::convertToSnakeFromCamelCase(StringRef input) { if (input.empty()) return ""; diff --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp index af88f88949b77..23ba1b0037b1e 100644 --- a/llvm/unittests/ADT/StringExtrasTest.cpp +++ b/llvm/unittests/ADT/StringExtrasTest.cpp @@ -189,6 +189,27 @@ TEST(StringExtrasTest, printHTMLEscaped) { EXPECT_EQ("ABCdef123&<>"'", OS.str()); } +TEST(StringExtrasTest, printPercentEncoded) { + auto encode = [](StringRef In) { + std::string Str; + raw_string_ostream OS(Str); + printPercentEncoded(In, OS); + return Str; + }; + + // Unreserved characters pass through unchanged. + EXPECT_EQ("AZaz09-_.~", encode("AZaz09-_.~")); + // Reserved characters are percent-encoded with uppercase hex. + EXPECT_EQ("a%20b%26c%3Dd", encode("a b&c=d")); + EXPECT_EQ("%2F%3F%23", encode("/?#")); + // Multi-byte UTF-8 is encoded byte by byte. + EXPECT_EQ("%C3%A9", encode("\xC3\xA9")); + // High bytes must not sign-extend into an over-long escape. + EXPECT_EQ("%80", encode("\x80")); + // The empty string maps to the empty string. + EXPECT_EQ("", encode("")); +} + TEST(StringExtrasTest, ConvertToSnakeFromCamelCase) { auto testConvertToSnakeCase = [](llvm::StringRef input, llvm::StringRef expected) { _______________________________________________ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
