[libcxx] Make regex_match backtrack when search fails
Summary: Fixes PR19851. alg.re.match/ecma.pass.cpp still XFAILS on linux, but after commenting out locale-related tests, it passes. I don't have a freebsd machine to produce a full pass. Reviewers: mclow.lists Subscribers: cfe-commits, emaste Differential Revision: https://reviews.llvm.org/D26026 git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@285352 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -865,7 +865,8 @@ enum match_flag_type
|
||||
format_sed = 1 << 8,
|
||||
format_no_copy = 1 << 9,
|
||||
format_first_only = 1 << 10,
|
||||
__no_update_pos = 1 << 11
|
||||
__no_update_pos = 1 << 11,
|
||||
__full_match = 1 << 12
|
||||
};
|
||||
|
||||
inline _LIBCPP_INLINE_VISIBILITY
|
||||
@@ -2984,10 +2985,12 @@ __lookahead<_CharT, _Traits>::__exec(__state& __s) const
|
||||
{
|
||||
match_results<const _CharT*> __m;
|
||||
__m.__init(1 + __exp_.mark_count(), __s.__current_, __s.__last_);
|
||||
bool __matched = __exp_.__match_at_start_ecma(__s.__current_, __s.__last_,
|
||||
__m,
|
||||
__s.__flags_ | regex_constants::match_continuous,
|
||||
__s.__at_first_ && __s.__current_ == __s.__first_);
|
||||
bool __matched = __exp_.__match_at_start_ecma(
|
||||
__s.__current_, __s.__last_,
|
||||
__m,
|
||||
(__s.__flags_ | regex_constants::match_continuous) &
|
||||
~regex_constants::__full_match,
|
||||
__s.__at_first_ && __s.__current_ == __s.__first_);
|
||||
if (__matched != __invert_)
|
||||
{
|
||||
__s.__do_ = __state::__accept_but_not_consume;
|
||||
@@ -5555,12 +5558,18 @@ basic_regex<_CharT, _Traits>::__match_at_start_ecma(
|
||||
switch (__s.__do_)
|
||||
{
|
||||
case __state::__end_state:
|
||||
if (__flags & regex_constants::match_not_null &&
|
||||
if ((__flags & regex_constants::match_not_null) &&
|
||||
__s.__current_ == __first)
|
||||
{
|
||||
__states.pop_back();
|
||||
break;
|
||||
}
|
||||
if ((__flags & regex_constants::__full_match) &&
|
||||
__s.__current_ != __last)
|
||||
{
|
||||
__states.pop_back();
|
||||
break;
|
||||
}
|
||||
__m.__matches_[0].first = __first;
|
||||
__m.__matches_[0].second = _VSTD::next(__first, __s.__current_ - __first);
|
||||
__m.__matches_[0].matched = true;
|
||||
@@ -5624,12 +5633,18 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_nosubs(
|
||||
switch (__s.__do_)
|
||||
{
|
||||
case __state::__end_state:
|
||||
if (__flags & regex_constants::match_not_null &&
|
||||
if ((__flags & regex_constants::match_not_null) &&
|
||||
__s.__current_ == __first)
|
||||
{
|
||||
__states.pop_back();
|
||||
break;
|
||||
}
|
||||
if ((__flags & regex_constants::__full_match) &&
|
||||
__s.__current_ != __last)
|
||||
{
|
||||
__states.pop_back();
|
||||
break;
|
||||
}
|
||||
if (!__matched || __highest_j < __s.__current_ - __s.__first_)
|
||||
__highest_j = __s.__current_ - __s.__first_;
|
||||
__matched = true;
|
||||
@@ -5715,12 +5730,18 @@ basic_regex<_CharT, _Traits>::__match_at_start_posix_subs(
|
||||
switch (__s.__do_)
|
||||
{
|
||||
case __state::__end_state:
|
||||
if (__flags & regex_constants::match_not_null &&
|
||||
if ((__flags & regex_constants::match_not_null) &&
|
||||
__s.__current_ == __first)
|
||||
{
|
||||
__states.pop_back();
|
||||
break;
|
||||
}
|
||||
if ((__flags & regex_constants::__full_match) &&
|
||||
__s.__current_ != __last)
|
||||
{
|
||||
__states.pop_back();
|
||||
break;
|
||||
}
|
||||
if (!__matched || __highest_j < __s.__current_ - __s.__first_)
|
||||
{
|
||||
__highest_j = __s.__current_ - __s.__first_;
|
||||
@@ -5951,8 +5972,10 @@ regex_match(_BidirectionalIterator __first, _BidirectionalIterator __last,
|
||||
const basic_regex<_CharT, _Traits>& __e,
|
||||
regex_constants::match_flag_type __flags = regex_constants::match_default)
|
||||
{
|
||||
bool __r = _VSTD::regex_search(__first, __last, __m, __e,
|
||||
__flags | regex_constants::match_continuous);
|
||||
bool __r = _VSTD::regex_search(
|
||||
__first, __last, __m, __e,
|
||||
__flags | regex_constants::match_continuous |
|
||||
regex_constants::__full_match);
|
||||
if (__r)
|
||||
{
|
||||
__r = !__m.suffix().matched;
|
||||
|
||||
@@ -371,16 +371,37 @@ int main()
|
||||
}
|
||||
{
|
||||
std::cmatch m;
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2273
|
||||
const char s[] = "tournament";
|
||||
assert(!std::regex_match(s, m, std::regex("tour|to|tournament")));
|
||||
assert(m.size() == 0);
|
||||
assert(std::regex_match(s, m, std::regex("tour|to|tournament")));
|
||||
assert(m.size() == 1);
|
||||
assert(!m.prefix().matched);
|
||||
assert(m.prefix().first == s);
|
||||
assert(m.prefix().second == m[0].first);
|
||||
assert(!m.suffix().matched);
|
||||
assert(m.suffix().first == m[0].second);
|
||||
assert(m.suffix().second == m[0].second);
|
||||
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||
assert(m.position(0) == 0);
|
||||
assert(m.str(0) == s);
|
||||
}
|
||||
{
|
||||
std::cmatch m;
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2273
|
||||
const char s[] = "tournamenttotour";
|
||||
assert(!std::regex_match(s, m, std::regex("(tour|to|tournament)+",
|
||||
std::regex_constants::nosubs)));
|
||||
assert(m.size() == 0);
|
||||
assert(
|
||||
std::regex_match(s, m, std::regex("(tour|to|tournament)+",
|
||||
std::regex_constants::nosubs)));
|
||||
assert(m.size() == 1);
|
||||
assert(!m.prefix().matched);
|
||||
assert(m.prefix().first == s);
|
||||
assert(m.prefix().second == m[0].first);
|
||||
assert(!m.suffix().matched);
|
||||
assert(m.suffix().first == m[0].second);
|
||||
assert(m.suffix().second == m[0].second);
|
||||
assert(m.length(0) == std::char_traits<char>::length(s));
|
||||
assert(m.position(0) == 0);
|
||||
assert(m.str(0) == s);
|
||||
}
|
||||
{
|
||||
std::cmatch m;
|
||||
@@ -1036,16 +1057,37 @@ int main()
|
||||
}
|
||||
{
|
||||
std::wcmatch m;
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2273
|
||||
const wchar_t s[] = L"tournament";
|
||||
assert(!std::regex_match(s, m, std::wregex(L"tour|to|tournament")));
|
||||
assert(m.size() == 0);
|
||||
assert(std::regex_match(s, m, std::wregex(L"tour|to|tournament")));
|
||||
assert(m.size() == 1);
|
||||
assert(!m.prefix().matched);
|
||||
assert(m.prefix().first == s);
|
||||
assert(m.prefix().second == m[0].first);
|
||||
assert(!m.suffix().matched);
|
||||
assert(m.suffix().first == m[0].second);
|
||||
assert(m.suffix().second == m[0].second);
|
||||
assert(m.length(0) == std::char_traits<wchar_t>::length(s));
|
||||
assert(m.position(0) == 0);
|
||||
assert(m.str(0) == s);
|
||||
}
|
||||
{
|
||||
std::wcmatch m;
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2273
|
||||
const wchar_t s[] = L"tournamenttotour";
|
||||
assert(!std::regex_match(s, m, std::wregex(L"(tour|to|tournament)+",
|
||||
std::regex_constants::nosubs)));
|
||||
assert(m.size() == 0);
|
||||
assert(
|
||||
std::regex_match(s, m, std::wregex(L"(tour|to|tournament)+",
|
||||
std::regex_constants::nosubs)));
|
||||
assert(m.size() == 1);
|
||||
assert(!m.prefix().matched);
|
||||
assert(m.prefix().first == s);
|
||||
assert(m.prefix().second == m[0].first);
|
||||
assert(!m.suffix().matched);
|
||||
assert(m.suffix().first == m[0].second);
|
||||
assert(m.suffix().second == m[0].second);
|
||||
assert(m.length(0) == std::char_traits<wchar_t>::length(s));
|
||||
assert(m.position(0) == 0);
|
||||
assert(m.str(0) == s);
|
||||
}
|
||||
{
|
||||
std::wcmatch m;
|
||||
|
||||
Reference in New Issue
Block a user