summaryrefslogtreecommitdiff
path: root/libcxx/include/regex
diff options
context:
space:
mode:
Diffstat (limited to 'libcxx/include/regex')
-rw-r--r--libcxx/include/regex68
1 files changed, 47 insertions, 21 deletions
diff --git a/libcxx/include/regex b/libcxx/include/regex
index 5ac9e325e136f..f42f1ecd16a41 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -21,7 +21,7 @@ namespace std
namespace regex_constants
{
-emum syntax_option_type
+enum syntax_option_type
{
icase = unspecified,
nosubs = unspecified,
@@ -631,7 +631,7 @@ template <class OutputIterator, class BidirectionalIterator,
const basic_regex<charT, traits>& e, const charT* fmt,
regex_constants::match_flag_type flags = regex_constants::match_default);
-template <class traits, class charT, class ST, class SA, class FST, class FSA>>
+template <class traits, class charT, class ST, class SA, class FST, class FSA>
basic_string<charT, ST, SA>
regex_replace(const basic_string<charT, ST, SA>& s,
const basic_regex<charT, traits>& e,
@@ -675,9 +675,9 @@ public:
regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
const regex_type& re,
regex_constants::match_flag_type m = regex_constants::match_default);
- regex_iterator(_BidirectionalIterator __a, _BidirectionalIterator __b,
- const regex_type&& __re,
- regex_constants::match_flag_type __m
+ regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
+ const regex_type&& re,
+ regex_constants::match_flag_type m
= regex_constants::match_default) = delete; // C++14
regex_iterator(const regex_iterator&);
regex_iterator& operator=(const regex_iterator&);
@@ -698,7 +698,7 @@ typedef regex_iterator<string::const_iterator> sregex_iterator;
typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
template <class BidirectionalIterator,
- class charT = typename iterator_traits< BidirectionalIterator>::value_type,
+ class charT = typename iterator_traits<BidirectionalIterator>::value_type,
class traits = regex_traits<charT>>
class regex_token_iterator
{
@@ -735,8 +735,8 @@ public:
regex_constants::match_flag_type m = regex_constants::match_default);
template <size_t N>
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b,
- const regex_type& re, const int (&submatches)[N],
- regex_constants::match_flag_type m = regex_constants::match_default) = delete // C++14;
+ const regex_type&& re, const int (&submatches)[N],
+ regex_constants::match_flag_type m = regex_constants::match_default) = delete; // C++14
regex_token_iterator(const regex_token_iterator&);
regex_token_iterator& operator=(const regex_token_iterator&);
@@ -977,7 +977,8 @@ class _LIBCPP_EXCEPTION_ABI regex_error
regex_constants::error_type __code_;
public:
explicit regex_error(regex_constants::error_type __ecode);
- virtual ~regex_error() throw();
+ regex_error(const regex_error&) _NOEXCEPT = default;
+ virtual ~regex_error() _NOEXCEPT;
_LIBCPP_INLINE_VISIBILITY
regex_constants::error_type code() const {return __code_;}
};
@@ -1000,7 +1001,19 @@ public:
typedef _CharT char_type;
typedef basic_string<char_type> string_type;
typedef locale locale_type;
+#ifdef __BIONIC__
+ // Originally bionic's ctype_base used its own ctype masks because the
+ // builtin ctype implementation wasn't in libc++ yet. Bionic's ctype mask
+ // was only 8 bits wide and already saturated, so it used a wider type here
+ // to make room for __regex_word (then a part of this class rather than
+ // ctype_base). Bionic has since moved to the builtin ctype_base
+ // implementation, but this was not updated to match. Since then Android has
+ // needed to maintain a stable libc++ ABI, and this can't be changed without
+ // an ABI break.
+ typedef uint16_t char_class_type;
+#else
typedef ctype_base::mask char_class_type;
+#endif
static const char_class_type __regex_word = ctype_base::__regex_word;
private:
@@ -2837,6 +2850,8 @@ private:
__parse_awk_escape(_ForwardIterator __first, _ForwardIterator __last,
basic_string<_CharT>* __str = nullptr);
+ bool __test_back_ref(_CharT c);
+
_LIBCPP_INLINE_VISIBILITY
void __push_l_anchor();
void __push_r_anchor();
@@ -3408,18 +3423,8 @@ basic_regex<_CharT, _Traits>::__parse_BACKREF(_ForwardIterator __first,
if (__first != __last)
{
_ForwardIterator __temp = _VSTD::next(__first);
- if (__temp != __last)
- {
- if (*__first == '\\')
- {
- int __val = __traits_.value(*__temp, 10);
- if (__val >= 1 && __val <= 9)
- {
- __push_back_ref(__val);
- __first = ++__temp;
- }
- }
- }
+ if (__temp != __last && *__first == '\\' && __test_back_ref(*__temp))
+ __first = ++__temp;
}
return __first;
}
@@ -3547,6 +3552,8 @@ basic_regex<_CharT, _Traits>::__parse_QUOTED_CHAR_ERE(_ForwardIterator __first,
default:
if (__get_grammar(__flags_) == awk)
__first = __parse_awk_escape(++__first, __last);
+ else if(__test_back_ref(*__temp))
+ __first = ++__temp;
break;
}
}
@@ -4661,6 +4668,22 @@ basic_regex<_CharT, _Traits>::__parse_egrep(_ForwardIterator __first,
}
template <class _CharT, class _Traits>
+bool
+basic_regex<_CharT, _Traits>::__test_back_ref(_CharT c)
+{
+ unsigned __val = __traits_.value(c, 10);
+ if (__val >= 1 && __val <= 9)
+ {
+ if (__val > mark_count())
+ __throw_regex_error<regex_constants::error_backref>();
+ __push_back_ref(__val);
+ return true;
+ }
+
+ return false;
+}
+
+template <class _CharT, class _Traits>
void
basic_regex<_CharT, _Traits>::__push_loop(size_t __min, size_t __max,
__owns_one_state<_CharT>* __s, size_t __mexp_begin, size_t __mexp_end,
@@ -5917,6 +5940,9 @@ basic_regex<_CharT, _Traits>::__search(
match_results<const _CharT*, _Allocator>& __m,
regex_constants::match_flag_type __flags) const
{
+ if (__flags & regex_constants::match_prev_avail)
+ __flags &= ~(regex_constants::match_not_bol | regex_constants::match_not_bow);
+
__m.__init(1 + mark_count(), __first, __last,
__flags & regex_constants::__no_update_pos);
if (__match_at_start(__first, __last, __m, __flags,