Completed perl feature set.

Merged in changes to Docs from main branch.


[SVN r22785]
This commit is contained in:
John Maddock committed 2004-05-11 10:27:13 +00:00
1 parent b5cf51fbc6
commit bb264b055f
38 files changed
+2253 -1786

No files matched your search

+32 -3
View File
@@ -185,6 +185,14 @@ public:
{
return m_pdata->m_flags;
}
void flags(regbase::flag_type f)
{
m_pdata->m_flags = f;
if(m_icase != static_cast<bool>(f & regbase::icase))
{
m_icase = static_cast<bool>(f & regbase::icase);
}
}
re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
re_literal* append_literal(charT c);
@@ -633,10 +641,19 @@ void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
// recursive implementation:
// create the last map in the machine first, so that earlier maps
// can make use of the result...
// start by saving the case setting:
bool l_icase = m_icase;
while(state)
{
switch(state->type)
{
case syntax_element_toggle_case:
// we need to track case changes here:
m_icase = static_cast<re_case*>(state)->icase;
state = state->next.p;
continue;
case syntax_element_alt:
case syntax_element_rep:
case syntax_element_dot_rep:
@@ -652,6 +669,8 @@ void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
create_startmap(static_cast<re_alt*>(state)->alt.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_skip);
// adjust the type of the state to allow for faster matching:
state->type = this->get_repeat_type(state);
// restore case sensitivity:
m_icase = l_icase;
return;
case syntax_element_backstep:
// we need to calculate how big the backstep is:
@@ -662,6 +681,8 @@ void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
state = state->next.p;
}
}
// restore case sensitivity:
m_icase = l_icase;
}
template <class charT, class traits>
@@ -726,10 +747,18 @@ template <class charT, class traits>
void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state, unsigned char* l_map, unsigned int* pnull, unsigned char mask)
{
int not_last_jump = 1;
// track case sensitivity:
bool l_icase = m_icase;
while(state)
{
switch(state->type)
{
case syntax_element_toggle_case:
l_icase = static_cast<re_case*>(state)->icase;
state = state->next.p;
break;
case syntax_element_literal:
{
// don't set anything in *pnull, set each element in l_map
@@ -740,7 +769,7 @@ void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state,
charT first_char = *static_cast<charT*>(static_cast<void*>(static_cast<re_literal*>(state) + 1));
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
if(m_traits.translate(static_cast<charT>(i), m_icase) == first_char)
if(m_traits.translate(static_cast<charT>(i), l_icase) == first_char)
l_map[i] |= mask;
}
}
@@ -826,7 +855,7 @@ void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state,
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
charT c = static_cast<charT>(i);
if(&c != re_is_set_member(&c, &c + 1, static_cast<re_set_long<mask_type>*>(state), *m_pdata))
if(&c != re_is_set_member(&c, &c + 1, static_cast<re_set_long<mask_type>*>(state), *m_pdata, m_icase))
l_map[i] |= mask;
}
}
@@ -841,7 +870,7 @@ void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state,
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
if(static_cast<re_set*>(state)->_map[
static_cast<unsigned char>(m_traits.translate(static_cast<charT>(i), this->m_icase))])
static_cast<unsigned char>(m_traits.translate(static_cast<charT>(i), l_icase))])
l_map[i] |= mask;
}
}
+211 -18
View File
@@ -53,6 +53,7 @@ public:
bool parse_perl_extension();
digraph<charT> get_next_set_literal(basic_char_set<charT, traits>& char_set);
charT unescape_character();
regex_constants::syntax_option_type parse_options();
private:
typedef bool (basic_regex_parser::*parser_proc_type)();
@@ -65,6 +66,7 @@ private:
unsigned m_mark_count; // how many sub-expressions we have
std::ptrdiff_t m_paren_start; // where the last seen ')' began (where repeats are inserted).
std::ptrdiff_t m_alt_insert_point; // where to insert the next alternative
bool m_has_case_change; // true if somewhere in the current block the case has changed
basic_regex_parser& operator=(const basic_regex_parser&);
basic_regex_parser(const basic_regex_parser&);
@@ -72,7 +74,7 @@ private:
template <class charT, class traits>
basic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)
: basic_regex_creator<charT, traits>(data), m_mark_count(0), m_paren_start(0), m_alt_insert_point(0)
: basic_regex_creator<charT, traits>(data), m_mark_count(0), m_paren_start(0), m_alt_insert_point(0), m_has_case_change(false)
{
}
@@ -103,6 +105,8 @@ void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2,
// parse all our characters:
bool result = parse_all();
// reset flags as a global scope (?imsx) may have altered them:
this->flags(flags);
// if we haven't gobbled up all the characters then we must
// have had an unexpected ')' :
if(!result)
@@ -184,11 +188,13 @@ bool basic_regex_parser<charT, traits>::parse_extended()
return parse_match_any();
case regex_constants::syntax_caret:
++m_position;
this->append_state(syntax_element_start_line);
this->append_state(
(this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_start : syntax_element_start_line));
break;
case regex_constants::syntax_dollar:
++m_position;
this->append_state(syntax_element_end_line);
this->append_state(
(this->flags() & regex_constants::no_mod_m ? syntax_element_buffer_end : syntax_element_end_line));
break;
case regex_constants::syntax_star:
if(m_position == this->m_base)
@@ -218,6 +224,19 @@ bool basic_regex_parser<charT, traits>::parse_extended()
return parse_alt();
case regex_constants::syntax_open_set:
return parse_set();
case regex_constants::syntax_hash:
//
// If we have a mod_x flag set, then skip until
// we get to a newline character:
//
if((this->flags()
& (regbase::no_perl_ex|regbase::mod_x))
== regbase::mod_x)
{
while((m_position != m_end) && !is_separator(*m_position++)){}
return true;
}
// Otherwise fall through:
default:
result = parse_literal();
break;
@@ -231,7 +250,14 @@ bool basic_regex_parser<charT, traits>::parse_extended()
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_literal()
{
this->append_literal(*m_position);
// append this as a literal provided it's not a space character
// or the perl option regbase::mod_x is not set:
if(
((this->flags()
& (regbase::main_option_type|regbase::mod_x|regbase::no_perl_ex))
!= regbase::mod_x)
|| !this->m_traits.is_class(*m_position, this->m_mask_space))
this->append_literal(*m_position);
++m_position;
return true;
}
@@ -266,11 +292,31 @@ bool basic_regex_parser<charT, traits>::parse_open_paren()
this->m_pdata->m_data.align();
m_alt_insert_point = this->m_pdata->m_data.size();
//
// back up the current flags in case we have a nested (?imsx) group:
//
regex_constants::syntax_option_type opts = this->flags();
bool old_case_change = m_has_case_change;
m_has_case_change = false; // no changes to this scope as yet...
//
// now recursively add more states, this will terminate when we get to a
// matching ')' :
//
parse_all();
//
// restore flags:
//
if(m_has_case_change)
{
// the case has changed in one or more of the alternatives
// within the scoped (...) block: we have to add a state
// to reset the case sensitivity:
static_cast<re_case*>(
this->append_state(syntax_element_toggle_case, sizeof(re_case))
)->icase = opts & regbase::icase;
}
this->flags(opts);
m_has_case_change = old_case_change;
//
// we either have a ')' or we have run out of characters prematurely:
//
if(m_position == m_end)
@@ -436,7 +482,12 @@ bool basic_regex_parser<charT, traits>::parse_match_any()
// we have a '.' that can match any character:
//
++m_position;
this->append_state(syntax_element_wild);
static_cast<re_dot*>(
this->append_state(syntax_element_wild, sizeof(re_dot))
)->mask = this->flags() & regbase::no_mod_s
? re_detail::force_not_newline
: this->flags() & regbase::mod_s ?
re_detail::force_newline : re_detail::dont_care;
return true;
}
@@ -609,10 +660,13 @@ bool basic_regex_parser<charT, traits>::parse_alt()
fail(REG_EMPTY, this->m_position - this->m_base);
++m_position;
//
// we need to append a trailing jump, then insert the alternative:
// we need to append a trailing jump:
//
re_syntax_base* pj = this->append_state(re_detail::syntax_element_jump, sizeof(re_jump));
std::ptrdiff_t jump_offset = this->getoffset(pj);
//
// now insert the alternative:
//
re_alt* palt = static_cast<re_alt*>(this->insert_state(this->m_alt_insert_point, syntax_element_alt, re_alt_size));
jump_offset += re_alt_size;
this->m_pdata->m_data.align();
@@ -623,6 +677,16 @@ bool basic_regex_parser<charT, traits>::parse_alt()
//
this->m_alt_insert_point = this->m_pdata->m_data.size();
//
// the start of this alternative must have a case changes state
// if the current block has messed around with case changes:
//
if(m_has_case_change)
{
static_cast<re_case*>(
this->append_state(syntax_element_toggle_case, sizeof(re_case))
)->icase = this->m_icase;
}
//
// recursively add states:
//
bool result = this->parse_all();
@@ -633,7 +697,7 @@ bool basic_regex_parser<charT, traits>::parse_alt()
fail(REG_EMPTY, this->m_position - this->m_base);
//
// fix up the jump we added to point to the end of the states
// that we're just added:
// that we've just added:
//
this->m_pdata->m_data.align();
re_jump* jmp = static_cast<re_jump*>(this->getaddress(jump_offset));
@@ -1083,7 +1147,13 @@ bool basic_regex_parser<charT, traits>::parse_QE()
while((m_position != m_end)
&& (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_escape))
++m_position;
if((m_position == m_end) || (++m_position == m_end)) // skip the escape
if(m_position == m_end)
{
// a \Q...\E sequence may terminate with the end of the expression:
end = m_position;
break;
}
if(++m_position == m_end) // skip the escape
{
fail(REG_EESCAPE, m_position - m_base);
return false;
@@ -1117,6 +1187,18 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
if(++m_position == m_end)
fail(REG_BADRPT, m_position - m_base);
//
// treat comments as a special case, as these
// are the only ones that don't start with a leading
// startmark state:
//
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_hash)
{
while((m_position != m_end)
&& (this->m_traits.syntax_type(*m_position++) != regex_constants::syntax_close_mark))
{}
return true;
}
//
// backup some state, and prepare the way:
//
int markid = 0;
@@ -1128,6 +1210,10 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
this->m_pdata->m_data.align();
m_alt_insert_point = this->m_pdata->m_data.size();
std::ptrdiff_t expected_alt_point = m_alt_insert_point;
bool restore_flags = true;
regex_constants::syntax_option_type old_flags = this->flags();
bool old_case_change = m_has_case_change;
m_has_case_change = false;
//
// select the actual extension used:
//
@@ -1140,15 +1226,6 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
pb->index = markid = 0;
++m_position;
break;
case regex_constants::syntax_hash:
//
// a comment; this actually becomes an empty non-capturing mark:
//
pb->index = markid = 0;
while((m_position != m_end)
&& (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_mark))
++m_position;
break;
case regex_constants::syntax_equal:
pb->index = markid = -1;
++m_position;
@@ -1235,7 +1312,37 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
break;
}
default:
fail(REG_BADRPT, m_position - m_base);
//
// lets assume that we have a (?imsx) group and try and parse it:
//
regex_constants::syntax_option_type opts = parse_options();
// make a note of whether we have a case change:
m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));
pb->index = markid = 0;
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark)
{
// update flags and carry on as normal:
this->flags(opts);
restore_flags = false;
old_case_change |= m_has_case_change; // defer end of scope by one ')'
}
else if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_colon)
{
// update flags and carry on until the matching ')' is found:
this->flags(opts);
++m_position;
}
else
fail(REG_BADRPT, m_position - m_base);
// finally append a case change state if we need it:
if(m_has_case_change)
{
static_cast<re_case*>(
this->append_state(syntax_element_toggle_case, sizeof(re_case))
)->icase = opts & regbase::icase;
}
}
//
// now recursively add more states, this will terminate when we get to a
@@ -1250,6 +1357,20 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
++m_position;
//
// restore the flags:
//
if(restore_flags)
{
// append a case change state if we need it:
if(m_has_case_change)
{
static_cast<re_case*>(
this->append_state(syntax_element_toggle_case, sizeof(re_case))
)->icase = old_flags & regbase::icase;
}
this->flags(old_flags);
}
//
// set up the jump pointer if we have one:
//
if(jump_offset)
@@ -1275,6 +1396,8 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
re_alt* alt = static_cast<re_alt*>(this->insert_state(expected_alt_point, syntax_element_alt, sizeof(re_alt)));
alt->alt.i = this->m_pdata->m_data.size() - this->getoffset(alt);
}
else if(this->getaddress(static_cast<re_alt*>(b)->alt.i, b)->type == syntax_element_alt)
fail(REG_BADPAT, m_position - m_base);
}
//
// append closing parenthesis state:
@@ -1286,9 +1409,79 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
// restore the alternate insertion point:
//
this->m_alt_insert_point = last_alt_point;
//
// and the case change data:
//
m_has_case_change = old_case_change;
return true;
}
template <class charT, class traits>
regex_constants::syntax_option_type basic_regex_parser<charT, traits>::parse_options()
{
// we have a (?imsx-imsx) group, convert it into a set of flags:
regex_constants::syntax_option_type f = this->flags();
bool breakout = false;
do
{
switch(*m_position)
{
case 's':
f |= regex_constants::mod_s;
f &= ~regex_constants::no_mod_s;
break;
case 'm':
f &= ~regex_constants::no_mod_m;
break;
case 'i':
f |= regex_constants::icase;
break;
case 'x':
f |= regex_constants::mod_x;
break;
default:
breakout = true;
continue;
}
if(++m_position == m_end)
fail(REG_EPAREN, m_position - m_base);
}
while(!breakout);
if(*m_position == '-')
{
if(++m_position == m_end)
fail(REG_EPAREN, m_position - m_base);
do
{
switch(*m_position)
{
case 's':
f &= ~regex_constants::mod_s;
f |= regex_constants::no_mod_s;
break;
case 'm':
f |= regex_constants::no_mod_m;
break;
case 'i':
f &= ~regex_constants::icase;
break;
case 'x':
f &= ~regex_constants::mod_x;
break;
default:
breakout = true;
continue;
}
if(++m_position == m_end)
fail(REG_EPAREN, m_position - m_base);
}
while(!breakout);
}
return f;
}
} // namespace re_detail
} // namespace boost
+5 -2
View File
@@ -91,12 +91,12 @@ template <class iterator, class charT, class traits_type, class char_classT>
iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
iterator last,
const re_set_long<char_classT>* set_,
const regex_data<charT, traits_type>& e)
const regex_data<charT, traits_type>& e, bool icase)
{
const charT* p = reinterpret_cast<const charT*>(set_+1);
iterator ptr;
unsigned int i;
bool icase = e.m_flags & regex_constants::icase;
//bool icase = e.m_flags & regex_constants::icase;
if(next == last) return next;
@@ -335,6 +335,7 @@ private:
bool match_dot_repeat_slow();
bool match_backstep();
bool match_assert_backref();
bool match_toggle_case();
bool backtrack_till_match(unsigned count);
// find procs stored in s_find_vtable:
@@ -385,6 +386,8 @@ private:
repeater_count<BidiIterator> rep_obj;
// the mask to pass when matching word boundaries:
typename traits::char_class_type m_word_mask;
// the bitmask to use when determining whether a match_any matches a newline or not:
unsigned char match_any_mask;
#ifdef BOOST_REGEX_NON_RECURSIVE
//
+14 -2
View File
@@ -73,6 +73,8 @@ perl_matcher<BidiIterator, Allocator, traits>::perl_matcher(BidiIterator first,
// 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 = (f & match_not_dot_newline) ? re_detail::test_not_newline : re_detail::test_newline;
}
template <class BidiIterator, class Allocator, class traits>
@@ -395,7 +397,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_wild()
{
if(position == last)
return false;
if(is_separator(*position) && (m_match_flags & match_not_dot_newline))
if(is_separator(*position) && ((match_any_mask & static_cast<const re_dot*>(pstate)->mask) == 0))
return false;
if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))
return false;
@@ -590,7 +592,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()
// let the traits class do the work:
if(position == last)
return false;
BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data());
BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<char_class_type>*>(pstate), re.get_data(), icase);
if(t != position)
{
pstate = pstate->next.p;
@@ -678,6 +680,16 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_assert_backref()
return (*m_presult)[static_cast<const re_brace*>(pstate)->index].matched;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_toggle_case()
{
// change our case sensitivity:
this->icase = static_cast<const re_case*>(pstate)->icase;
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
{
@@ -113,7 +113,7 @@ struct saved_single_repeat : public saved_state
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
{
static matcher_proc_type const s_match_vtable[28] =
static matcher_proc_type const s_match_vtable[29] =
{
(&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
@@ -143,6 +143,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
&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,
};
push_recursion_stopper();
@@ -575,7 +576,9 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
{
if(m_match_flags & (match_not_dot_newline | match_not_dot_null))
if(m_match_flags & match_not_dot_null)
return match_dot_repeat_slow();
if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
return match_dot_repeat_slow();
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
@@ -763,7 +766,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
BidiIterator end = position;
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data())))
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
{
++position;
}
@@ -771,7 +774,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
}
else
{
while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data())))
while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
{
++position;
++count;
@@ -1269,7 +1272,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool
// wind forward until we can skip out of the repeat:
do
{
if(position == re_is_set_member(position, last, set, re.get_data()))
if(position == re_is_set_member(position, last, set, re.get_data(), icase))
{
// failed repeat match, discard this state and look for another:
destroy_single_repeat();
@@ -48,7 +48,7 @@ public:
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
{
static matcher_proc_type const s_match_vtable[28] =
static matcher_proc_type const s_match_vtable[29] =
{
(&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
@@ -78,6 +78,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
&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,
};
if(state_count > max_state_count)
@@ -427,7 +428,9 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
#pragma warning(push)
#pragma warning(disable:4127)
#endif
if(m_match_flags & (match_not_dot_newline | match_not_dot_null))
if(m_match_flags & match_not_dot_null)
return match_dot_repeat_slow();
if((static_cast<const re_dot*>(pstate->next.p)->mask & match_any_mask) == 0)
return match_dot_repeat_slow();
//
// start by working out how much we can skip:
@@ -670,7 +673,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
BidiIterator end = position;
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data())))
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
{
++position;
}
@@ -678,7 +681,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
}
else
{
while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data())))
while((count < desired) && (position != last) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
{
++position;
++count;
@@ -698,7 +701,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
{
while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
{
if(position != re_is_set_member(position, last, set, re.get_data()))
if(position != re_is_set_member(position, last, set, re.get_data(), icase))
{
++position;
++count;
@@ -718,7 +721,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
if(position == last)
return false;
position = save_pos;
if(position != re_is_set_member(position, last, set, re.get_data()))
if(position != re_is_set_member(position, last, set, re.get_data(), icase))
{
++position;
++count;
+8
View File
@@ -52,6 +52,10 @@ public:
//
no_bk_refs = 1 << 8, // \d not allowed
no_perl_ex = 1 << 9, // disable perl extensions
no_mod_m = 1 << 10, // disable Perl m modifier
mod_x = 1 << 11, // Perl x modifier
mod_s = 1 << 12, // force s modifier on (overrides match_not_dot_newline)
no_mod_s = 1 << 13, // force s modifier off (overrides match_not_dot_newline)
//
// options specific to basic group:
@@ -125,6 +129,10 @@ namespace regex_constants{
no_intervals = ::boost::regbase::no_intervals,
no_char_classes = ::boost::regbase::no_char_classes,
no_escape_in_lists = ::boost::regbase::no_escape_in_lists,
no_mod_m = ::boost::regbase::no_mod_m,
mod_x = ::boost::regbase::mod_x,
mod_s = ::boost::regbase::mod_s,
no_mod_s = ::boost::regbase::no_mod_s,
basic = ::boost::regbase::basic,
extended = ::boost::regbase::extended,
+29 -3
View File
@@ -110,7 +110,8 @@ enum syntax_element_type
// a backstep for lookbehind repeats:
syntax_element_backstep = syntax_element_long_set_rep + 1,
// an assertion that a mark was matched:
syntax_element_assert_backref = syntax_element_backstep +1
syntax_element_assert_backref = syntax_element_backstep + 1,
syntax_element_toggle_case = syntax_element_assert_backref + 1
};
#ifdef BOOST_REGEX_DEBUG
@@ -141,7 +142,7 @@ struct re_syntax_base
};
/*** struct re_brace **************************************************
Base class for all states in the machine.
A marked parenthesis.
***********************************************************************/
struct re_brace : public re_syntax_base
{
@@ -150,6 +151,23 @@ struct re_brace : public re_syntax_base
int index;
};
/*** struct re_dot **************************************************
Match anything.
***********************************************************************/
enum
{
dont_care = 1,
force_not_newline = 0,
force_newline = 2,
test_not_newline = 2,
test_newline = 3,
};
struct re_dot : public re_syntax_base
{
unsigned char mask;
};
/*** struct re_literal ************************************************
A string of literals, following this structure will be an
array of characters: charT[length]
@@ -159,6 +177,14 @@ struct re_literal : public re_syntax_base
unsigned int length;
};
/*** struct re_case ************************************************
Indicates whether we are moving to a case insensive block or not
***********************************************************************/
struct re_case : public re_syntax_base
{
bool icase;
};
/*** struct re_set_long ***********************************************
A wide character set of characters, following this structure will be
an array of type charT:
@@ -234,7 +260,7 @@ template <class iterator, class charT, class traits_type, class char_classT>
iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
iterator last,
const re_set_long<char_classT>* set_,
const regex_data<charT, traits_type>& e);
const regex_data<charT, traits_type>& e, bool icase);
} // namespace re_detail