aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Shen <timshen@google.com>2017-09-11 19:02:34 +0000
committerTim Shen <timshen@gcc.gnu.org>2017-09-11 19:02:34 +0000
commit3366a4740876b62c7e40f1ab74d3ed65bd698606 (patch)
treed213ab8f4b3ae4ae7945be932ecebbb19faab4fe
parent47d7966a70e1fcf39c11402f02ca3931a02f21eb (diff)
downloadgcc-3366a4740876b62c7e40f1ab74d3ed65bd698606.zip
gcc-3366a4740876b62c7e40f1ab74d3ed65bd698606.tar.gz
gcc-3366a4740876b62c7e40f1ab74d3ed65bd698606.tar.bz2
re PR libstdc++/71500 (regex::icase only works on first character in a range)
PR libstdc++/71500 * include/bits/regex_executor.tcc: Support icase in regex_tratis<...> for back reference matches. * testsuite/28_regex/regression.cc: Test case. From-SVN: r251982
-rw-r--r--libstdc++-v3/ChangeLog7
-rw-r--r--libstdc++-v3/include/bits/regex_executor.tcc55
-rw-r--r--libstdc++-v3/testsuite/28_regex/regression.cc12
3 files changed, 71 insertions, 3 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 33b9cdb..7163c64 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,10 @@
+2017-09-11 Tim Shen <timshen@google.com>
+
+ PR libstdc++/71500
+ * include/bits/regex_executor.tcc: Support icase in regex_tratis<...>
+ for back reference matches.
+ * testsuite/28_regex/regression.cc: Test case.
+
2017-09-11 Jonathan Wakely <jwakely@redhat.com>
* testsuite/21_strings/basic_string/lwg2946.cc: Adjust for
diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc
index 226e058..f6149fe 100644
--- a/libstdc++-v3/include/bits/regex_executor.tcc
+++ b/libstdc++-v3/include/bits/regex_executor.tcc
@@ -335,6 +335,54 @@ namespace __detail
_M_states._M_queue(__state._M_next, _M_cur_results);
}
+ template<typename _BiIter, typename _TraitsT>
+ struct _Backref_matcher
+ {
+ _Backref_matcher(bool __icase, const _TraitsT& __traits)
+ : _M_traits(__traits) { }
+
+ bool
+ _M_apply(_BiIter __expected_begin,
+ _BiIter __expected_end, _BiIter __actual_begin,
+ _BiIter __actual_end)
+ {
+ return _M_traits.transform(__expected_begin, __expected_end)
+ == _M_traits.transform(__actual_begin, __actual_end);
+ }
+
+ const _TraitsT& _M_traits;
+ };
+
+ template<typename _BiIter, typename _CharT>
+ struct _Backref_matcher<_BiIter, std::regex_traits<_CharT>>
+ {
+ using _TraitsT = std::regex_traits<_CharT>;
+ _Backref_matcher(bool __icase, const _TraitsT& __traits)
+ : _M_icase(__icase), _M_traits(__traits) { }
+
+ bool
+ _M_apply(_BiIter __expected_begin,
+ _BiIter __expected_end, _BiIter __actual_begin,
+ _BiIter __actual_end)
+ {
+ if (!_M_icase)
+ return std::equal(__expected_begin, __expected_end,
+ __actual_begin, __actual_end);
+ typedef std::ctype<_CharT> __ctype_type;
+ const auto& __fctyp = use_facet<__ctype_type>(_M_traits.getloc());
+ return std::equal(__expected_begin, __expected_end,
+ __actual_begin, __actual_end,
+ [this, &__fctyp](_CharT __lhs, _CharT __rhs)
+ {
+ return __fctyp.tolower(__lhs)
+ == __fctyp.tolower(__rhs);
+ });
+ }
+
+ bool _M_icase;
+ const _TraitsT& _M_traits;
+ };
+
// First fetch the matched result from _M_cur_results as __submatch;
// then compare it with
// (_M_current, _M_current + (__submatch.second - __submatch.first)).
@@ -355,9 +403,10 @@ namespace __detail
__last != _M_end && __tmp != __submatch.second;
++__tmp)
++__last;
- if (_M_re._M_automaton->_M_traits.transform(__submatch.first,
- __submatch.second)
- == _M_re._M_automaton->_M_traits.transform(_M_current, __last))
+ if (_Backref_matcher<_BiIter, _TraitsT>(
+ _M_re.flags() & regex_constants::icase,
+ _M_re._M_automaton->_M_traits)._M_apply(
+ __submatch.first, __submatch.second, _M_current, __last))
{
if (__last != _M_current)
{
diff --git a/libstdc++-v3/testsuite/28_regex/regression.cc b/libstdc++-v3/testsuite/28_regex/regression.cc
index ee4d3e1..3fa9022 100644
--- a/libstdc++-v3/testsuite/28_regex/regression.cc
+++ b/libstdc++-v3/testsuite/28_regex/regression.cc
@@ -93,6 +93,17 @@ test06()
}
}
+// PR libstdc++/71500
+void
+test07()
+{
+ bool test [[gnu::unused]] = true;
+
+ VERIFY(regex_match_debug("abc abc", regex("([a-z]+) \\1", regex::icase)));
+ VERIFY(regex_match_debug("Abc abc", regex("([a-z]+) \\1", regex::icase)));
+ VERIFY(regex_match_debug("abc Abc", regex("([a-z]+) \\1", regex::icase)));
+}
+
int
main()
{
@@ -102,6 +113,7 @@ main()
test04();
test05();
test06();
+ test07();
return 0;
}