On Wed, Feb 11, 2026 at 1:21 AM Jonathan Wakely <[email protected]> wrote:

> 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 <[email protected]>
> ---
>
> v2: Extended wchar_t/lookup_classname.cc with the same additions as
> char/lookup_classname.cc
>
> Tested x86_64-linux and aarch64-linux.
>
LGTM.

>
>  .../28_regex/traits/char/lookup_classname.cc  | 66 +++++++++++++++++++
>  .../traits/wchar_t/lookup_classname.cc        | 65 ++++++++++++++++++
>  2 files changed, 131 insertions(+)
>
> 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 0f277bce532c..2e5c1c711818 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 <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;
>  }
> 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 18e289868a17..36db7bbb949d 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<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;
>  }
> --
> 2.52.0
>
>

Reply via email to