Boost-Graph
view release on metacpan or search on metacpan
include/boost/regex/v4/perl_matcher_common.hpp view on Meta::CPAN
* LOCATION: see http://www.boost.org for most recent version.
* FILE perl_matcher_common.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Definitions of perl_matcher member functions that are
* common to both the recursive and non-recursive versions.
*/
#ifndef BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
#define BOOST_REGEX_V4_PERL_MATCHER_COMMON_HPP
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
#ifdef __BORLANDC__
# pragma option push -w-8008 -w-8066
#endif
namespace boost{
namespace re_detail{
template <class BidiIterator, class Allocator, class traits>
perl_matcher<BidiIterator, Allocator, traits>::perl_matcher(BidiIterator first, BidiIterator end,
match_results<BidiIterator, Allocator>& what,
const basic_regex<char_type, traits>& e,
match_flag_type f)
: m_result(what), base(first), last(end),
position(first), re(e), traits_inst(e.get_traits()),
m_independent(false), next_count(&rep_obj), rep_obj(&next_count)
{
typedef typename regex_iterator_traits<BidiIterator>::iterator_category category;
if(e.empty())
{
// precondition failure: e is not a valid regex.
std::invalid_argument ex("Invalid regular expression object");
boost::throw_exception(ex);
}
pstate = 0;
m_match_flags = f;
icase = re.flags() & regex_constants::icase;
estimate_max_state_count(static_cast<category*>(0));
if(!(m_match_flags & (match_perl|match_posix)))
{
if((re.flags() & (regbase::main_option_type|regbase::no_perl_ex)) == 0)
m_match_flags |= match_perl;
else if((re.flags() & (regbase::main_option_type|regbase::emacs_ex)) == (regbase::basic_syntax_group|regbase::emacs_ex))
m_match_flags |= match_perl;
else
m_match_flags |= match_posix;
}
if(m_match_flags & match_posix)
{
m_temp_match.reset(new match_results<BidiIterator, Allocator>());
m_presult = m_temp_match.get();
}
else
m_presult = &m_result;
#ifdef BOOST_REGEX_NON_RECURSIVE
m_stack_base = 0;
m_backup_state = 0;
#endif
// find the value to use for matching word boundaries:
const char_type w = static_cast<char_type>('w');
m_word_mask = traits_inst.lookup_classname(&w, &w+1);
// find bitmask to use for matching '.':
match_any_mask = static_cast<unsigned char>((f & match_not_dot_newline) ? re_detail::test_not_newline : re_detail::test_newline);
}
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
{
static const difference_type k = 100000;
difference_type dist = boost::re_detail::distance(base, last);
traits_size_type states = static_cast<traits_size_type>(re.size());
states *= states;
difference_type lim = ((std::numeric_limits<difference_type>::max)() - k) / states;
if(dist >= lim)
max_state_count = (std::numeric_limits<difference_type>::max)();
else
max_state_count = k + states * dist;
}
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
{
// we don't know how long the sequence is:
max_state_count = BOOST_REGEX_MAX_STATE_COUNT;
}
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(
protected_proc_type proc)
{
/*
__try{
return (this->*proc)();
}__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
{
reset_stack_guard_page();
}
// we only get here after a stack overflow:
raise_error<traits>(traits_inst, regex_constants::error_size);
// and we never really get here at all:
return false;
*/
::boost::re_detail::concrete_protected_call
<perl_matcher<BidiIterator, Allocator, traits> >
obj(this, proc);
return obj.execute();
}
#endif
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match()
{
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::match_imp);
#else
return match_imp();
#endif
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
{
// initialise our stack if we are non-recursive:
#ifdef BOOST_REGEX_NON_RECURSIVE
save_state_init init(&m_stack_base, &m_backup_state);
used_block_count = BOOST_REGEX_MAX_BLOCKS;
#if !defined(BOOST_NO_EXCEPTIONS)
try{
#endif
#endif
// reset our state machine:
position = base;
search_base = base;
state_count = 0;
m_match_flags |= regex_constants::match_all;
m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last);
m_presult->set_base(base);
if(m_match_flags & match_posix)
m_result = *m_presult;
verify_options(re.flags(), m_match_flags);
if(0 == match_prefix())
return false;
return m_result[0].second == last;
#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)
}
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
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find()
{
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::find_imp);
#else
return find_imp();
#endif
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
{
static matcher_proc_type const s_find_vtable[7] =
{
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,
&perl_matcher<BidiIterator, Allocator, traits>::match_prefix,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
};
// initialise our stack if we are non-recursive:
#ifdef BOOST_REGEX_NON_RECURSIVE
save_state_init init(&m_stack_base, &m_backup_state);
used_block_count = BOOST_REGEX_MAX_BLOCKS;
#if !defined(BOOST_NO_EXCEPTIONS)
try{
#endif
#endif
state_count = 0;
if((m_match_flags & regex_constants::match_init) == 0)
{
// reset our state machine:
position = base;
search_base = base;
pstate = re.get_first_state();
m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last);
m_presult->set_base(base);
m_match_flags |= regex_constants::match_init;
}
else
{
// start again:
search_base = position = m_result[0].second;
// If last match was null and match_not_null was not set then increment
// our start position, otherwise we go into an infinite loop:
if(((m_match_flags & match_not_null) == 0) && (m_result.length() == 0))
{
if(position == last)
return false;
else
++position;
}
// reset $` start:
m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last);
if(base != search_base)
m_match_flags |= match_prev_avail;
}
if(m_match_flags & match_posix)
{
m_result.set_size(re.mark_count(), base, last);
m_result.set_base(base);
}
verify_options(re.flags(), m_match_flags);
// find out what kind of expression we have:
unsigned type = (m_match_flags & match_continuous) ?
static_cast<unsigned int>(regbase::restart_continue)
: static_cast<unsigned int>(re.get_restart_type());
// call the appropriate search routine:
matcher_proc_type proc = s_find_vtable[type];
return (this->*proc)();
#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_NO_EXCEPTIONS)
}
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;
( run in 0.479 second using v1.01-cache-2.11-cpan-e1769b4cff6 )