Commit 4dae67e0 by Tim Shen Committed by Tim Shen

re PR libstdc++/61227 ([C++11] Regex [\w] does not work)

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
parent b9b7e07c
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> 2014-05-19 Jonathan Wakely <jwakely@redhat.com>
* python/libstdcxx/v6/printers.py: Use Python3 raise syntax. * python/libstdcxx/v6/printers.py: Use Python3 raise syntax.
......
...@@ -369,15 +369,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -369,15 +369,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif #endif
} }
// __neg should be true for \D, \S and \W only.
void 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(), auto __mask = _M_traits.lookup_classname(__s.data(),
__s.data() + __s.size(), __s.data() + __s.size(),
__icase); __icase);
if (__mask == 0) if (__mask == 0)
__throw_regex_error(regex_constants::error_ctype); __throw_regex_error(regex_constants::error_ctype);
if (!__neg)
_M_class_set |= __mask; _M_class_set |= __mask;
else
_M_neg_class_set.push_back(__mask);
#ifdef _GLIBCXX_DEBUG #ifdef _GLIBCXX_DEBUG
_M_is_ready = false; _M_is_ready = false;
#endif #endif
...@@ -435,6 +439,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -435,6 +439,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::vector<_CharT> _M_char_set; std::vector<_CharT> _M_char_set;
std::vector<_StringT> _M_equiv_set; std::vector<_StringT> _M_equiv_set;
std::vector<pair<_StrTransT, _StrTransT>> _M_range_set; std::vector<pair<_StrTransT, _StrTransT>> _M_range_set;
std::vector<_CharClassT> _M_neg_class_set;
_CharClassT _M_class_set; _CharClassT _M_class_set;
_TransT _M_translator; _TransT _M_translator;
const _TraitsT& _M_traits; const _TraitsT& _M_traits;
......
...@@ -397,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -397,7 +397,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_DEBUG_ASSERT(_M_value.size() == 1); _GLIBCXX_DEBUG_ASSERT(_M_value.size() == 1);
_BracketMatcher<_TraitsT, __icase, __collate> __matcher _BracketMatcher<_TraitsT, __icase, __collate> __matcher
(_M_ctype.is(_CtypeT::upper, _M_value[0]), _M_traits); (_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(); __matcher._M_ready();
_M_stack.push(_StateSeqT(_M_nfa, _M_stack.push(_StateSeqT(_M_nfa,
_M_nfa._M_insert_matcher(std::move(__matcher)))); _M_nfa._M_insert_matcher(std::move(__matcher))));
...@@ -428,7 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -428,7 +428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else if (_M_match_token(_ScannerT::_S_token_equiv_class_name)) else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
__matcher._M_add_equivalence_class(_M_value); __matcher._M_add_equivalence_class(_M_value);
else if (_M_match_token(_ScannerT::_S_token_char_class_name)) 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 else if (_M_try_char()) // [a
{ {
auto __ch = _M_value[0]; auto __ch = _M_value[0];
...@@ -451,6 +451,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -451,6 +451,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
} }
__matcher._M_add_char(__ch); __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 else
__throw_regex_error(regex_constants::error_brack); __throw_regex_error(regex_constants::error_brack);
} }
...@@ -527,6 +531,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -527,6 +531,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_traits.transform_primary(&__ch, &__ch+1)) _M_traits.transform_primary(&__ch, &__ch+1))
!= _M_equiv_set.end()) != _M_equiv_set.end())
__ret = true; __ret = true;
else
{
for (auto& __it : _M_neg_class_set)
if (!_M_traits.isctype(__ch, __it))
{
__ret = true;
break;
}
}
} }
if (_M_is_non_matching) if (_M_is_non_matching)
return !__ret; return !__ret;
......
...@@ -44,6 +44,16 @@ test01() ...@@ -44,6 +44,16 @@ test01()
VERIFY(regex_match_debug("_az", regex("\\w*"))); VERIFY(regex_match_debug("_az", regex("\\w*")));
VERIFY(regex_match_debug("!@#$%", regex("\\W*"))); VERIFY(regex_match_debug("!@#$%", regex("\\W*")));
VERIFY(!regex_match_debug("_01234", 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 int
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment