diff --git a/doc/history.qbk b/doc/history.qbk index 17231392..17b43f57 100644 --- a/doc/history.qbk +++ b/doc/history.qbk @@ -18,6 +18,7 @@ All issues including closed ones can be viewed [@https://svn.boost.org/trac/boos [h4 Boost.Regex-5.1.1] * Change to lockfree implementation of memory cache, see [@https://github.com/boostorg/regex/pull/23 PR#23]. +* Fix bug in case sensitivity change, see [@https://svn.boost.org/trac/boost/ticket/11940 #11940]. [h4 Boost.Regex-5.1.0 (Boost-1.60.0)] diff --git a/doc/html/boost_regex/background_information/history.html b/doc/html/boost_regex/background_information/history.html index 21b56489..1cf10e32 100644 --- a/doc/html/boost_regex/background_information/history.html +++ b/doc/html/boost_regex/background_information/history.html @@ -39,9 +39,14 @@ Boost.Regex-5.1.1 -
Boost.Regex-5.1.0 diff --git a/doc/html/index.html b/doc/html/index.html index 81680b0c..fa8905af 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -221,7 +221,7 @@

- +

Last revised: March 12, 2016 at 19:00:00 GMT

Last revised: March 14, 2016 at 19:20:20 GMT


diff --git a/include/boost/regex/v4/perl_matcher.hpp b/include/boost/regex/v4/perl_matcher.hpp index a7298fbd..96a086b8 100644 --- a/include/boost/regex/v4/perl_matcher.hpp +++ b/include/boost/regex/v4/perl_matcher.hpp @@ -537,6 +537,7 @@ private: bool unwind_recursion_pop(bool); bool unwind_commit(bool); bool unwind_then(bool); + bool unwind_case(bool); void destroy_single_repeat(); void push_matched_paren(int index, const sub_match& sub); void push_recursion_stopper(); @@ -547,6 +548,7 @@ private: void push_non_greedy_repeat(const re_syntax_base* ps); void push_recursion(int idx, const re_syntax_base* p, results_type* presults); void push_recursion_pop(); + void push_case_change(bool); // pointer to base of stack: saved_state* m_stack_base; diff --git a/include/boost/regex/v4/perl_matcher_common.hpp b/include/boost/regex/v4/perl_matcher_common.hpp index e60581df..6febff4c 100644 --- a/include/boost/regex/v4/perl_matcher_common.hpp +++ b/include/boost/regex/v4/perl_matcher_common.hpp @@ -793,15 +793,6 @@ inline bool perl_matcher::match_assert_backref( return result; } -template -bool perl_matcher::match_toggle_case() -{ - // change our case sensitivity: - this->icase = static_cast(pstate)->icase; - pstate = pstate->next.p; - return true; -} - template bool perl_matcher::match_fail() { diff --git a/include/boost/regex/v4/perl_matcher_non_recursive.hpp b/include/boost/regex/v4/perl_matcher_non_recursive.hpp index bf77eaa5..aa7af3b4 100644 --- a/include/boost/regex/v4/perl_matcher_non_recursive.hpp +++ b/include/boost/regex/v4/perl_matcher_non_recursive.hpp @@ -138,6 +138,12 @@ struct saved_recursion : public saved_state Results results; }; +struct saved_change_case : public saved_state +{ + bool icase; + saved_change_case(bool c) : saved_state(18), icase(c) {} +}; + template bool perl_matcher::match_all_states() { @@ -242,6 +248,22 @@ inline void perl_matcher::push_matched_paren(in m_backup_state = pmp; } +template +inline void perl_matcher::push_case_change(bool c) +{ + //BOOST_ASSERT(index); + saved_change_case* pmp = static_cast(m_backup_state); + --pmp; + if(pmp < m_stack_base) + { + extend_stack(); + pmp = static_cast(m_backup_state); + --pmp; + } + (void) new (pmp)saved_change_case(c); + m_backup_state = pmp; +} + template inline void perl_matcher::push_recursion_stopper() { @@ -347,6 +369,16 @@ inline void perl_matcher::push_recursion(int id m_backup_state = pmp; } +template +bool perl_matcher::match_toggle_case() +{ + // change our case sensitivity: + push_case_change(this->icase); + this->icase = static_cast(pstate)->icase; + pstate = pstate->next.p; + return true; +} + template bool perl_matcher::match_startmark() { @@ -1142,6 +1174,7 @@ bool perl_matcher::unwind(bool have_match) &perl_matcher::unwind_recursion_pop, &perl_matcher::unwind_commit, &perl_matcher::unwind_then, + &perl_matcher::unwind_case, }; m_recursive_result = have_match; @@ -1170,6 +1203,16 @@ bool perl_matcher::unwind_end(bool) return false; // end of stack nothing more to search } +template +bool perl_matcher::unwind_case(bool) +{ + saved_change_case* pmp = static_cast(m_backup_state); + icase = pmp->icase; + boost::BOOST_REGEX_DETAIL_NS::inplace_destroy(pmp++); + m_backup_state = pmp; + return true; +} + template bool perl_matcher::unwind_paren(bool have_match) { diff --git a/include/boost/regex/v4/perl_matcher_recursive.hpp b/include/boost/regex/v4/perl_matcher_recursive.hpp index 3893837d..33b91581 100644 --- a/include/boost/regex/v4/perl_matcher_recursive.hpp +++ b/include/boost/regex/v4/perl_matcher_recursive.hpp @@ -289,11 +289,13 @@ bool perl_matcher::match_alt() BidiIterator oldposition(position); const re_syntax_base* old_pstate = jmp->alt.p; pstate = pstate->next.p; + bool oldcase = icase; m_have_then = false; if(!match_all_states()) { pstate = old_pstate; position = oldposition; + icase = oldcase; if(m_have_then) { m_can_backtrack = true; @@ -1036,6 +1038,20 @@ bool perl_matcher::match_then() return false; } +template +bool perl_matcher::match_toggle_case() +{ + // change our case sensitivity: + bool oldcase = this->icase; + this->icase = static_cast(pstate)->icase; + pstate = pstate->next.p; + bool result = match_all_states(); + this->icase = oldcase; + return result; +} + + + template bool perl_matcher::skip_until_paren(int index, bool have_match) { diff --git a/test/regress/test_perl_ex.cpp b/test/regress/test_perl_ex.cpp index 2f081e2d..73125419 100644 --- a/test/regress/test_perl_ex.cpp +++ b/test/regress/test_perl_ex.cpp @@ -245,6 +245,10 @@ void test_options2() TEST_REGEX_SEARCH("a(?i:b)*c", perl, "aBBc", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("a(?i:b)*c", perl, "aBC", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a(?i:b)*c", perl, "aBBC", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "J", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "j", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "h", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "H", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a(?=b(?i)c)\\w\\wd", perl, "abcd", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("a(?=b(?i)c)\\w\\wd", perl, "abCd", match_default, make_array(0, 4, -2, -2));