regex_constants icase and collate for matching a single char and for matching back references
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@108178 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cba352d348
commit
e34f17d383
234
include/regex
234
include/regex
@ -1680,6 +1680,128 @@ __back_ref<_CharT>::__exec(__state& __s) const
|
||||
}
|
||||
}
|
||||
|
||||
// __back_ref_icase
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
class __back_ref_icase
|
||||
: public __owns_one_state<_CharT>
|
||||
{
|
||||
typedef __owns_one_state<_CharT> base;
|
||||
|
||||
_Traits __traits_;
|
||||
unsigned __mexp_;
|
||||
public:
|
||||
typedef _STD::__state<_CharT> __state;
|
||||
|
||||
explicit __back_ref_icase(const _Traits& __traits, unsigned __mexp,
|
||||
__node<_CharT>* __s)
|
||||
: base(__s), __traits_(__traits), __mexp_(__mexp) {}
|
||||
|
||||
virtual void __exec(__state&) const;
|
||||
|
||||
virtual string speak() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "__back_ref_icase " << __mexp_;
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
void
|
||||
__back_ref_icase<_CharT, _Traits>::__exec(__state& __s) const
|
||||
{
|
||||
sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];
|
||||
if (__sm.matched)
|
||||
{
|
||||
ptrdiff_t __len = __sm.second - __sm.first;
|
||||
if (__s.__last_ - __s.__current_ >= __len)
|
||||
{
|
||||
for (ptrdiff_t __i = 0; __i < __len; ++__i)
|
||||
{
|
||||
if (__traits_.translate_nocase(__sm.first[__i]) !=
|
||||
__traits_.translate_nocase(__s.__current_[__i]))
|
||||
goto __not_equal;
|
||||
}
|
||||
__s.__do_ = __state::__accept_but_not_consume;
|
||||
__s.__current_ += __len;
|
||||
__s.__node_ = this->first();
|
||||
}
|
||||
else
|
||||
{
|
||||
__s.__do_ = __state::__reject;
|
||||
__s.__node_ = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__not_equal:
|
||||
__s.__do_ = __state::__reject;
|
||||
__s.__node_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// __back_ref_collate
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
class __back_ref_collate
|
||||
: public __owns_one_state<_CharT>
|
||||
{
|
||||
typedef __owns_one_state<_CharT> base;
|
||||
|
||||
_Traits __traits_;
|
||||
unsigned __mexp_;
|
||||
public:
|
||||
typedef _STD::__state<_CharT> __state;
|
||||
|
||||
explicit __back_ref_collate(const _Traits& __traits, unsigned __mexp,
|
||||
__node<_CharT>* __s)
|
||||
: base(__s), __traits_(__traits), __mexp_(__mexp) {}
|
||||
|
||||
virtual void __exec(__state&) const;
|
||||
|
||||
virtual string speak() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "__back_ref_collate " << __mexp_;
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
void
|
||||
__back_ref_collate<_CharT, _Traits>::__exec(__state& __s) const
|
||||
{
|
||||
sub_match<const _CharT*>& __sm = __s.__sub_matches_[__mexp_-1];
|
||||
if (__sm.matched)
|
||||
{
|
||||
ptrdiff_t __len = __sm.second - __sm.first;
|
||||
if (__s.__last_ - __s.__current_ >= __len)
|
||||
{
|
||||
for (ptrdiff_t __i = 0; __i < __len; ++__i)
|
||||
{
|
||||
if (__traits_.translate(__sm.first[__i]) !=
|
||||
__traits_.translate(__s.__current_[__i]))
|
||||
goto __not_equal;
|
||||
}
|
||||
__s.__do_ = __state::__accept_but_not_consume;
|
||||
__s.__current_ += __len;
|
||||
__s.__node_ = this->first();
|
||||
}
|
||||
else
|
||||
{
|
||||
__s.__do_ = __state::__reject;
|
||||
__s.__node_ = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
__not_equal:
|
||||
__s.__do_ = __state::__reject;
|
||||
__s.__node_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// __r_anchor
|
||||
|
||||
template <class _CharT>
|
||||
@ -1806,6 +1928,100 @@ __match_char<_CharT>::__exec(__state& __s) const
|
||||
}
|
||||
}
|
||||
|
||||
// __match_char_icase
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
class __match_char_icase
|
||||
: public __owns_one_state<_CharT>
|
||||
{
|
||||
typedef __owns_one_state<_CharT> base;
|
||||
|
||||
_Traits __traits_;
|
||||
_CharT __c_;
|
||||
|
||||
__match_char_icase(const __match_char_icase&);
|
||||
__match_char_icase& operator=(const __match_char_icase&);
|
||||
public:
|
||||
typedef _STD::__state<_CharT> __state;
|
||||
|
||||
__match_char_icase(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
|
||||
: base(__s), __traits_(__traits), __c_(__traits.translate_nocase(__c)) {}
|
||||
|
||||
virtual void __exec(__state&) const;
|
||||
|
||||
virtual string speak() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "match char icase " << __c_;
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
void
|
||||
__match_char_icase<_CharT, _Traits>::__exec(__state& __s) const
|
||||
{
|
||||
if (__s.__current_ != __s.__last_ &&
|
||||
__traits_.translate_nocase(*__s.__current_) == __c_)
|
||||
{
|
||||
__s.__do_ = __state::__accept_and_consume;
|
||||
++__s.__current_;
|
||||
__s.__node_ = this->first();
|
||||
}
|
||||
else
|
||||
{
|
||||
__s.__do_ = __state::__reject;
|
||||
__s.__node_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// __match_char_collate
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
class __match_char_collate
|
||||
: public __owns_one_state<_CharT>
|
||||
{
|
||||
typedef __owns_one_state<_CharT> base;
|
||||
|
||||
_Traits __traits_;
|
||||
_CharT __c_;
|
||||
|
||||
__match_char_collate(const __match_char_collate&);
|
||||
__match_char_collate& operator=(const __match_char_collate&);
|
||||
public:
|
||||
typedef _STD::__state<_CharT> __state;
|
||||
|
||||
__match_char_collate(const _Traits& __traits, _CharT __c, __node<_CharT>* __s)
|
||||
: base(__s), __traits_(__traits), __c_(__traits.translate(__c)) {}
|
||||
|
||||
virtual void __exec(__state&) const;
|
||||
|
||||
virtual string speak() const
|
||||
{
|
||||
ostringstream os;
|
||||
os << "match char icase " << __c_;
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
|
||||
template <class _CharT, class _Traits>
|
||||
void
|
||||
__match_char_collate<_CharT, _Traits>::__exec(__state& __s) const
|
||||
{
|
||||
if (__s.__current_ != __s.__last_ &&
|
||||
__traits_.translate(*__s.__current_) == __c_)
|
||||
{
|
||||
__s.__do_ = __state::__accept_and_consume;
|
||||
++__s.__current_;
|
||||
__s.__node_ = this->first();
|
||||
}
|
||||
else
|
||||
{
|
||||
__s.__do_ = __state::__reject;
|
||||
__s.__node_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template <class, class> class match_results;
|
||||
|
||||
template <class _CharT, class _Traits = regex_traits<_CharT> >
|
||||
@ -2913,7 +3129,14 @@ template <class _CharT, class _Traits>
|
||||
void
|
||||
basic_regex<_CharT, _Traits>::__push_char(value_type __c)
|
||||
{
|
||||
__end_->first() = new __match_char<_CharT>(__c, __end_->first());
|
||||
if (flags() & regex_constants::icase)
|
||||
__end_->first() = new __match_char_icase<_CharT, _Traits>
|
||||
(__traits_, __c, __end_->first());
|
||||
else if (flags() & regex_constants::collate)
|
||||
__end_->first() = new __match_char_collate<_CharT, _Traits>
|
||||
(__traits_, __c, __end_->first());
|
||||
else
|
||||
__end_->first() = new __match_char<_CharT>(__c, __end_->first());
|
||||
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
|
||||
}
|
||||
|
||||
@ -2955,7 +3178,14 @@ template <class _CharT, class _Traits>
|
||||
void
|
||||
basic_regex<_CharT, _Traits>::__push_back_ref(int __i)
|
||||
{
|
||||
__end_->first() = new __back_ref<_CharT>(__i, __end_->first());
|
||||
if (flags() & regex_constants::icase)
|
||||
__end_->first() = new __back_ref_icase<_CharT, _Traits>
|
||||
(__traits_, __i, __end_->first());
|
||||
else if (flags() & regex_constants::collate)
|
||||
__end_->first() = new __back_ref_collate<_CharT, _Traits>
|
||||
(__traits_, __i, __end_->first());
|
||||
else
|
||||
__end_->first() = new __back_ref<_CharT>(__i, __end_->first());
|
||||
__end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
|
||||
}
|
||||
|
||||
|
@ -472,4 +472,30 @@ int main()
|
||||
assert(!std::regex_search(s, m, std::regex("^\\(ab*\\)*\\1$", std::regex_constants::basic)));
|
||||
assert(m.size() == 0);
|
||||
}
|
||||
{
|
||||
std::cmatch m;
|
||||
const char s[] = "aBAbbAbB";
|
||||
assert(std::regex_search(s, m, std::regex("^\\(Ab*\\)*\\1$",
|
||||
std::regex_constants::basic | std::regex_constants::icase)));
|
||||
assert(m.size() == 2);
|
||||
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);
|
||||
assert(m.length(1) == 3);
|
||||
assert(m.position(1) == 2);
|
||||
assert(m.str(1) == "Abb");
|
||||
}
|
||||
{
|
||||
std::cmatch m;
|
||||
const char s[] = "aBAbbAbB";
|
||||
assert(!std::regex_search(s, m, std::regex("^\\(Ab*\\)*\\1$",
|
||||
std::regex_constants::basic)));
|
||||
assert(m.size() == 0);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user