]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Improve tests for std::regex_traits::lookup_classname [PR124015]
authorJonathan Wakely <jwakely@redhat.com>
Tue, 10 Feb 2026 20:01:32 +0000 (20:01 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 11 Feb 2026 11:00:02 +0000 (11:00 +0000)
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 <tkaminsk@redhat.com>
libstdc++-v3/testsuite/28_regex/traits/char/lookup_classname.cc
libstdc++-v3/testsuite/28_regex/traits/wchar_t/lookup_classname.cc

index 0f277bce532cb8bad2777e6076414ff8dd524c30..2e5c1c7118185f8b89d6978d3fb7fbf7d6c54b81 100644 (file)
@@ -28,6 +28,7 @@
 #include <regex>
 #include <forward_list>
 #include <string.h>
+#include <ctype.h>
 #include <testsuite_hooks.h>
 
 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<CharT> 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;
 }
index 18e289868a179bbaa4e12180f0bfa83a8d5d3294..36db7bbb949d487dd656721c754a750591b77104 100644 (file)
@@ -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<CharT> 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;
 }