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
-
-
+
+-
Change to lockfree implementation of memory cache, see PR#23.
-
+
+-
+ Fix bug in case sensitivity change, see #11940.
+
+
-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));