mirror of
https://github.com/boostorg/regex.git
synced 2025-07-29 20:17:24 +02:00
more or less completed non-recursive implementation.
[SVN r18185]
This commit is contained in:
@ -468,10 +468,9 @@ void raise_error(const traits& t, unsigned code)
|
||||
# ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
|
||||
# undef BOOST_REGEX_HAS_MS_STACK_GUARD
|
||||
# endif
|
||||
namespace boost{ namespace re_detail{
|
||||
BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block();
|
||||
BOOST_REGEX_DECL void BOOST_REGEX_CALL release_mem_block(void*);
|
||||
} }
|
||||
# ifndef BOOST_REGEX_MAX_CACHE_BLOCKS
|
||||
# define BOOST_REGEX_MAX_CACHE_BLOCKS BOOST_REGEX_MAX_BLOCKS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -77,3 +77,9 @@
|
||||
// used by the non-recursive algorithm.
|
||||
// #define BOOST_REGEX_MAX_BLOCKS 1024
|
||||
|
||||
// define this if you want to set the maximum number of memory blocks
|
||||
// cached by the non-recursive algorithm: Normally this is the same as
|
||||
// BOOST_REGEX_MAX_BLOCKS, but can be higher if you have multiple threads
|
||||
// all using boost.regex, or lower if you don't want boost.regex to cache
|
||||
// memory.
|
||||
// #define BOOST_REGEX_MAX_CACHE_BLOCKS 1024
|
||||
|
@ -16,14 +16,14 @@
|
||||
* LOCATION: see http://www.boost.org for most recent version.
|
||||
* FILE mem_block_cache.hpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Definitions of perl_matcher member functions that are
|
||||
* specific to the non-recursive implementation.
|
||||
* DESCRIPTION: memory block cache used by the non-recursive matcher.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
|
||||
#define BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
|
||||
|
||||
#include <new>
|
||||
#include <boost/regex/v4/regex_synch.hpp>
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
# pragma option push -a8 -b -Vx -Ve -pc -w-8027
|
||||
@ -39,7 +39,9 @@ struct mem_block_node
|
||||
|
||||
struct mem_block_cache
|
||||
{
|
||||
// this member has to be statically initialsed:
|
||||
mem_block_node* next;
|
||||
unsigned cached_blocks;
|
||||
|
||||
~mem_block_cache()
|
||||
{
|
||||
@ -52,19 +54,33 @@ struct mem_block_cache
|
||||
}
|
||||
void* get()
|
||||
{
|
||||
if(next)
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
re_detail::cs_guard g(*re_detail::p_re_lock);
|
||||
#endif
|
||||
if(next)
|
||||
{
|
||||
mem_block_node* result = next;
|
||||
next = next->next;
|
||||
--cached_blocks;
|
||||
return result;
|
||||
}
|
||||
return ::operator new(BOOST_REGEX_BLOCKSIZE);
|
||||
}
|
||||
void put(void* p)
|
||||
{
|
||||
mem_block_node* old = static_cast<mem_block_node*>(p);
|
||||
old->next = next;
|
||||
next = old;
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
re_detail::cs_guard g(*re_detail::p_re_lock);
|
||||
#endif
|
||||
if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)
|
||||
{
|
||||
::operator delete(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_block_node* old = static_cast<mem_block_node*>(p);
|
||||
old->next = next;
|
||||
next = old;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -384,6 +384,7 @@ private:
|
||||
bool unwind_char_repeat(bool);
|
||||
bool unwind_short_set_repeat(bool);
|
||||
bool unwind_long_set_repeat(bool);
|
||||
bool unwind_non_greedy_repeat(bool);
|
||||
void destroy_single_repeat();
|
||||
void push_matched_paren(int index, const sub_match<BidiIterator>& sub);
|
||||
void push_recursion_stopper();
|
||||
@ -391,6 +392,7 @@ private:
|
||||
void push_alt(const re_syntax_base* ps);
|
||||
void push_repeater_count(int i, repeater_count<BidiIterator>** s);
|
||||
void push_single_repeat(unsigned c, const re_repeat* r, BidiIterator last_position, int id);
|
||||
void push_non_greedy_repeat(const re_syntax_base* ps);
|
||||
|
||||
|
||||
// pointer to base of stack:
|
||||
|
@ -97,6 +97,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match()
|
||||
#ifdef BOOST_REGEX_NON_RECURSIVE
|
||||
save_state_init init(&m_stack_base, &m_backup_state);
|
||||
used_block_count = BOOST_REGEX_MAX_BLOCKS;
|
||||
try{
|
||||
#endif
|
||||
|
||||
// reset our state machine:
|
||||
@ -111,6 +112,17 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match()
|
||||
return false;
|
||||
return m_result[0].second == last;
|
||||
|
||||
#ifdef BOOST_REGEX_NON_RECURSIVE
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
// unwind all pushed states, apart from anything else this
|
||||
// ensures that all the states are correctly destructed
|
||||
// not just the memory freed.
|
||||
while(unwind(true)){}
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
|
||||
}__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
|
||||
{
|
||||
@ -134,6 +146,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find()
|
||||
#ifdef BOOST_REGEX_NON_RECURSIVE
|
||||
save_state_init init(&m_stack_base, &m_backup_state);
|
||||
used_block_count = BOOST_REGEX_MAX_BLOCKS;
|
||||
try{
|
||||
#endif
|
||||
|
||||
state_count = 0;
|
||||
@ -180,6 +193,17 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find()
|
||||
matcher_proc_type proc = s_find_vtable[type];
|
||||
return (this->*proc)();
|
||||
|
||||
#ifdef BOOST_REGEX_NON_RECURSIVE
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
// unwind all pushed states, apart from anything else this
|
||||
// ensures that all the states are correctly destructed
|
||||
// not just the memory freed.
|
||||
while(unwind(true)){}
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
|
||||
}__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
|
||||
{
|
||||
@ -755,6 +779,12 @@ perl_matcher<BidiIterator, Allocator, traits, Allocator2>::s_match_vtable[] =
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_combining,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_soft_buffer_end,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_restart_continue,
|
||||
#if 0
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep,
|
||||
#else
|
||||
#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_fast,
|
||||
#else
|
||||
@ -763,7 +793,7 @@ perl_matcher<BidiIterator, Allocator, traits, Allocator2>::s_match_vtable[] =
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repeat,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_repeat,
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template <class BidiIterator, class Allocator, class traits, class Allocator2>
|
||||
|
@ -54,7 +54,8 @@ enum saved_state_type
|
||||
saved_state_rep_fast_dot = 9,
|
||||
saved_state_rep_char = 10,
|
||||
saved_state_rep_short_set = 11,
|
||||
saved_state_rep_long_set = 12
|
||||
saved_state_rep_long_set = 12,
|
||||
saved_state_non_greedy_long_repeat = 13
|
||||
};
|
||||
|
||||
struct saved_state
|
||||
@ -134,8 +135,6 @@ struct saved_single_repeat : public saved_state
|
||||
template <class BidiIterator, class Allocator, class traits, class Allocator2>
|
||||
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_all_states()
|
||||
{
|
||||
if(state_count > max_state_count)
|
||||
raise_error(traits_inst, REG_ESPACE);
|
||||
push_recursion_stopper();
|
||||
do{
|
||||
while(pstate)
|
||||
@ -144,6 +143,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_all_states
|
||||
++state_count;
|
||||
if(!(this->*proc)())
|
||||
{
|
||||
if(state_count > max_state_count)
|
||||
raise_error(traits_inst, REG_ESPACE);
|
||||
if((m_match_flags & match_partial) && (position == last))
|
||||
m_has_partial_match = true;
|
||||
if(false == unwind(false))
|
||||
@ -235,6 +236,21 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_alt(
|
||||
m_backup_state = pmp;
|
||||
}
|
||||
|
||||
template <class BidiIterator, class Allocator, class traits, class Allocator2>
|
||||
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_non_greedy_repeat(const re_syntax_base* ps)
|
||||
{
|
||||
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;
|
||||
}
|
||||
new (pmp)saved_position<BidiIterator>(ps, position, saved_state_non_greedy_long_repeat);
|
||||
m_backup_state = pmp;
|
||||
}
|
||||
|
||||
template <class BidiIterator, class Allocator, class traits, class Allocator2>
|
||||
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_repeater_count(int i, repeater_count<BidiIterator>** s)
|
||||
{
|
||||
@ -408,19 +424,16 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep()
|
||||
if(take_second)
|
||||
{
|
||||
// store position in case we fail:
|
||||
BidiIterator pos = position;
|
||||
push_non_greedy_repeat(rep->next.p);
|
||||
pstate = rep->alt.p;
|
||||
if(match_all_states())
|
||||
return true;
|
||||
// failed alternative, reset posistion and fall through for repeat:
|
||||
position = pos;
|
||||
return true;
|
||||
}
|
||||
if((next_count->get_count() < rep->max) && take_first)
|
||||
{
|
||||
// increase the counter:
|
||||
++(*next_count);
|
||||
pstate = rep->next.p;
|
||||
return match_all_states();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -1114,6 +1127,21 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class BidiIterator, class Allocator, class traits, class Allocator2>
|
||||
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_non_greedy_repeat(bool r)
|
||||
{
|
||||
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
|
||||
if(!r)
|
||||
{
|
||||
position = pmp->position;
|
||||
pstate = pmp->pstate;
|
||||
++(*next_count);
|
||||
}
|
||||
destroy(pmp++);
|
||||
m_backup_state = pmp;
|
||||
return r;
|
||||
}
|
||||
|
||||
template <class BidiIterator, class Allocator, class traits, class Allocator2>
|
||||
typename perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_proc_type const
|
||||
perl_matcher<BidiIterator, Allocator, traits, Allocator2>::s_unwind_table[] =
|
||||
@ -1131,6 +1159,7 @@ perl_matcher<BidiIterator, Allocator, traits, Allocator2>::s_unwind_table[] =
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_char_repeat,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set_repeat,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_repeat,
|
||||
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_non_greedy_repeat,
|
||||
};
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user