]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR libstdc++/61227 ([C++11] Regex [\w] does not work)
authorTim Shen <timshen91@gmail.com>
Tue, 20 May 2014 04:31:54 +0000 (04:31 +0000)
committerTim Shen <timshen@gcc.gnu.org>
Tue, 20 May 2014 04:31:54 +0000 (04:31 +0000)
2014-05-20  Tim Shen  <timshen91@gmail.com>

PR libstdc++/61227
* include/bits/regex_compiler.h
(_BracketMatcher<>::_M_add_character_class): Add negative character
class support.
* include/bits/regex_compiler.tcc (_BracketMatcher<>::_M_apply):
Likewise.
* testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc:
Add more testcases.

From-SVN: r210630

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/regex_compiler.h
libstdc++-v3/include/bits/regex_compiler.tcc
libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc

index 0b2bf8924dfa755c21fa490d6bb26962e93d22c8..247af1264e2ebf54a6bdb9675a40be34694cd71a 100644 (file)
@@ -1,3 +1,14 @@
+2014-05-20  Tim Shen  <timshen91@gmail.com>
+
+       PR libstdc++/61227
+       * include/bits/regex_compiler.h
+       (_BracketMatcher<>::_M_add_character_class): Add negative character
+       class support.
+       * include/bits/regex_compiler.tcc (_BracketMatcher<>::_M_apply):
+       Likewise.
+       * testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc:
+       Add more testcases.
+
 2014-05-19  Jonathan Wakely  <jwakely@redhat.com>
 
        * python/libstdcxx/v6/printers.py: Use Python3 raise syntax.
index d7e21624e3702150c4658a126a4b0d8241f98a02..52f7235c8dbbcc9fdb23aa85d3f1701e7524731c 100644 (file)
@@ -369,15 +369,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 #endif
       }
 
+      // __neg should be true for \D, \S and \W only.
       void
-      _M_add_character_class(const _StringT& __s)
+      _M_add_character_class(const _StringT& __s, bool __neg)
       {
        auto __mask = _M_traits.lookup_classname(__s.data(),
                                                 __s.data() + __s.size(),
                                                 __icase);
        if (__mask == 0)
          __throw_regex_error(regex_constants::error_ctype);
-       _M_class_set |= __mask;
+       if (!__neg)
+         _M_class_set |= __mask;
+       else
+         _M_neg_class_set.push_back(__mask);
 #ifdef _GLIBCXX_DEBUG
        _M_is_ready = false;
 #endif
@@ -387,7 +391,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_make_range(_CharT __l, _CharT __r)
       {
        _M_range_set.push_back(make_pair(_M_translator._M_transform(__l),
-                                     _M_translator._M_transform(__r)));
+                                        _M_translator._M_transform(__r)));
 #ifdef _GLIBCXX_DEBUG
        _M_is_ready = false;
 #endif
@@ -435,6 +439,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       std::vector<_CharT>                       _M_char_set;
       std::vector<_StringT>                     _M_equiv_set;
       std::vector<pair<_StrTransT, _StrTransT>> _M_range_set;
+      std::vector<_CharClassT>                  _M_neg_class_set;
       _CharClassT                               _M_class_set;
       _TransT                                   _M_translator;
       const _TraitsT&                           _M_traits;
index 3cf9e457ccd7c5844d69c33cf4c63a52e9d079a1..472cf1ff49c1b9606e8cf4e4a0360085e28e76a7 100644 (file)
@@ -397,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _GLIBCXX_DEBUG_ASSERT(_M_value.size() == 1);
       _BracketMatcher<_TraitsT, __icase, __collate> __matcher
        (_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits);
-      __matcher._M_add_character_class(_M_value);
+      __matcher._M_add_character_class(_M_value, false);
       __matcher._M_ready();
       _M_stack.push(_StateSeqT(_M_nfa,
        _M_nfa._M_insert_matcher(std::move(__matcher))));
@@ -428,7 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
        __matcher._M_add_equivalence_class(_M_value);
       else if (_M_match_token(_ScannerT::_S_token_char_class_name))
-       __matcher._M_add_character_class(_M_value);
+       __matcher._M_add_character_class(_M_value, false);
       else if (_M_try_char()) // [a
        {
          auto __ch = _M_value[0];
@@ -451,6 +451,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            }
          __matcher._M_add_char(__ch);
        }
+      else if (_M_match_token(_ScannerT::_S_token_quoted_class))
+       __matcher._M_add_character_class(_M_value,
+                                        _M_ctype.is(_CtypeT::upper,
+                                                    _M_value[0]));
       else
        __throw_regex_error(regex_constants::error_brack);
     }
@@ -527,6 +531,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                             _M_traits.transform_primary(&__ch, &__ch+1))
                   != _M_equiv_set.end())
            __ret = true;
+         else
+           {
+             for (auto& __it : _M_neg_class_set)
+               if (!_M_traits.isctype(__ch, __it))
+                 {
+                   __ret = true;
+                   break;
+                 }
+           }
        }
       if (_M_is_non_matching)
        return !__ret;
index e7280acbdbdea523606b352cb2b6015ba1a87a6a..86417323516d8352a436a7715c889c63ba1ec873 100644 (file)
@@ -44,6 +44,16 @@ test01()
   VERIFY(regex_match_debug("_az", regex("\\w*")));
   VERIFY(regex_match_debug("!@#$%", regex("\\W*")));
   VERIFY(!regex_match_debug("_01234", regex("\\W*")));
+
+  VERIFY(regex_match_debug("01", regex("[\\d]*")));
+  VERIFY(regex_match_debug("asdfjkl", regex("[\\D]*")));
+  VERIFY(!regex_match_debug("asdfjkl0", regex("[\\D]*")));
+  VERIFY(regex_match_debug("\r\t\v\f ", regex("[\\s]*")));
+  VERIFY(regex_match_debug("asdfjkl", regex("[\\S]*")));
+  VERIFY(!regex_match_debug("asdfjkl\r", regex("[\\S]*")));
+  VERIFY(regex_match_debug("_az", regex("[\\w]*")));
+  VERIFY(regex_match_debug("!@#$%", regex("[\\W]*")));
+  VERIFY(!regex_match_debug("_01234", regex("[\\W]*")));
 }
 
 int