summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp')
-rw-r--r--3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp256
1 files changed, 248 insertions, 8 deletions
diff --git a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp
index 10e0347..0fcd454 100644
--- a/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp
+++ b/3rdParty/Boost/src/boost/regex/v4/perl_matcher_non_recursive.hpp
@@ -127,10 +127,21 @@ struct saved_single_repeat : public saved_state
: saved_state(arg_id), count(c), rep(r), last_position(lp){}
};
+template <class Results>
+struct saved_recursion : public saved_state
+{
+ saved_recursion(int id, const re_syntax_base* p, Results* pr)
+ : saved_state(14), recursion_id(id), preturn_address(p), results(*pr)
+ {}
+ int recursion_id;
+ const re_syntax_base* preturn_address;
+ Results results;
+};
+
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
{
- static matcher_proc_type const s_match_vtable[29] =
+ static matcher_proc_type const s_match_vtable[30] =
{
(&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
@@ -154,13 +165,18 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
&perl_matcher<BidiIterator, Allocator, traits>::match_combining,
&perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
- (::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
+ // Although this next line *should* be evaluated at compile time, in practice
+ // some compilers (VC++) emit run-time initialisation which breaks thread
+ // safety, so use a dispatch function instead:
+ //(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
+ &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_dispatch,
&perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::match_backstep,
&perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref,
&perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case,
+ &perl_matcher<BidiIterator, Allocator, traits>::match_recursion,
};
push_recursion_stopper();
@@ -172,7 +188,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
if(!(this->*proc)())
{
if(state_count > max_state_count)
- raise_error(traits_inst, regex_constants::error_space);
+ raise_error(traits_inst, regex_constants::error_complexity);
if((m_match_flags & match_partial) && (position == last) && (position != search_base))
m_has_partial_match = true;
bool successful_unwind = unwind(false);
@@ -203,13 +219,13 @@ void perl_matcher<BidiIterator, Allocator, traits>::extend_stack()
m_backup_state = block;
}
else
- raise_error(traits_inst, regex_constants::error_size);
+ raise_error(traits_inst, regex_constants::error_stack);
}
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
{
- BOOST_ASSERT(index);
+ //BOOST_ASSERT(index);
saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
--pmp;
if(pmp < m_stack_base)
@@ -313,9 +329,25 @@ inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(st
}
template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion(int id, const re_syntax_base* p, results_type* presults)
+{
+ saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_recursion<results_type>(id, p, presults);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
{
int index = static_cast<const re_brace*>(pstate)->index;
+ icase = static_cast<const re_brace*>(pstate)->icase;
switch(index)
{
case 0:
@@ -400,6 +432,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
break;
}
}
+ case -5:
+ {
+ push_matched_paren(0, (*m_presult)[0]);
+ m_presult->set_first(position, 0, true);
+ pstate = pstate->next.p;
+ break;
+ }
default:
{
BOOST_ASSERT(index > 0);
@@ -848,6 +887,105 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
#endif
}
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_recursion()
+{
+ BOOST_ASSERT(pstate->type == syntax_element_recurse);
+ //
+ // Backup call stack:
+ //
+ push_recursion_pop();
+ //
+ // Set new call stack:
+ //
+ if(recursion_stack_position >= static_cast<int>(sizeof(recursion_stack)/sizeof(recursion_stack[0])))
+ {
+ return false;
+ }
+ recursion_stack[recursion_stack_position].preturn_address = pstate->next.p;
+ recursion_stack[recursion_stack_position].results = *m_presult;
+ if(static_cast<const re_recurse*>(pstate)->state_id > 0)
+ {
+ push_repeater_count(static_cast<const re_recurse*>(pstate)->state_id, &next_count);
+ }
+ pstate = static_cast<const re_jump*>(pstate)->alt.p;
+ recursion_stack[recursion_stack_position].id = static_cast<const re_brace*>(pstate)->index;
+ ++recursion_stack_position;
+ //BOOST_ASSERT(recursion_stack[recursion_stack_position-1].id);
+
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
+{
+ int index = static_cast<const re_brace*>(pstate)->index;
+ icase = static_cast<const re_brace*>(pstate)->icase;
+ if(index > 0)
+ {
+ if((m_match_flags & match_nosubs) == 0)
+ {
+ m_presult->set_second(position, index);
+ }
+ if(recursion_stack_position)
+ {
+ if(index == recursion_stack[recursion_stack_position-1].id)
+ {
+ --recursion_stack_position;
+ pstate = recursion_stack[recursion_stack_position].preturn_address;
+ *m_presult = recursion_stack[recursion_stack_position].results;
+ push_recursion(recursion_stack[recursion_stack_position].id, recursion_stack[recursion_stack_position].preturn_address, &recursion_stack[recursion_stack_position].results);
+ }
+ }
+ }
+ else if((index < 0) && (index != -4))
+ {
+ // matched forward lookahead:
+ pstate = 0;
+ return true;
+ }
+ pstate = pstate->next.p;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
+{
+ if(recursion_stack_position)
+ {
+ BOOST_ASSERT(0 == recursion_stack[recursion_stack_position-1].id);
+ --recursion_stack_position;
+ pstate = recursion_stack[recursion_stack_position].preturn_address;
+ *m_presult = recursion_stack[recursion_stack_position].results;
+ push_recursion(recursion_stack[recursion_stack_position].id, recursion_stack[recursion_stack_position].preturn_address, &recursion_stack[recursion_stack_position].results);
+ return true;
+ }
+ if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
+ return false;
+ if((m_match_flags & match_all) && (position != last))
+ return false;
+ if((m_match_flags & regex_constants::match_not_initial_null) && (position == search_base))
+ return false;
+ m_presult->set_second(position);
+ pstate = 0;
+ m_has_found_match = true;
+ if((m_match_flags & match_posix) == match_posix)
+ {
+ m_result.maybe_assign(*m_presult);
+ if((m_match_flags & match_any) == 0)
+ return false;
+ }
+#ifdef BOOST_REGEX_MATCH_EXTRA
+ if(match_extra & m_match_flags)
+ {
+ for(unsigned i = 0; i < m_presult->size(); ++i)
+ if((*m_presult)[i].matched)
+ ((*m_presult)[i]).get_captures().push_back((*m_presult)[i]);
+ }
+#endif
+ return true;
+}
+
/****************************************************************************
Unwind and associated proceedures follow, these perform what normal stack
@@ -858,7 +996,7 @@ unwinding does in the recursive implementation.
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)
{
- static unwind_proc_type const s_unwind_table[14] =
+ static unwind_proc_type const s_unwind_table[18] =
{
&perl_matcher<BidiIterator, Allocator, traits>::unwind_end,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,
@@ -874,6 +1012,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)
&perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion,
+ &perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop,
};
m_recursive_result = have_match;
@@ -907,8 +1047,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match
// restore previous values if no match was found:
if(have_match == false)
{
- m_presult->set_first(pmp->sub.first, pmp->index);
- m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched);
+ m_presult->set_first(pmp->sub.first, pmp->index, pmp->index == 0);
+ m_presult->set_second(pmp->sub.second, pmp->index, pmp->sub.matched, pmp->index == 0);
}
#ifdef BOOST_REGEX_MATCH_EXTRA
//
@@ -1377,6 +1517,106 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(boo
return r;
}
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion(bool r)
+{
+ saved_recursion<results_type>* pmp = static_cast<saved_recursion<results_type>*>(m_backup_state);
+ if(!r)
+ {
+ recursion_stack[recursion_stack_position].id = pmp->recursion_id;
+ recursion_stack[recursion_stack_position].preturn_address = pmp->preturn_address;
+ recursion_stack[recursion_stack_position].results = pmp->results;
+ ++recursion_stack_position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_pop(bool r)
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ if(!r)
+ {
+ --recursion_stack_position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_pop()
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_state(15);
+ m_backup_state = pmp;
+}
+/*
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_pop(bool r)
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ if(!r)
+ {
+ --parenthesis_stack_position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_pop()
+{
+ saved_state* pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_state*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_state(16);
+ m_backup_state = pmp;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+bool perl_matcher<BidiIterator, Allocator, traits>::unwind_parenthesis_push(bool r)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ if(!r)
+ {
+ parenthesis_stack[parenthesis_stack_position++] = pmp->position;
+ }
+ boost::re_detail::inplace_destroy(pmp++);
+ m_backup_state = pmp;
+ return true;
+}
+
+template <class BidiIterator, class Allocator, class traits>
+inline void perl_matcher<BidiIterator, Allocator, traits>::push_parenthesis_push(BidiIterator p)
+{
+ saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ if(pmp < m_stack_base)
+ {
+ extend_stack();
+ pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
+ --pmp;
+ }
+ (void) new (pmp)saved_position<BidiIterator>(0, p, 17);
+ m_backup_state = pmp;
+}
+*/
} // namespace re_detail
} // namespace boost