forked from boostorg/regex
Added support for Perl style \N \P and \p.
Completed first draft of Unicode UCS-4 support. Broken compiler compatibility fixes. Added unicode_iterators. [SVN r26185]
This commit is contained in:
1 parent
f141de61ec
commit
d35e5a088e
17 files changed
+1051
-46
No files matched your search
@@ -611,6 +611,52 @@ bool basic_regex_parser<charT, traits>::parse_extended_escape()
|
||||
++m_position;
|
||||
this->append_state(syntax_element_restart_continue);
|
||||
break;
|
||||
case regex_constants::escape_type_not_property:
|
||||
negate = true;
|
||||
// fall through:
|
||||
case regex_constants::escape_type_property:
|
||||
{
|
||||
++m_position;
|
||||
char_class_type m;
|
||||
if(m_position == m_end)
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
// maybe have \p{ddd}
|
||||
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
|
||||
{
|
||||
const charT* base = m_position;
|
||||
// skip forward until we find enclosing brace:
|
||||
while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
|
||||
++m_position;
|
||||
if(m_position == m_end)
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
m = this->m_traits.lookup_classname(++base, m_position++);
|
||||
}
|
||||
else
|
||||
{
|
||||
m = this->m_traits.lookup_classname(m_position, m_position+1);
|
||||
++m_position;
|
||||
}
|
||||
if(m != 0)
|
||||
{
|
||||
basic_char_set<charT, traits> char_set;
|
||||
if(negate)
|
||||
char_set.negate();
|
||||
char_set.add_class(m);
|
||||
if(0 == this->append_set(char_set))
|
||||
{
|
||||
fail(regex_constants::error_ctype, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
fail(regex_constants::error_ctype, m_position - m_base);
|
||||
}
|
||||
default:
|
||||
this->append_literal(unescape_character());
|
||||
break;
|
||||
@@ -948,6 +994,7 @@ bool basic_regex_parser<charT, traits>::parse_set()
|
||||
if(m != 0)
|
||||
{
|
||||
char_set.add_class(m);
|
||||
++m_position;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1373,6 +1420,41 @@ charT basic_regex_parser<charT, traits>::unescape_character()
|
||||
}
|
||||
return static_cast<charT>(val);
|
||||
}
|
||||
case regex_constants::escape_type_named_char:
|
||||
{
|
||||
++m_position;
|
||||
if(m_position == m_end)
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
// maybe have \N{name}
|
||||
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_open_brace)
|
||||
{
|
||||
const charT* base = m_position;
|
||||
// skip forward until we find enclosing brace:
|
||||
while((m_position != m_end) && (this->m_traits.syntax_type(*m_position) != regex_constants::syntax_close_brace))
|
||||
++m_position;
|
||||
if(m_position == m_end)
|
||||
{
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
string_type s = this->m_traits.lookup_collatename(++base, m_position++);
|
||||
if(s.empty())
|
||||
{
|
||||
fail(regex_constants::error_collate, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
if(s.size() == 1)
|
||||
{
|
||||
return s[0];
|
||||
}
|
||||
}
|
||||
// fall through is a failure:
|
||||
fail(regex_constants::error_escape, m_position - m_base);
|
||||
return false;
|
||||
}
|
||||
default:
|
||||
result = *m_position;
|
||||
break;
|
||||
|
||||
@@ -75,7 +75,7 @@ class basic_regex_formatter
|
||||
public:
|
||||
typedef typename traits::char_type char_type;
|
||||
basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
|
||||
: m_traits(t), m_results(r), m_out(o), m_state(output_copy) {}
|
||||
: m_traits(t), m_results(r), m_out(o), m_state(output_copy), m_have_conditional(false) {}
|
||||
OutputIterator format(const char_type* p1, const char_type* p2, match_flag_type f);
|
||||
OutputIterator format(const char_type* p1, match_flag_type f)
|
||||
{
|
||||
@@ -108,6 +108,7 @@ private:
|
||||
const char_type* m_end; // format string end
|
||||
match_flag_type m_flags; // format flags to use
|
||||
output_state m_state; // what to do with the next character
|
||||
bool m_have_conditional; // we are parsing a conditional
|
||||
private:
|
||||
basic_regex_formatter(const basic_regex_formatter&);
|
||||
basic_regex_formatter& operator=(const basic_regex_formatter&);
|
||||
@@ -147,7 +148,10 @@ void basic_regex_formatter<OutputIterator, Results, traits>::format_all()
|
||||
if(m_flags & boost::regex_constants::format_all)
|
||||
{
|
||||
++m_position;
|
||||
bool have_conditional = m_have_conditional;
|
||||
m_have_conditional = false;
|
||||
format_until_scope_end();
|
||||
m_have_conditional = have_conditional;
|
||||
if(m_position == m_end)
|
||||
return;
|
||||
BOOST_ASSERT(*m_position == static_cast<char_type>(')'));
|
||||
@@ -158,7 +162,6 @@ void basic_regex_formatter<OutputIterator, Results, traits>::format_all()
|
||||
++m_position;
|
||||
break;
|
||||
case ')':
|
||||
case ':':
|
||||
if(m_flags & boost::regex_constants::format_all)
|
||||
{
|
||||
return;
|
||||
@@ -166,6 +169,14 @@ void basic_regex_formatter<OutputIterator, Results, traits>::format_all()
|
||||
put(*m_position);
|
||||
++m_position;
|
||||
break;
|
||||
case ':':
|
||||
if((m_flags & boost::regex_constants::format_all) && m_have_conditional)
|
||||
{
|
||||
return;
|
||||
}
|
||||
put(*m_position);
|
||||
++m_position;
|
||||
break;
|
||||
case '?':
|
||||
if(m_flags & boost::regex_constants::format_all)
|
||||
{
|
||||
@@ -405,7 +416,9 @@ void basic_regex_formatter<OutputIterator, Results, traits>::format_conditional(
|
||||
// output varies depending upon whether sub-expression v matched or not:
|
||||
if(m_results[v].matched)
|
||||
{
|
||||
m_have_conditional = true;
|
||||
format_all();
|
||||
m_have_conditional = false;
|
||||
if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
|
||||
{
|
||||
// skip the ':':
|
||||
@@ -425,7 +438,9 @@ void basic_regex_formatter<OutputIterator, Results, traits>::format_conditional(
|
||||
output_state saved_state = m_state;
|
||||
m_state = output_none;
|
||||
// format until ':' or ')':
|
||||
m_have_conditional = true;
|
||||
format_all();
|
||||
m_have_conditional = false;
|
||||
// restore state:
|
||||
m_state = saved_state;
|
||||
if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
|
||||
|
||||
@@ -89,7 +89,11 @@ static const escape_syntax_type escape_type_C = 50; /
|
||||
static const escape_syntax_type escape_type_Z = 51; // for \Z
|
||||
static const escape_syntax_type escape_type_G = 52; // for \G
|
||||
|
||||
static const escape_syntax_type syntax_max = 54;
|
||||
static const escape_syntax_type escape_type_property = 54; // for \p
|
||||
static const escape_syntax_type escape_type_not_property = 55; // for \P
|
||||
static const escape_syntax_type escape_type_named_char = 56; // for \N
|
||||
|
||||
static const escape_syntax_type syntax_max = 57;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user