From: Jonathan Wakely Date: Tue, 10 Feb 2026 20:01:32 +0000 (+0000) Subject: libstdc++: Improve tests for std::regex_traits::lookup_classname [PR124015] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=81e492ba723f9cfdd69d4badfdec1c00983952a9;p=thirdparty%2Fgcc.git libstdc++: Improve tests for std::regex_traits::lookup_classname [PR124015] libstdc++-v3/ChangeLog: PR libstdc++/124015 * testsuite/28_regex/traits/char/lookup_classname.cc: Check for correct result for unrecognized classname. Check that lookup is case insensitive. Check that all required classnames are recognized. Check that icase flag only affects "lower" and "upper". * testsuite/28_regex/traits/wchar_t/lookup_classname.cc: Likewise. Reviewed-by: Tomasz KamiƄski --- diff --git a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc index 0f277bce532..2e5c1c71181 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc @@ -28,6 +28,7 @@ #include #include #include +#include #include void @@ -67,10 +68,75 @@ test03() VERIFY(traits.isctype('C', traits.lookup_classname(s.begin(), s.end(), true))); } +void +test04() +{ + // Transform "string" into "StRiNg" + auto mix_case = [](std::string s) { + int i = 0; + for (auto& ch : s) + if (++i % 2) + ch = toupper(ch); + return s; + }; + + typedef char CharT; + typedef std::regex_traits traits; + traits t; + + auto lookup = [&t](const std::string& s, bool icase) { + return t.lookup_classname(s.begin(), s.end(), icase); + }; + + VERIFY( lookup("", false) == 0 ); + VERIFY( lookup(":::not a valid classname:::", false) == 0 ); + VERIFY( lookup(":::not a valid classname:::", true) == 0 ); + VERIFY( lookup("alnu", false) == 0 ); + VERIFY( lookup("alnumb", false) == 0 ); + VERIFY( lookup("x", false) == 0 ); + VERIFY( lookup("di", false) == 0 ); + VERIFY( lookup("digi", false) == 0 ); + VERIFY( lookup("digix", false) == 0 ); + VERIFY( lookup(std::string{"d\0i", 3}, false) == 0 ); + VERIFY( lookup(std::string{"digit\0", 6}, false) == 0 ); + VERIFY( lookup(std::string{"digit\0bad", 9}, false) == 0 ); + + for (std::string cls : { "alnum", "alpha", "blank", "cntrl", "digit", + "graph", "lower", "print", "punct", "space", + "upper", "xdigit", "d", "s", "w" }) + { + traits::char_class_type val = lookup(cls, false); + // val should be non-zero: + VERIFY( val != 0 ); + // val is independent of the case of the name, + // i.e. "alpha" and "ALPHA" and "AlPhA" give same result: + VERIFY( lookup(mix_case(cls), false) == val ); + + // Repeat same checks for icase=true. + traits::char_class_type ival = lookup(cls, true); + VERIFY( ival != 0 ); + VERIFY( lookup(mix_case(cls), true) == ival ); + + if (cls == "lower" || cls == "upper") // icase=true should affect value + { + VERIFY( ival != val ); + VERIFY( ival == lookup("alpha", false) ); + } + else + VERIFY( ival == val ); + + if (cls == "d") + VERIFY( val == lookup("digit", false) ); + else if (cls == "s") + VERIFY( val == lookup("space", false) ); + } +} + int main() { test01(); test02(); test03(); + test04(); return 0; } diff --git a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc index 18e289868a1..36db7bbb949 100644 --- a/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc +++ b/libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc @@ -45,8 +45,73 @@ test01() #undef range } +void +test04() +{ + // Transform "string" into "StRiNg" + auto mix_case = [](std::wstring s) { + int i = 0; + for (auto& ch : s) + if (++i % 2) + ch = toupper(ch); + return s; + }; + + typedef wchar_t CharT; + typedef std::regex_traits traits; + traits t; + + auto lookup = [&t](const std::wstring& s, bool icase) { + return t.lookup_classname(s.begin(), s.end(), icase); + }; + + VERIFY( lookup(L"", false) == 0 ); + VERIFY( lookup(L":::not a valid classname:::", false) == 0 ); + VERIFY( lookup(L":::not a valid classname:::", true) == 0 ); + VERIFY( lookup(L"alnu", false) == 0 ); + VERIFY( lookup(L"alnumb", false) == 0 ); + VERIFY( lookup(L"x", false) == 0 ); + VERIFY( lookup(L"di", false) == 0 ); + VERIFY( lookup(L"digi", false) == 0 ); + VERIFY( lookup(L"digix", false) == 0 ); + VERIFY( lookup(std::wstring{L"d\0i", 3}, false) == 0 ); + VERIFY( lookup(std::wstring{L"digit\0", 6}, false) == 0 ); + VERIFY( lookup(std::wstring{L"digit\0bad", 9}, false) == 0 ); + + for (std::wstring cls : { L"alnum", L"alpha", L"blank", L"cntrl", L"digit", + L"graph", L"lower", L"print", L"punct", L"space", + L"upper", L"xdigit", L"d", L"s", L"w" }) + { + traits::char_class_type val = lookup(cls, false); + // val should be non-zero: + VERIFY( val != 0 ); + // val is independent of the case of the name, + // i.e. "alpha" and "ALPHA" and "AlPhA" give same result: + VERIFY( lookup(mix_case(cls), false) == val ); + + // Repeat same checks for icase=true. + traits::char_class_type ival = lookup(cls, true); + VERIFY( ival != 0 ); + VERIFY( lookup(mix_case(cls), true) == ival ); + + if (cls == L"lower" || cls == L"upper") // icase=true should affect value + { + VERIFY( ival != val ); + VERIFY( ival == lookup(L"alpha", false) ); + } + else + VERIFY( ival == val ); + + if (cls == L"d") + VERIFY( val == lookup(L"digit", false) ); + else if (cls == L"s") + VERIFY( val == lookup(L"space", false) ); + } +} + int main() { test01(); + test04(); return 0; }