commit 2dc9acc2289801765d726c65996e9e0cddca0d6d Author: tim Date: Fri Oct 4 00:53:08 2013 -0400 2013-10-04 Tim Shen * include/bits/regex.h (__regex_match_impl<>, __regex_match_testsuite<>, __regex_search_impl<>, __regex_search_testsuite<>): Declare. * include/bits/regex.tcc (__regex_match_impl<>, __regex_match_testsuite<>, __regex_search_impl<>, __regex_search_testsuite<>): Implement. These *_testsuite should be used in testcaes, to force test two executors. * include/bits/regex_executor.tcc: Do not resize __cur_results to prevent from out of bound access during backtracking. * testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc: Use *_testsuite. * testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc: Same. * testsuite/28_regex/algorithms/regex_match/basic/string_01.cc: Same. * testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc: Same. * testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc: Same. * testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/53622.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/57173.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/58576.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc: Same. * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/ cstring_bracket_01.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/ cstring_questionmark.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/string_any.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/ string_range_00_03.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/ string_range_01_03.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/ string_range_02_03.cc: Same. * testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc: Same. * testsuite/28_regex/algorithms/regex_search/basic/string_01.cc: Same. * testsuite/28_regex/algorithms/regex_search/ecma/assertion.cc: Same. * testsuite/28_regex/algorithms/regex_search/ecma/flags.cc: Same. * testsuite/28_regex/algorithms/regex_search/ecma/greedy.cc: Same. * testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc: Same. * testsuite/28_regex/init-list.cc: Same. * testsuite/28_regex/match_results/format.cc: Same. diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h index 4d7e7d7..eb08a27 100644 --- a/libstdc++-v3/include/bits/regex.h +++ b/libstdc++-v3/include/bits/regex.h @@ -32,6 +32,25 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +namespace __detail +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + bool + __regex_match_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Cp, _Rp>&, + regex_constants::match_flag_type); + + template + bool + __regex_search_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Cp, _Rp>&, + regex_constants::match_flag_type); + +_GLIBCXX_END_NAMESPACE_VERSION +} + /** * @addtogroup regex * @{ @@ -722,19 +741,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const basic_regex<_CharT, _TraitsT>&, regex_constants::match_flag_type); - template + template friend bool - regex_match(_Bp, _Bp, - match_results<_Bp, _Ap>&, - const basic_regex<_Cp, _Rp>&, - regex_constants::match_flag_type); + __detail::__regex_match_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Cp, _Rp>&, + regex_constants::match_flag_type); - template + template friend bool - regex_search(_Bp, _Bp, - match_results<_Bp, _Ap>&, - const basic_regex<_Cp, _Rp>&, - regex_constants::match_flag_type); + __detail::__regex_search_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Cp, _Rp>&, + regex_constants::match_flag_type); template friend class __detail::_Executor; @@ -1852,20 +1869,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION friend class regex_iterator; template + typename _Ch_type, typename _Rx_traits, int> friend bool - regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&, - const basic_regex<_Ch_type, - _Rx_traits>&, - regex_constants::match_flag_type); + __detail::__regex_match_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Ch_type, _Rx_traits>&, + regex_constants::match_flag_type); - template + template friend bool - regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&, - const basic_regex<_Ch_type, - _Rx_traits>&, - regex_constants::match_flag_type); + __detail::__regex_search_impl(_Bp, _Bp, match_results<_Bp, _Ap>&, + const basic_regex<_Cp, _Rp>&, + regex_constants::match_flag_type); _Bi_iter _M_begin; bool _M_in_iterator; diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc index 24316d2..addc6a6 100644 --- a/libstdc++-v3/include/bits/regex.tcc +++ b/libstdc++-v3/include/bits/regex.tcc @@ -32,6 +32,265 @@ namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION +namespace __detail +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + bool + __regex_match_impl(_BiIter __s, + _BiIter __e, + match_results<_BiIter, _Alloc>& __m, + const basic_regex<_CharT, _TraitsT>& __re, + regex_constants::match_flag_type __flags) + { + if (__re._M_automaton == nullptr) + return false; + + typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m; + auto __size = __re._M_automaton->_M_sub_count(); + __size += 2; + __res.resize(__size); + for (decltype(__size) __i = 0; __i < __size; ++__i) + __res[__i].matched = false; + + typedef std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>> + _ExecutorPtr; + typedef _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _DFSExecutorT; + typedef _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _BFSExecutorT; + + _ExecutorPtr __executor; + if (__policy == 0) // dispatcher + __executor = __get_executor(__s, __e, __res, __re, __flags); + else if (__policy == 1) // _DFSExecutor + __executor = _ExecutorPtr(new _DFSExecutorT(__s, __e, __res, __re, + __flags)); + else // _BFSExecutor + __executor = _ExecutorPtr(new _BFSExecutorT(__s, __e, __res, __re, + __flags)); + + if (__executor->_M_match()) + { + for (auto __it : __res) + if (!__it.matched) + __it.first = __it.second = __e; + auto& __pre = __res[__res.size()-2]; + auto& __suf = __res[__res.size()-1]; + __pre.matched = false; + __pre.first = __s; + __pre.second = __s; + __suf.matched = false; + __suf.first = __e; + __suf.second = __e; + return true; + } + return false; + } + + template + bool + __regex_match_testsuite(_Bi_iter __s, + _Bi_iter __e, + match_results<_Bi_iter, _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + auto res1 = __regex_match_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, 0> + (__s, __e, __m, __re, __flags); + match_results<_Bi_iter, _Alloc> __mm; + auto res2 = __regex_match_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, 1> + (__s, __e, __mm, __re, __flags); + if (res1 == res2 && __m == __mm) + return res1; + __throw_regex_error(regex_constants::error_brace); + } + + template + inline bool + __regex_match_testsuite(_Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return __regex_match_testsuite(__first, __last, __what, __re, __flags); + } + + template + inline bool + __regex_match_testsuite(const _Ch_type* __s, + match_results& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return __regex_match_testsuite(__s, __s + _Rx_traits::length(__s), + __m, __re, __f); } + + template + inline bool + __regex_match_testsuite(const basic_string<_Ch_type, _Ch_traits, + _Ch_alloc>& __s, + match_results::const_iterator, + _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return __regex_match_testsuite(__s.begin(), __s.end(), + __m, __re, __flags); } + + template + inline bool + __regex_match_testsuite(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return __regex_match_testsuite(__s, __s + _Rx_traits::length(__s), + __re, __f); } + + template + inline bool + __regex_match_testsuite(const basic_string<_Ch_type, _Ch_traits, + _Str_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return __regex_match_testsuite(__s.begin(), __s.end(), __re, __flags); } + + template + bool + __regex_search_impl(_BiIter __s, _BiIter __e, + match_results<_BiIter, _Alloc>& __m, + const basic_regex<_CharT, _TraitsT>& __re, + regex_constants::match_flag_type __flags) + { + if (__re._M_automaton == nullptr) + return false; + + typename match_results<_BiIter, _Alloc>::_Base_type& __res = __m; + auto __size = __re._M_automaton->_M_sub_count(); + __size += 2; + __res.resize(__size); + for (decltype(__size) __i = 0; __i < __size; ++__i) + __res[__i].matched = false; + + typedef std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>> + _ExecutorPtr; + typedef _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _DFSExecutorT; + typedef _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _BFSExecutorT; + + _ExecutorPtr __executor; + if (__policy == 0) // dispatcher + __executor = __get_executor(__s, __e, __res, __re, __flags); + else if (__policy == 1) // _DFSExecutor + __executor = _ExecutorPtr(new _DFSExecutorT(__s, __e, __res, __re, + __flags)); + else // _BFSExecutor + __executor = _ExecutorPtr(new _BFSExecutorT(__s, __e, __res, __re, + __flags)); + + if (__executor->_M_search()) + { + for (auto __it : __res) + if (!__it.matched) + __it.first = __it.second = __e; + auto& __pre = __res[__res.size()-2]; + auto& __suf = __res[__res.size()-1]; + __pre.first = __s; + __pre.second = __res[0].first; + __pre.matched = (__pre.first != __pre.second); + __suf.first = __res[0].second; + __suf.second = __e; + __suf.matched = (__suf.first != __suf.second); + return true; + } + return false; + } + + template + bool + __regex_search_testsuite(_Bi_iter __s, _Bi_iter __e, + match_results<_Bi_iter, _Alloc>& __m, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + auto res1 = __regex_search_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, 0> + (__s, __e, __m, __re, __flags); + match_results<_Bi_iter, _Alloc> __mm; + auto res2 = __regex_search_impl<_Bi_iter, _Alloc, _Ch_type, _Rx_traits, 1> + (__s, __e, __mm, __re, __flags); + if (res1 == res2 && __m == __mm) + return res1; + __throw_regex_error(regex_constants::error_brace); + } + + template + inline bool + __regex_search_testsuite(_Bi_iter __first, _Bi_iter __last, + const basic_regex<_Ch_type, _Rx_traits>& __re, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { + match_results<_Bi_iter> __what; + return __regex_search_testsuite(__first, __last, __what, __re, __flags); + } + + template + inline bool + __regex_search_testsuite(const _Ch_type* __s, + match_results& __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return __regex_search_testsuite(__s, __s + _Rx_traits::length(__s), + __m, __e, __f); } + + template + inline bool + __regex_search_testsuite(const _Ch_type* __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return __regex_search_testsuite(__s, __s + _Rx_traits::length(__s), + __e, __f); } + + template + inline bool + __regex_search_testsuite(const basic_string<_Ch_type, _Ch_traits, + _String_allocator>& __s, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __flags + = regex_constants::match_default) + { return __regex_search_testsuite(__s.begin(), __s.end(), __e, __flags); } + + template + inline bool + __regex_search_testsuite(const basic_string<_Ch_type, _Ch_traits, + _Ch_alloc>& __s, + match_results::const_iterator, _Alloc>& + __m, + const basic_regex<_Ch_type, _Rx_traits>& __e, + regex_constants::match_flag_type __f + = regex_constants::match_default) + { return __regex_search_testsuite(__s.begin(), __s.end(), __m, __e, __f); } + +_GLIBCXX_END_NAMESPACE_VERSION +} // __detail + template template typename regex_traits<_Ch_type>::string_type @@ -404,34 +663,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) - { - if (__re._M_automaton == nullptr) - return false; - - typename match_results<_Bi_iter, _Alloc>::_Base_type& __res = __m; - auto __size = __re._M_automaton->_M_sub_count(); - __size += 2; - __res.resize(__size); - for (decltype(__size) __i = 0; __i < __size; ++__i) - __res[__i].matched = false; - - if (__detail::__get_executor(__s, __e, __res, __re, __flags)->_M_match()) - { - for (auto __it : __res) - if (!__it.matched) - __it.first = __it.second = __e; - auto& __pre = __res[__res.size()-2]; - auto& __suf = __res[__res.size()-1]; - __pre.matched = false; - __pre.first = __s; - __pre.second = __s; - __suf.matched = false; - __suf.first = __e; - __suf.second = __e; - return true; - } - return false; - } + { return __detail::__regex_match_impl<_Bi_iter, _Alloc, + _Ch_type, _Rx_traits, 0>(__s, __e, __m, __re, __flags); } template @@ -441,35 +674,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION const basic_regex<_Ch_type, _Rx_traits>& __re, regex_constants::match_flag_type __flags = regex_constants::match_default) - { - if (__re._M_automaton == nullptr) - return false; - - typename match_results<_Bi_iter, _Alloc>::_Base_type& __res = __m; - auto __size = __re._M_automaton->_M_sub_count(); - __size += 2; - __res.resize(__size); - for (decltype(__size) __i = 0; __i < __size; ++__i) - __res[__i].matched = false; - - if (__detail::__get_executor(__first, __last, __res, __re, __flags) - ->_M_search()) - { - for (auto __it : __res) - if (!__it.matched) - __it.first = __it.second = __last; - auto& __pre = __res[__res.size()-2]; - auto& __suf = __res[__res.size()-1]; - __pre.first = __first; - __pre.second = __res[0].first; - __pre.matched = (__pre.first != __pre.second); - __suf.first = __res[0].second; - __suf.second = __last; - __suf.matched = (__suf.first != __suf.second); - return true; - } - return false; - } + { return __detail::__regex_search_impl<_Bi_iter, _Alloc, + _Ch_type, _Rx_traits, 0>(__first, __last, __m, __re, __flags); } template diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc index 60ba952..8e705bb 100644 --- a/libstdc++-v3/include/bits/regex_executor.tcc +++ b/libstdc++-v3/include/bits/regex_executor.tcc @@ -387,13 +387,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { if (_M_re.flags() & regex_constants::nosubs) { - // truncate - __cur_results.resize(3); + if (__cur_results[0].matched) + _M_results[0] = __cur_results[0]; _M_results.resize(3); } - for (unsigned int __i = 0; __i < __cur_results.size(); ++__i) - if (__cur_results[__i].matched) - _M_results[__i] = __cur_results[__i]; + else + for (unsigned int __i = 0; __i < __cur_results.size(); ++__i) + if (__cur_results[__i].matched) + _M_results[__i] = __cur_results[__i]; } template