From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id GYeWM8Wyz2os8AkAWB0awg (envelope-from ) for ; Wed, 14 Oct 2026 12:50:13 -0400 Received: by simark.ca (Postfix, from userid 112) id CFC771E04E; Wed, 14 Oct 2026 12:50:13 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-2.3 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED autolearn=ham autolearn_force=no version=4.0.1 Received: from vm01.sourceware.org (vm01.sourceware.org [38.145.34.32]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id D11DB1E04E for ; Wed, 14 Oct 2026 12:50:12 -0400 (EDT) Received: from vm01.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 716D44BA23E8 for ; Wed, 14 Oct 2026 16:50:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 716D44BA23E8 Received: from simark.ca (simark.ca [158.69.221.121]) by sourceware.org (Postfix) with ESMTPS id 1BCEE4BA2E14; Wed, 14 Oct 2026 16:48:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1BCEE4BA2E14 Authentication-Results: sourceware.org; dmarc=fail (p=none dis=none) header.from=efficios.com Authentication-Results: sourceware.org; spf=fail smtp.mailfrom=efficios.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 1BCEE4BA2E14 Authentication-Results: sourceware.org; arc=none smtp.remote-ip=158.69.221.121 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791996514; cv=none; b=bx736uyb9zdZ3wLEtrskQwCBTo9/XkKqWFUfX1XmElQaCKfVOj3U4lBskUcSl3j1WK9hs9oXHSocP3Cbba1Ja2fxV7UuSnZ23n58gePQdgzsy4dr5sDPYsoLYT7JlM7uCxNUb4m9LcwKt4xgmLxgviZu1jphv5fV5CEg0Ic1QtQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1791996514; c=relaxed/simple; bh=94w0ECUSZf6khApR8s0V0W5TQsis4bE29o6dd9TyVuk=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=C577Q7ZRwzHjOLFBmnS06AbAO4LSB2oPDNX4BHN7M4rhuoDN2nPRjRUFUpF/BMIKBgvlSdPvU7WdovTIAuGV/oLLnO4hXunS5XTZaBtQ0VgkauaJcEyEhOSWet5rkf7mfErNCi7UxjKbGYdw/pZbcYsBfGkJjStsOUqZYFb7vUo= ARC-Authentication-Results: i=1; sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 1BCEE4BA2E14 Received: by simark.ca (Postfix) id 9371B1E04F; Wed, 14 Oct 2026 12:48:32 -0400 (EDT) From: Simon Marchi To: gcc-patches@sourceware.org, gdb-patches@sourceware.org Cc: Simon Marchi Subject: [PATCH v2 1/2] gdb: add selftests for split_name Date: Wed, 14 Oct 2026 12:46:58 -0400 Message-ID: <20261014164830.358677-2-simon.marchi@efficios.com> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261005052602.1288766-3-simon.marchi@polymtl.ca> References: <20261005052602.1288766-3-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces~public-inbox=simark.ca@sourceware.org Add selftests for split_name, covering all splitting styles. Some output is questionable, but the goal is to document the current behavior. Change-Id: Ib31a6f01762e84eefff647e0c141975ea23d469f --- gdb/split-name.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) diff --git a/gdb/split-name.c b/gdb/split-name.c index bc145909c2e8..cb740a968d49 100644 --- a/gdb/split-name.c +++ b/gdb/split-name.c @@ -19,6 +19,8 @@ #include "split-name.h" #include "cp-support.h" +#include "gdbsupport/enumerate.h" +#include "gdbsupport/selftest.h" /* See split-name.h. */ @@ -64,3 +66,190 @@ split_name (const char *name, split_style style) result.emplace_back (&name[previous_len]); return result; } + +#if GDB_SELF_TEST + +namespace selftests { + +/* Return a string representation of COMPONENTS, for debugging. */ + +static std::string +components_to_string (const std::vector &components) +{ + std::string str = "{"; + + for (auto [i, component] : gdb::ranges::views::enumerate (components)) + { + if (i > 0) + str += ","; + + str += " \""; + str += component; + str += "\""; + } + + str += " }"; + return str; +} + +/* Check that splitting NAME using STYLE gives EXPECTED. */ + +static void +check_split_name (const char *name, split_style style, + const std::vector &expected) +{ + std::vector result = split_name (name, style); + + if (result != expected) + debug_printf ("split_name (\"%s\"): got %s, expected %s\n", name, + components_to_string (result).c_str (), + components_to_string (expected).c_str ()); + + SELF_CHECK (result == expected); +} + +static void +test_split_name_none () +{ + /* No splitting is ever done. */ + check_split_name ("", split_style::NONE, { "" }); + check_split_name ("foo", split_style::NONE, { "foo" }); + check_split_name ("a::b", split_style::NONE, { "a::b" }); + check_split_name ("a.b", split_style::NONE, { "a.b" }); + check_split_name ("a..b", split_style::NONE, { "a..b" }); + check_split_name ("::", split_style::NONE, { "::" }); + check_split_name (".", split_style::NONE, { "." }); +} + +static void +test_split_name_cxx () +{ + /* Simple names. */ + check_split_name ("", split_style::CXX, { "" }); + check_split_name ("foo", split_style::CXX, { "foo" }); + check_split_name ("a::b", split_style::CXX, { "a", "b" }); + check_split_name ("a::b::c", split_style::CXX, { "a", "b", "c" }); + + /* Dots are not separators. */ + check_split_name ("a.b", split_style::CXX, { "a.b" }); + check_split_name ("a..b::c", split_style::CXX, { "a..b", "c" }); + + /* A single colon is not a separator. */ + check_split_name ("a:b", split_style::CXX, { "a:b" }); + check_split_name ("a:::b", split_style::CXX, { "a", ":b" }); + + /* Templates. */ + check_split_name ("a", split_style::CXX, { "a" }); + check_split_name ("a::d", split_style::CXX, { "a", "d" }); + check_split_name ("a::b::g", split_style::CXX, + { "a", "b", "g" }); + check_split_name ("a>::f", split_style::CXX, + { "a>", "f" }); + check_split_name ("std::vector >::size", + split_style::CXX, + { "std", "vector >", "size" }); + + /* Parentheses: function parameters, function-local names, + anonymous namespaces. */ + check_split_name ("a::b(c::d)", split_style::CXX, { "a", "b(c::d)" }); + check_split_name ("a::b(c::d) const", split_style::CXX, + { "a", "b(c::d) const" }); + check_split_name ("foo(int)::bar", split_style::CXX, + { "foo(int)", "bar" }); + check_split_name ("(anonymous namespace)::foo", split_style::CXX, + { "(anonymous namespace)", "foo" }); + check_split_name ("a::(anonymous namespace)::foo", split_style::CXX, + { "a", "(anonymous namespace)", "foo" }); + + /* Operators, which can contain characters that would otherwise + be treated specially. */ + check_split_name ("A::operator<", split_style::CXX, + { "A", "operator<" }); + check_split_name ("A::operator<<", split_style::CXX, + { "A", "operator<<" }); + check_split_name ("A::operator>", split_style::CXX, + { "A", "operator>" }); + check_split_name ("A::operator>>", split_style::CXX, + { "A", "operator>>" }); + check_split_name ("A::operator->", split_style::CXX, + { "A", "operator->" }); + check_split_name ("A::operator()", split_style::CXX, + { "A", "operator()" }); + check_split_name ("A::operator< ", split_style::CXX, + { "A", "operator< " }); + check_split_name ("A::operator<(A const&, A const&)", split_style::CXX, + { "A", "operator<(A const&, A const&)" }); + + /* "operator" as part of an identifier is not an operator. */ + check_split_name ("cooperator::x", split_style::CXX, + { "cooperator", "x" }); + check_split_name ("operator_foo::x", split_style::CXX, + { "operator_foo", "x" }); + + /* Malformed names are returned as a single component. */ + check_split_name ("ab::c", split_style::CXX, { "a>b::c" }); + check_split_name ("a)b::c", split_style::CXX, { "a)b::c" }); + + /* Leading, trailing or consecutive separators produce empty + components. */ + check_split_name ("::", split_style::CXX, { "", "" }); + check_split_name ("::a", split_style::CXX, { "", "a" }); + check_split_name ("a::", split_style::CXX, { "a", "" }); + check_split_name ("a::::b", split_style::CXX, { "a", "", "b" }); +} + +static void +test_split_name_dot_style () +{ + /* Simple names. */ + check_split_name ("", split_style::DOT_STYLE, { "" }); + check_split_name ("foo", split_style::DOT_STYLE, { "foo" }); + check_split_name ("a.b", split_style::DOT_STYLE, { "a", "b" }); + check_split_name ("a.b.c", split_style::DOT_STYLE, { "a", "b", "c" }); + check_split_name ("pkg.sub.func", split_style::DOT_STYLE, + { "pkg", "sub", "func" }); + + /* "::" is not a separator. */ + check_split_name ("a::b", split_style::DOT_STYLE, { "a::b" }); + check_split_name ("a::b.c", split_style::DOT_STYLE, { "a::b", "c" }); + + /* Go method names. */ + check_split_name ("main.(*T).Method", split_style::DOT_STYLE, + { "main", "(*T)", "Method" }); + + /* Ada operator names. */ + check_split_name ("pkg.\"+\"", split_style::DOT_STYLE, + { "pkg", "\"+\"" }); + + /* Leading, trailing or consecutive dots produce empty components. */ + check_split_name (".", split_style::DOT_STYLE, { "", "" }); + check_split_name ("..", split_style::DOT_STYLE, { "", "", "" }); + check_split_name (".a", split_style::DOT_STYLE, { "", "a" }); + check_split_name ("a.", split_style::DOT_STYLE, { "a", "" }); + check_split_name ("a..b", split_style::DOT_STYLE, { "a", "", "b" }); + check_split_name (".a.b", split_style::DOT_STYLE, { "", "a", "b" }); + check_split_name ("a.b.", split_style::DOT_STYLE, { "a", "b", "" }); + check_split_name ("a.b..c", split_style::DOT_STYLE, + { "a", "b", "", "c" }); + check_split_name ("a..b.c", split_style::DOT_STYLE, + { "a", "", "b", "c" }); + check_split_name ("a...b", split_style::DOT_STYLE, { "a", "", "", "b" }); +} + +} /* namespace selftests */ + +#endif /* GDB_SELF_TEST */ + +INIT_GDB_FILE (split_name) +{ +#if GDB_SELF_TEST + selftests::register_test ("split_name_none", + selftests::test_split_name_none); + selftests::register_test ("split_name_cxx", + selftests::test_split_name_cxx); + selftests::register_test ("split_name_dot_style", + selftests::test_split_name_dot_style); +#endif +} -- 2.56.0