Fixed remaining zero-width assertion issues.

Added separate file instantiation of ICU support templates.
Ensured code is STLport debug mode clean.


[SVN r30980]
This commit is contained in:
John Maddock
2005-09-14 12:20:41 +00:00
parent 90f4367b8d
commit 40b7a4902f
26 changed files with 358 additions and 112 deletions

View File

@ -47,6 +47,10 @@ rule check-icu-config ( )
{ {
gICU_LIBS += <library-file>$(ICU_PATH)/lib/cygicuuc.dll ; gICU_LIBS += <library-file>$(ICU_PATH)/lib/cygicuuc.dll ;
} }
else if [ GLOB $(ICU_PATH)/lib : cygicuuc32.dll ]
{
gICU_LIBS += <library-file>$(ICU_PATH)/lib/cygicuuc32.dll ;
}
else if [ GLOB /usr/local/lib : cygicuuc.dll ] else if [ GLOB /usr/local/lib : cygicuuc.dll ]
{ {
gICU_LIBS += <library-file>/usr/local/lib/cygicuuc.dll ; gICU_LIBS += <library-file>/usr/local/lib/cygicuuc.dll ;
@ -85,6 +89,10 @@ rule check-icu-config ( )
{ {
gICU_LIBS += <library-file>$(ICU_PATH)/lib/cygicuin.dll ; gICU_LIBS += <library-file>$(ICU_PATH)/lib/cygicuin.dll ;
} }
else if [ GLOB $(ICU_PATH)/lib : cygicuin32.dll ]
{
gICU_LIBS += <library-file>$(ICU_PATH)/lib/cygicuin32.dll ;
}
else if [ GLOB /usr/local/lib : cygicuin.dll ] else if [ GLOB /usr/local/lib : cygicuin.dll ]
{ {
gICU_LIBS += <library-file>/usr/local/lib/cygicuin.dll ; gICU_LIBS += <library-file>/usr/local/lib/cygicuin.dll ;
@ -255,3 +263,5 @@ install regex lib

View File

@ -57,7 +57,15 @@
Initialise all the data members of the unicode_iterators: this keeps gcc from Initialise all the data members of the unicode_iterators: this keeps gcc from
issuing needless warnings. issuing needless warnings.
<LI> <LI>
Ported the ICU integration code to VC6 and VC7.</LI></UL> Ported the ICU integration code to VC6 and VC7.
<LI>
Ensured code is STLport debug mode clean.
<LI>
Fixed lookbehind assertions so that fixed length repeats are permitted, and so
that regex iteration allows lookbehind to look back before the current search
range (into the last match).
<LI>
Fixed strange bug with non-greedy repeats inside forward lookahead assertions.</LI></UL>
<P>Boost 1.33.0.</P> <P>Boost 1.33.0.</P>
<UL> <UL>
<LI> <LI>

View File

@ -57,7 +57,15 @@
Initialise all the data members of the unicode_iterators: this keeps gcc from Initialise all the data members of the unicode_iterators: this keeps gcc from
issuing needless warnings. issuing needless warnings.
<LI> <LI>
Ported the ICU integration code to VC6 and VC7.</LI></UL> Ported the ICU integration code to VC6 and VC7.
<LI>
Ensured code is STLport debug mode clean.
<LI>
Fixed lookbehind assertions so that fixed length repeats are permitted, and so
that regex iteration allows lookbehind to look back before the current search
range (into the last match).
<LI>
Fixed strange bug with non-greedy repeats inside forward lookahead assertions.</LI></UL>
<P>Boost 1.33.0.</P> <P>Boost 1.33.0.</P>
<UL> <UL>
<LI> <LI>

View File

@ -203,6 +203,28 @@ private:
boost::shared_ptr< ::boost::re_detail::icu_regex_traits_implementation> m_pimpl; boost::shared_ptr< ::boost::re_detail::icu_regex_traits_implementation> m_pimpl;
}; };
} // namespace boost
//
// template instances:
//
#define BOOST_REGEX_CHAR_T UChar32
#undef BOOST_REGEX_TRAITS_T
#define BOOST_REGEX_TRAITS_T , icu_regex_traits
#define BOOST_REGEX_ICU_INSTANCES
#ifdef BOOST_REGEX_ICU_INSTANTIATE
# define BOOST_REGEX_INSTANTIATE
#endif
#include <boost/regex/v4/instances.hpp>
#undef BOOST_REGEX_CHAR_T
#undef BOOST_REGEX_TRAITS_T
#undef BOOST_REGEX_ICU_INSTANCES
#ifdef BOOST_REGEX_INSTANTIATE
# undef BOOST_REGEX_INSTANTIATE
#endif
namespace boost{
// types: // types:
typedef basic_regex< ::UChar32, icu_regex_traits> u32regex; typedef basic_regex< ::UChar32, icu_regex_traits> u32regex;
typedef match_results<const ::UChar32*> u32match; typedef match_results<const ::UChar32*> u32match;
@ -258,7 +280,9 @@ inline u32regex do_make_u32regex(InputIterator i,
v.push_back(*a); v.push_back(*a);
++a; ++a;
} }
return u32regex(&*v.begin(), v.size(), opt); if(v.size())
return u32regex(&*v.begin(), v.size(), opt);
return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
} }
template <class InputIterator> template <class InputIterator>
@ -276,7 +300,9 @@ inline u32regex do_make_u32regex(InputIterator i,
v.push_back(*a); v.push_back(*a);
++a; ++a;
} }
return u32regex(&*v.begin(), v.size(), opt); if(v.size())
return u32regex(&*v.begin(), v.size(), opt);
return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
} }
template <class InputIterator> template <class InputIterator>
@ -292,7 +318,9 @@ inline u32regex do_make_u32regex(InputIterator i,
v.push_back((UCHAR32)(*i)); v.push_back((UCHAR32)(*i));
++a; ++a;
} }
return u32regex(&*v.begin(), v.size(), opt); if(v.size())
return u32regex(&*v.begin(), v.size(), opt);
return u32regex(static_cast<UChar32 const*>(0), static_cast<u32regex::size_type>(0), opt);
} }
#endif #endif
} }
@ -547,22 +575,24 @@ inline bool do_regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m, match_results<BidiIterator, Allocator>& m,
const u32regex& e, const u32regex& e,
match_flag_type flags, match_flag_type flags,
BidiIterator base,
boost::mpl::int_<4> const*) boost::mpl::int_<4> const*)
{ {
return ::boost::regex_search(first, last, m, e, flags); return ::boost::regex_search(first, last, m, e, flags, base);
} }
template <class BidiIterator, class Allocator> template <class BidiIterator, class Allocator>
bool do_regex_search(BidiIterator first, BidiIterator last, bool do_regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m, match_results<BidiIterator, Allocator>& m,
const u32regex& e, const u32regex& e,
match_flag_type flags, match_flag_type flags,
BidiIterator base,
boost::mpl::int_<2> const*) boost::mpl::int_<2> const*)
{ {
typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type; typedef u16_to_u32_iterator<BidiIterator, UChar32> conv_type;
typedef match_results<conv_type> match_type; typedef match_results<conv_type> match_type;
typedef typename match_type::allocator_type alloc_type; typedef typename match_type::allocator_type alloc_type;
match_type what; match_type what;
bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags); bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags, conv_type(base));
// copy results across to m: // copy results across to m:
if(result) copy_results(m, what); if(result) copy_results(m, what);
return result; return result;
@ -572,13 +602,14 @@ bool do_regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m, match_results<BidiIterator, Allocator>& m,
const u32regex& e, const u32regex& e,
match_flag_type flags, match_flag_type flags,
BidiIterator base,
boost::mpl::int_<1> const*) boost::mpl::int_<1> const*)
{ {
typedef u8_to_u32_iterator<BidiIterator, UChar32> conv_type; typedef u8_to_u32_iterator<BidiIterator, UChar32> conv_type;
typedef match_results<conv_type> match_type; typedef match_results<conv_type> match_type;
typedef typename match_type::allocator_type alloc_type; typedef typename match_type::allocator_type alloc_type;
match_type what; match_type what;
bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags); bool result = ::boost::regex_search(conv_type(first), conv_type(last), what, e, flags, conv_type(base));
// copy results across to m: // copy results across to m:
if(result) copy_results(m, what); if(result) copy_results(m, what);
return result; return result;
@ -591,14 +622,23 @@ inline bool u32regex_search(BidiIterator first, BidiIterator last,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0)); return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
}
template <class BidiIterator, class Allocator>
inline bool u32regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m,
const u32regex& e,
match_flag_type flags,
BidiIterator base)
{
return re_detail::do_regex_search(first, last, m, e, flags, base, static_cast<mpl::int_<sizeof(*first)> const*>(0));
} }
inline bool u32regex_search(const UChar* p, inline bool u32regex_search(const UChar* p,
match_results<const UChar*>& m, match_results<const UChar*>& m,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0)); return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
} }
#if !defined(U_WCHAR_IS_UTF16) && !defined(BOOST_NO_WREGEX) #if !defined(U_WCHAR_IS_UTF16) && !defined(BOOST_NO_WREGEX)
inline bool u32regex_search(const wchar_t* p, inline bool u32regex_search(const wchar_t* p,
@ -606,7 +646,7 @@ inline bool u32regex_search(const wchar_t* p,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0)); return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
} }
#endif #endif
inline bool u32regex_search(const char* p, inline bool u32regex_search(const char* p,
@ -614,21 +654,21 @@ inline bool u32regex_search(const char* p,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0)); return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
} }
inline bool u32regex_search(const unsigned char* p, inline bool u32regex_search(const unsigned char* p,
match_results<const unsigned char*>& m, match_results<const unsigned char*>& m,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0)); return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
} }
inline bool u32regex_search(const std::string& s, inline bool u32regex_search(const std::string& s,
match_results<std::string::const_iterator>& m, match_results<std::string::const_iterator>& m,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0)); return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
} }
#ifndef BOOST_NO_STD_WSTRING #ifndef BOOST_NO_STD_WSTRING
inline bool u32regex_search(const std::wstring& s, inline bool u32regex_search(const std::wstring& s,
@ -636,7 +676,7 @@ inline bool u32regex_search(const std::wstring& s,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0)); return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
} }
#endif #endif
inline bool u32regex_search(const UnicodeString& s, inline bool u32regex_search(const UnicodeString& s,
@ -644,7 +684,7 @@ inline bool u32regex_search(const UnicodeString& s,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0)); return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
} }
template <class BidiIterator> template <class BidiIterator>
inline bool u32regex_search(BidiIterator first, BidiIterator last, inline bool u32regex_search(BidiIterator first, BidiIterator last,
@ -652,14 +692,14 @@ inline bool u32regex_search(BidiIterator first, BidiIterator last,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<BidiIterator> m; match_results<BidiIterator> m;
return re_detail::do_regex_search(first, last, m, e, flags, static_cast<mpl::int_<sizeof(*first)> const*>(0)); return re_detail::do_regex_search(first, last, m, e, flags, first, static_cast<mpl::int_<sizeof(*first)> const*>(0));
} }
inline bool u32regex_search(const UChar* p, inline bool u32regex_search(const UChar* p,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<const UChar*> m; match_results<const UChar*> m;
return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, static_cast<mpl::int_<2> const*>(0)); return re_detail::do_regex_search(p, p+u_strlen(p), m, e, flags, p, static_cast<mpl::int_<2> const*>(0));
} }
#if !defined(U_WCHAR_IS_UTF16) && !defined(BOOST_NO_WREGEX) #if !defined(U_WCHAR_IS_UTF16) && !defined(BOOST_NO_WREGEX)
inline bool u32regex_search(const wchar_t* p, inline bool u32regex_search(const wchar_t* p,
@ -667,7 +707,7 @@ inline bool u32regex_search(const wchar_t* p,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<const wchar_t*> m; match_results<const wchar_t*> m;
return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0)); return re_detail::do_regex_search(p, p+std::wcslen(p), m, e, flags, p, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
} }
#endif #endif
inline bool u32regex_search(const char* p, inline bool u32regex_search(const char* p,
@ -675,21 +715,21 @@ inline bool u32regex_search(const char* p,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<const char*> m; match_results<const char*> m;
return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, static_cast<mpl::int_<1> const*>(0)); return re_detail::do_regex_search(p, p+std::strlen(p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
} }
inline bool u32regex_search(const unsigned char* p, inline bool u32regex_search(const unsigned char* p,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<const unsigned char*> m; match_results<const unsigned char*> m;
return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, static_cast<mpl::int_<1> const*>(0)); return re_detail::do_regex_search(p, p+std::strlen((const char*)p), m, e, flags, p, static_cast<mpl::int_<1> const*>(0));
} }
inline bool u32regex_search(const std::string& s, inline bool u32regex_search(const std::string& s,
const u32regex& e, const u32regex& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<std::string::const_iterator> m; match_results<std::string::const_iterator> m;
return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<1> const*>(0)); return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<1> const*>(0));
} }
#ifndef BOOST_NO_STD_WSTRING #ifndef BOOST_NO_STD_WSTRING
inline bool u32regex_search(const std::wstring& s, inline bool u32regex_search(const std::wstring& s,
@ -697,7 +737,7 @@ inline bool u32regex_search(const std::wstring& s,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<std::wstring::const_iterator> m; match_results<std::wstring::const_iterator> m;
return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0)); return re_detail::do_regex_search(s.begin(), s.end(), m, e, flags, s.begin(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
} }
#endif #endif
inline bool u32regex_search(const UnicodeString& s, inline bool u32regex_search(const UnicodeString& s,
@ -705,7 +745,7 @@ inline bool u32regex_search(const UnicodeString& s,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
match_results<const UChar*> m; match_results<const UChar*> m;
return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, static_cast<mpl::int_<sizeof(wchar_t)> const*>(0)); return re_detail::do_regex_search(s.getBuffer(), s.getBuffer() + s.length(), m, e, flags, s.getBuffer(), static_cast<mpl::int_<sizeof(wchar_t)> const*>(0));
} }
// //
@ -797,7 +837,10 @@ OutputIterator do_regex_replace(OutputIterator out,
{ {
if(!(flags & regex_constants::format_no_copy)) if(!(flags & regex_constants::format_no_copy))
out = re_detail::copy(i->prefix().first, i->prefix().second, out); out = re_detail::copy(i->prefix().first, i->prefix().second, out);
out = ::boost::re_detail::regex_format_imp(out, *i, &*f.begin(), &*f.end(), flags, e.get_traits()); if(f.size())
out = ::boost::re_detail::regex_format_imp(out, *i, &*f.begin(), &*f.begin() + f.size(), flags, e.get_traits());
else
out = ::boost::re_detail::regex_format_imp(out, *i, static_cast<UChar32 const*>(0), static_cast<UChar32 const*>(0), flags, e.get_traits());
last_m = (*i)[0].second; last_m = (*i)[0].second;
if(flags & regex_constants::format_first_only) if(flags & regex_constants::format_first_only)
break; break;

View File

@ -23,15 +23,9 @@
# include <boost/regex/config.hpp> # include <boost/regex/config.hpp>
#endif #endif
#ifdef BOOST_REGEX_V3
# ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
# include <boost/regex/v3/regex_traits.hpp>
# endif
#else
# ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED # ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
# include <boost/regex/v4/regex_traits.hpp> # include <boost/regex/v4/regex_traits.hpp>
# endif # endif
#endif
#endif // include #endif // include

View File

@ -272,7 +272,10 @@ public:
{ {
typedef typename traits::string_type seq_type; typedef typename traits::string_type seq_type;
seq_type a(arg_first, arg_last); seq_type a(arg_first, arg_last);
assign(&*a.begin(), &*a.begin() + a.size(), f); if(a.size())
assign(&*a.begin(), &*a.begin() + a.size(), f);
else
assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
} }
template <class ST, class SA> template <class ST, class SA>
@ -296,9 +299,13 @@ public:
{ {
typedef typename traits::string_type seq_type; typedef typename traits::string_type seq_type;
seq_type a(arg_first, arg_last); seq_type a(arg_first, arg_last);
const charT* p1 = &*a.begin(); if(a.size())
const charT* p2 = &*a.begin() + a.size(); {
return assign(p1, p2, f); const charT* p1 = &*a.begin();
const charT* p2 = &*a.begin() + a.size();
return assign(p1, p2, f);
}
return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
} }
#else #else
unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal) unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)

View File

@ -762,6 +762,7 @@ void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
state = p.second; state = p.second;
v.pop_back(); v.pop_back();
// Build maps:
create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take); create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take);
m_bad_repeats = 0; m_bad_repeats = 0;
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); 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);
@ -806,14 +807,40 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
case syntax_element_set: case syntax_element_set:
result += 1; result += 1;
break; break;
case syntax_element_backref:
case syntax_element_rep:
case syntax_element_combining:
case syntax_element_dot_rep: case syntax_element_dot_rep:
case syntax_element_char_rep: case syntax_element_char_rep:
case syntax_element_short_set_rep: case syntax_element_short_set_rep:
case syntax_element_backref:
case syntax_element_rep:
case syntax_element_combining:
case syntax_element_long_set_rep: case syntax_element_long_set_rep:
case syntax_element_backstep: case syntax_element_backstep:
{
re_repeat* rep = static_cast<re_repeat *>(state);
// adjust the type of the state to allow for faster matching:
state->type = this->get_repeat_type(state);
if((state->type == syntax_element_dot_rep)
|| (state->type == syntax_element_char_rep)
|| (state->type == syntax_element_short_set_rep))
{
if(rep->max != rep->min)
return -1;
result += static_cast<int>(rep->min);
state = rep->alt.p;
continue;
}
else if((state->type == syntax_element_long_set_rep))
{
BOOST_ASSERT(rep->next.p->type == syntax_element_long_set);
if(static_cast<re_set_long<mask_type>*>(rep->next.p)->singleton == 0)
return -1;
if(rep->max != rep->min)
return -1;
result += static_cast<int>(rep->min);
state = rep->alt.p;
continue;
}
}
return -1; return -1;
case syntax_element_long_set: case syntax_element_long_set:
if(static_cast<re_set_long<mask_type>*>(state)->singleton == 0) if(static_cast<re_set_long<mask_type>*>(state)->singleton == 0)
@ -1027,7 +1054,7 @@ void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state,
return; return;
case syntax_element_endmark: case syntax_element_endmark:
// need to handle independent subs as a special case: // need to handle independent subs as a special case:
if(static_cast<re_brace*>(state)->index == -3) if(static_cast<re_brace*>(state)->index < 0)
{ {
// can be null, any character can match: // can be null, any character can match:
set_all_masks(l_map, mask); set_all_masks(l_map, mask);

View File

@ -1729,6 +1729,8 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
// lets assume that we have a (?imsx) group and try and parse it: // lets assume that we have a (?imsx) group and try and parse it:
// //
regex_constants::syntax_option_type opts = parse_options(); regex_constants::syntax_option_type opts = parse_options();
if(m_position == m_end)
return false;
// make a note of whether we have a case change: // make a note of whether we have a case change:
m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase)); m_has_case_change = ((opts & regbase::icase) != (this->flags() & regbase::icase));
pb->index = markid = 0; pb->index = markid = 0;

View File

@ -816,7 +816,7 @@ bool cpp_regex_traits_implementation<charT>::isctype(const charT c, char_class_t
template <class charT> template <class charT>
boost::shared_ptr<cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT)) inline boost::shared_ptr<cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(charT))
{ {
cpp_regex_traits_base<charT> key(l); cpp_regex_traits_base<charT> key(l);
return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5); return ::boost::object_cache<cpp_regex_traits_base<charT>, cpp_regex_traits_implementation<charT> >::get(key, 5);

View File

@ -33,6 +33,10 @@ namespace boost{
# error "BOOST_REGEX_CHAR_T not defined" # error "BOOST_REGEX_CHAR_T not defined"
#endif #endif
#ifndef BOOST_REGEX_TRAITS_T
# define BOOST_REGEX_TRAITS_T , boost::regex_traits<BOOST_REGEX_CHAR_T >
#endif
// //
// what follows is compiler specific: // what follows is compiler specific:
// //
@ -47,7 +51,11 @@ namespace boost{
# pragma option push -Jgx # pragma option push -Jgx
# endif # endif
template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >; template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >;
template class BOOST_REGEX_DECL match_results< const BOOST_REGEX_CHAR_T* >;
#ifndef BOOST_NO_STD_ALLOCATOR
template class BOOST_REGEX_DECL ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >;
#endif
# ifndef BOOST_REGEX_INSTANTIATE # ifndef BOOST_REGEX_INSTANTIATE
# pragma option pop # pragma option pop
@ -72,16 +80,18 @@ template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >;
# pragma warning(disable : 4251 4231 4660) # pragma warning(disable : 4251 4231 4660)
# endif # endif
template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >; template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >;
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template class BOOST_REGEX_DECL match_results< const BOOST_REGEX_CHAR_T* >; template class BOOST_REGEX_DECL match_results< const BOOST_REGEX_CHAR_T* >;
#endif #endif
#ifndef BOOST_NO_STD_ALLOCATOR #ifndef BOOST_NO_STD_ALLOCATOR
template class BOOST_REGEX_DECL ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >; template class BOOST_REGEX_DECL ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >;
#endif #endif
#if !(defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB <= 1))\ #if !(defined(BOOST_DINKUMWARE_STDLIB) && (BOOST_DINKUMWARE_STDLIB <= 1))\
&& !(defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION <= 800))\ && !(defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION <= 800))\
&& !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))\
&& !defined(BOOST_REGEX_ICU_INSTANCES)
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
template class BOOST_REGEX_DECL match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >; template class BOOST_REGEX_DECL match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >;
#endif #endif
@ -105,40 +115,87 @@ template class BOOST_REGEX_DECL ::boost::re_detail::perl_matcher< std::basic_str
# define template __extension__ extern template # define template __extension__ extern template
# endif # endif
template BOOST_REGEX_DECL basic_regex<BOOST_REGEX_CHAR_T>& #if !defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_REGEX_ICU_INSTANCES)
basic_regex<BOOST_REGEX_CHAR_T>::do_assign( namespace re_detail{
template BOOST_REGEX_DECL
std::locale cpp_regex_traits_base<BOOST_REGEX_CHAR_T>::imbue(const std::locale& l);
/*
template BOOST_REGEX_DECL
void cpp_regex_traits_char_layer<BOOST_REGEX_CHAR_T>::init();
template BOOST_REGEX_DECL
typename cpp_regex_traits_char_layer<BOOST_REGEX_CHAR_T>::string_type
cpp_regex_traits_char_layer<BOOST_REGEX_CHAR_T>::get_default_message(regex_constants::syntax_type i);
*/
template BOOST_REGEX_DECL
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::string_type
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::transform_primary(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
template BOOST_REGEX_DECL
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::string_type
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::transform(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
template BOOST_REGEX_DECL
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::string_type
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::lookup_collatename(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
template BOOST_REGEX_DECL
void cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::init();
template BOOST_REGEX_DECL
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::char_class_type
cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::lookup_classname_imp(const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p2) const;
#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET
template BOOST_REGEX_DECL
bool cpp_regex_traits_implementation<BOOST_REGEX_CHAR_T>::isctype(const BOOST_REGEX_CHAR_T c, char_class_type mask) const;
#endif
} // namespace
template BOOST_REGEX_DECL
int cpp_regex_traits<BOOST_REGEX_CHAR_T>::toi(const BOOST_REGEX_CHAR_T*& first, const BOOST_REGEX_CHAR_T* last, int radix)const;
template BOOST_REGEX_DECL
std::string cpp_regex_traits<BOOST_REGEX_CHAR_T>::catalog_name(const std::string& name);
template BOOST_REGEX_DECL
std::string& cpp_regex_traits<BOOST_REGEX_CHAR_T>::get_catalog_name_inst();
template BOOST_REGEX_DECL
std::string cpp_regex_traits<BOOST_REGEX_CHAR_T>::get_catalog_name();
#ifdef BOOST_HAS_THREADS
template BOOST_REGEX_DECL
static_mutex& cpp_regex_traits<BOOST_REGEX_CHAR_T>::get_mutex_inst();
#endif
#endif
template BOOST_REGEX_DECL basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >&
basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >::do_assign(
const BOOST_REGEX_CHAR_T* p1, const BOOST_REGEX_CHAR_T* p1,
const BOOST_REGEX_CHAR_T* p2, const BOOST_REGEX_CHAR_T* p2,
flag_type f); flag_type f);
template BOOST_REGEX_DECL basic_regex<BOOST_REGEX_CHAR_T>::locale_type BOOST_REGEX_CALL template BOOST_REGEX_DECL basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >::locale_type BOOST_REGEX_CALL
basic_regex<BOOST_REGEX_CHAR_T>::imbue(locale_type l); basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >::imbue(locale_type l);
template BOOST_REGEX_DECL void BOOST_REGEX_CALL template BOOST_REGEX_DECL void BOOST_REGEX_CALL
match_results<const BOOST_REGEX_CHAR_T*>::maybe_assign( match_results<const BOOST_REGEX_CHAR_T*>::maybe_assign(
const match_results<const BOOST_REGEX_CHAR_T*>& m); const match_results<const BOOST_REGEX_CHAR_T*>& m);
namespace re_detail{
template BOOST_REGEX_DECL void ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::construct_init( template BOOST_REGEX_DECL void perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >::construct_init(
BOOST_REGEX_CHAR_T const * first, BOOST_REGEX_CHAR_T const * end, BOOST_REGEX_CHAR_T const * first, BOOST_REGEX_CHAR_T const * end,
match_results<BOOST_REGEX_CHAR_T const *>& what, match_results<BOOST_REGEX_CHAR_T const *>& what,
const basic_regex<BOOST_REGEX_CHAR_T>& e, const basic_regex<BOOST_REGEX_CHAR_T BOOST_REGEX_TRAITS_T >& e,
match_flag_type f); match_flag_type f);
template BOOST_REGEX_DECL bool ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::match(); template BOOST_REGEX_DECL bool perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >::match();
template BOOST_REGEX_DECL bool ::boost::re_detail::perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::find(); template BOOST_REGEX_DECL bool perl_matcher<BOOST_REGEX_CHAR_T const *, match_results< const BOOST_REGEX_CHAR_T* >::allocator_type BOOST_REGEX_TRAITS_T >::find();
} // namespace
#if defined(__GLIBCPP__) || defined(__GLIBCXX__) #if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) && !defined(BOOST_REGEX_ICU_INSTANCES)
// std:basic_string<>::const_iterator instances as well: // std:basic_string<>::const_iterator instances as well:
template BOOST_REGEX_DECL void BOOST_REGEX_CALL template BOOST_REGEX_DECL void BOOST_REGEX_CALL
match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>::maybe_assign( match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>::maybe_assign(
const match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>& m); const match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>& m);
template BOOST_REGEX_DECL void ::boost::re_detail::perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::construct_init( namespace re_detail{
template BOOST_REGEX_DECL void perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::construct_init(
std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator first, std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator end, std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator first, std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator end,
match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>& what, match_results<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator>& what,
const basic_regex<BOOST_REGEX_CHAR_T>& e, const basic_regex<BOOST_REGEX_CHAR_T>& e,
match_flag_type f); match_flag_type f);
template BOOST_REGEX_DECL bool ::boost::re_detail::perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::match(); template BOOST_REGEX_DECL bool perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::match();
template BOOST_REGEX_DECL bool ::boost::re_detail::perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::find(); template BOOST_REGEX_DECL bool perl_matcher<std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator, match_results< std::basic_string<BOOST_REGEX_CHAR_T>::const_iterator >::allocator_type, boost::regex_traits<BOOST_REGEX_CHAR_T > >::find();
} // namespace
#endif #endif
# ifdef template # ifdef template

View File

@ -324,7 +324,8 @@ public:
perl_matcher(BidiIterator first, BidiIterator end, perl_matcher(BidiIterator first, BidiIterator end,
match_results<BidiIterator, Allocator>& what, match_results<BidiIterator, Allocator>& what,
const basic_regex<char_type, traits>& e, const basic_regex<char_type, traits>& e,
match_flag_type f); match_flag_type f,
BidiIterator base);
bool match(); bool match();
bool find(); bool find();
@ -409,6 +410,8 @@ private:
BidiIterator restart; BidiIterator restart;
// where the current search started from, acts as base for $` during grep: // where the current search started from, acts as base for $` during grep:
BidiIterator search_base; BidiIterator search_base;
// how far we can go back when matching lookbehind:
BidiIterator backstop;
// the expression being examined: // the expression being examined:
const basic_regex<char_type, traits>& re; const basic_regex<char_type, traits>& re;
// the expression's traits class: // the expression's traits class:

View File

@ -35,9 +35,10 @@ template <class BidiIterator, class Allocator, class traits>
perl_matcher<BidiIterator, Allocator, traits>::perl_matcher(BidiIterator first, BidiIterator end, perl_matcher<BidiIterator, Allocator, traits>::perl_matcher(BidiIterator first, BidiIterator end,
match_results<BidiIterator, Allocator>& what, match_results<BidiIterator, Allocator>& what,
const basic_regex<char_type, traits>& e, const basic_regex<char_type, traits>& e,
match_flag_type f) match_flag_type f,
BidiIterator b)
: m_result(what), base(first), last(end), : m_result(what), base(first), last(end),
position(first), re(e), traits_inst(e.get_traits()), position(first), backstop(b), re(e), traits_inst(e.get_traits()),
m_independent(false), next_count(&rep_obj), rep_obj(&next_count) m_independent(false), next_count(&rep_obj), rep_obj(&next_count)
{ {
construct_init(first, last, what, e, f); construct_init(first, last, what, e, f);
@ -161,7 +162,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
search_base = base; search_base = base;
state_count = 0; state_count = 0;
m_match_flags |= regex_constants::match_all; 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_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last);
m_presult->set_base(base); m_presult->set_base(base);
if(m_match_flags & match_posix) if(m_match_flags & match_posix)
m_result = *m_presult; m_result = *m_presult;
@ -220,8 +221,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
if((m_match_flags & regex_constants::match_init) == 0) if((m_match_flags & regex_constants::match_init) == 0)
{ {
// reset our state machine: // reset our state machine:
position = base; search_base = position = base;
search_base = base;
pstate = re.get_first_state(); pstate = re.get_first_state();
m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last); m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last);
m_presult->set_base(base); m_presult->set_base(base);
@ -242,8 +242,8 @@ bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
} }
// reset $` start: // reset $` start:
m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last); m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), search_base, last);
if(base != search_base) //if((base != search_base) && (base == backstop))
m_match_flags |= match_prev_avail; // m_match_flags |= match_prev_avail;
} }
if(m_match_flags & match_posix) if(m_match_flags & match_posix)
{ {
@ -346,7 +346,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_literal()
template <class BidiIterator, class Allocator, class traits> template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line() bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
{ {
if(position == base) if(position == backstop)
{ {
if((m_match_flags & match_prev_avail) == 0) if((m_match_flags & match_prev_avail) == 0)
{ {
@ -390,7 +390,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
// we're not yet at the end so *first is always valid: // we're not yet at the end so *first is always valid:
if(is_separator(*position)) if(is_separator(*position))
{ {
if((position != base) || (m_match_flags & match_prev_avail)) if((position != backstop) || (m_match_flags & match_prev_avail))
{ {
// check that we're not in the middle of \r\n sequence // check that we're not in the middle of \r\n sequence
BidiIterator t(position); BidiIterator t(position);
@ -472,7 +472,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
{ {
b = (m_match_flags & match_not_eow) ? true : false; b = (m_match_flags & match_not_eow) ? true : false;
} }
if((position == base) && ((m_match_flags & match_prev_avail) == 0)) if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
{ {
if(m_match_flags & match_not_bow) if(m_match_flags & match_not_bow)
b ^= true; b ^= true;
@ -502,7 +502,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
if(traits_inst.isctype(*position, m_word_mask)) if(traits_inst.isctype(*position, m_word_mask))
{ {
bool b; bool b;
if((position == base) && ((m_match_flags & match_prev_avail) == 0)) if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
return false; return false;
else else
{ {
@ -526,7 +526,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
return false; // can't be starting a word if we're already at the end of input return false; // can't be starting a word if we're already at the end of input
if(!traits_inst.isctype(*position, m_word_mask)) if(!traits_inst.isctype(*position, m_word_mask))
return false; // next character isn't a word character return false; // next character isn't a word character
if((position == base) && ((m_match_flags & match_prev_avail) == 0)) if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
{ {
if(m_match_flags & match_not_bow) if(m_match_flags & match_not_bow)
return false; // no previous input return false; // no previous input
@ -547,7 +547,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
template <class BidiIterator, class Allocator, class traits> template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end() bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
{ {
if((position == base) && ((m_match_flags & match_prev_avail) == 0)) if((position == backstop) && ((m_match_flags & match_prev_avail) == 0))
return false; // start of buffer can't be end of word return false; // start of buffer can't be end of word
BidiIterator t(position); BidiIterator t(position);
--t; --t;
@ -572,7 +572,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
template <class BidiIterator, class Allocator, class traits> template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start() bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()
{ {
if((position != base) || (m_match_flags & match_not_bob)) if((position != backstop) || (m_match_flags & match_not_bob))
return false; return false;
// OK match: // OK match:
pstate = pstate->next.p; pstate = pstate->next.p;
@ -685,7 +685,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
template <class BidiIterator, class Allocator, class traits> template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep() bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()
{ {
std::ptrdiff_t maxlen = ::boost::re_detail::distance(search_base, position); std::ptrdiff_t maxlen = ::boost::re_detail::distance(backstop, position);
if(maxlen < static_cast<const re_brace*>(pstate)->index) if(maxlen < static_cast<const re_brace*>(pstate)->index)
return false; return false;
std::advance(position, -static_cast<const re_brace*>(pstate)->index); std::advance(position, -static_cast<const re_brace*>(pstate)->index);

View File

@ -43,7 +43,7 @@ inline unsigned int regex_grep(Predicate foo,
typedef typename match_results<BidiIterator>::allocator_type match_allocator_type; typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;
match_results<BidiIterator> m; match_results<BidiIterator> m;
re_detail::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags); re_detail::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags, first);
unsigned int count = 0; unsigned int count = 0;
while(matcher.find()) while(matcher.find())
{ {

View File

@ -57,15 +57,15 @@ public:
{ return what; } { return what; }
bool next() bool next()
{ {
if(what.prefix().first != what[0].second) //if(what.prefix().first != what[0].second)
flags |= match_prev_avail; // flags |= match_prev_avail;
BidirectionalIterator next_start = what[0].second; BidirectionalIterator next_start = what[0].second;
match_flag_type f(flags); match_flag_type f(flags);
if(!what.length()) if(!what.length())
f |= regex_constants::match_not_initial_null; f |= regex_constants::match_not_initial_null;
if(base != next_start) //if(base != next_start)
f |= regex_constants::match_not_bob; // f |= regex_constants::match_not_bob;
bool result = regex_search(next_start, end, what, re, f); bool result = regex_search(next_start, end, what, re, f, base);
if(result) if(result)
what.set_base(base); what.set_base(base);
return result; return result;

View File

@ -39,7 +39,7 @@ bool regex_match(BidiIterator first, BidiIterator last,
const basic_regex<charT, traits>& e, const basic_regex<charT, traits>& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{ {
re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags); re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, first);
return matcher.match(); return matcher.match();
} }
template <class iterator, class charT, class traits> template <class iterator, class charT, class traits>

View File

@ -31,11 +31,21 @@ bool regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m, match_results<BidiIterator, Allocator>& m,
const basic_regex<charT, traits>& e, const basic_regex<charT, traits>& e,
match_flag_type flags = match_default) match_flag_type flags = match_default)
{
return regex_search(first, last, m, e, flags, first);
}
template <class BidiIterator, class Allocator, class charT, class traits>
bool regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m,
const basic_regex<charT, traits>& e,
match_flag_type flags,
BidiIterator base)
{ {
if(e.flags() & regex_constants::failbit) if(e.flags() & regex_constants::failbit)
return false; return false;
re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags); re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags, base);
return matcher.find(); return matcher.find();
} }
@ -124,7 +134,7 @@ bool regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator> m; match_results<BidiIterator> m;
typedef typename match_results<BidiIterator>::allocator_type match_alloc_type; typedef typename match_results<BidiIterator>::allocator_type match_alloc_type;
re_detail::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags | regex_constants::match_any); re_detail::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags | regex_constants::match_any, first);
return matcher.find(); return matcher.find();
} }

View File

@ -53,6 +53,7 @@ class regex_token_iterator_implementation
typedef sub_match<BidirectionalIterator> value_type; typedef sub_match<BidirectionalIterator> value_type;
match_results<BidirectionalIterator> what; // current match match_results<BidirectionalIterator> what; // current match
BidirectionalIterator base; // start of search area
BidirectionalIterator end; // end of search area BidirectionalIterator end; // end of search area
const regex_type re; // the expression const regex_type re; // the expression
match_flag_type flags; // match flags match_flag_type flags; // match flags
@ -97,7 +98,8 @@ public:
bool init(BidirectionalIterator first) bool init(BidirectionalIterator first)
{ {
N = 0; N = 0;
if(regex_search(first, end, what, re, flags) == true) base = first;
if(regex_search(first, end, what, re, flags, base) == true)
{ {
N = 0; N = 0;
result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]); result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
@ -134,10 +136,10 @@ public:
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]); result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
return true; return true;
} }
if(what.prefix().first != what[0].second) //if(what.prefix().first != what[0].second)
flags |= match_prev_avail | regex_constants::match_not_bob; // flags |= /*match_prev_avail |*/ regex_constants::match_not_bob;
BidirectionalIterator last_end(what[0].second); BidirectionalIterator last_end(what[0].second);
if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags))) if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
{ {
N =0; N =0;
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]); result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);

View File

@ -42,7 +42,7 @@ public:
bool init(BidirectionalIterator first) bool init(BidirectionalIterator first)
{ {
base = first; base = first;
return u32regex_search(first, end, what, re, flags); return u32regex_search(first, end, what, re, flags, base);
} }
bool compare(const u32regex_iterator_implementation& that) bool compare(const u32regex_iterator_implementation& that)
{ {
@ -53,15 +53,15 @@ public:
{ return what; } { return what; }
bool next() bool next()
{ {
if(what.prefix().first != what[0].second) //if(what.prefix().first != what[0].second)
flags |= match_prev_avail; // flags |= match_prev_avail;
BidirectionalIterator next_start = what[0].second; BidirectionalIterator next_start = what[0].second;
match_flag_type f(flags); match_flag_type f(flags);
if(!what.length()) if(!what.length())
f |= regex_constants::match_not_initial_null; f |= regex_constants::match_not_initial_null;
if(base != next_start) //if(base != next_start)
f |= regex_constants::match_not_bob; // f |= regex_constants::match_not_bob;
bool result = u32regex_search(next_start, end, what, re, f); bool result = u32regex_search(next_start, end, what, re, f, base);
if(result) if(result)
what.set_base(base); what.set_base(base);
return result; return result;

View File

@ -50,7 +50,8 @@ class u32regex_token_iterator_implementation
match_results<BidirectionalIterator> what; // current match match_results<BidirectionalIterator> what; // current match
BidirectionalIterator end; // end of search area BidirectionalIterator end; // end of search area
const regex_type re; // the expression BidirectionalIterator base; // start of search area
const regex_type re; // the expression
match_flag_type flags; // match flags match_flag_type flags; // match flags
value_type result; // the current string result value_type result; // the current string result
int N; // the current sub-expression being enumerated int N; // the current sub-expression being enumerated
@ -93,8 +94,9 @@ public:
bool init(BidirectionalIterator first) bool init(BidirectionalIterator first)
{ {
base = first;
N = 0; N = 0;
if(u32regex_search(first, end, what, re, flags) == true) if(u32regex_search(first, end, what, re, flags, base) == true)
{ {
N = 0; N = 0;
result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]); result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
@ -131,10 +133,10 @@ public:
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]); result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);
return true; return true;
} }
if(what.prefix().first != what[0].second) //if(what.prefix().first != what[0].second)
flags |= match_prev_avail | regex_constants::match_not_bob; // flags |= match_prev_avail | regex_constants::match_not_bob;
BidirectionalIterator last_end(what[0].second); BidirectionalIterator last_end(what[0].second);
if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags))) if(u32regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags), base))
{ {
N =0; N =0;
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]); result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);

View File

@ -19,6 +19,7 @@
#include <boost/regex/config.hpp> #include <boost/regex/config.hpp>
#ifdef BOOST_HAS_ICU #ifdef BOOST_HAS_ICU
#define BOOST_REGEX_ICU_INSTANTIATE
#include <boost/regex/icu.hpp> #include <boost/regex/icu.hpp>
namespace boost{ namespace boost{
@ -38,11 +39,18 @@ icu_regex_traits_implementation::string_type icu_regex_traits_implementation::do
t.push_back(*i++); t.push_back(*i++);
#endif #endif
::uint8_t result[100]; ::uint8_t result[100];
::int32_t len = pcoll->getSortKey(&*t.begin(), static_cast< ::int32_t>(t.size()), result, sizeof(result)); ::int32_t len;
if(t.size())
len = pcoll->getSortKey(&*t.begin(), static_cast< ::int32_t>(t.size()), result, sizeof(result));
else
len = pcoll->getSortKey(static_cast<UChar const*>(0), static_cast< ::int32_t>(0), result, sizeof(result));
if(std::size_t(len) > sizeof(result)) if(std::size_t(len) > sizeof(result))
{ {
scoped_array< ::uint8_t> presult(new ::uint8_t[len+1]); scoped_array< ::uint8_t> presult(new ::uint8_t[len+1]);
len = pcoll->getSortKey(&*t.begin(), static_cast< ::int32_t>(t.size()), presult.get(), len+1); if(t.size())
len = pcoll->getSortKey(&*t.begin(), static_cast< ::int32_t>(t.size()), presult.get(), len+1);
else
len = pcoll->getSortKey(static_cast<UChar const*>(0), static_cast< ::int32_t>(0), presult.get(), len+1);
if((0 == presult[len-1]) && (len > 1)) if((0 == presult[len-1]) && (len > 1))
--len; --len;
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS
@ -398,10 +406,12 @@ icu_regex_traits::char_class_type icu_regex_traits::lookup_classname(const char_
++i; ++i;
} }
} }
id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); if(s.size())
id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
if(id >= 0) if(id >= 0)
return masks[id+1]; return masks[id+1];
result = lookup_icu_mask(&*s.begin(), &*s.begin() + s.size()); if(s.size())
result = lookup_icu_mask(&*s.begin(), &*s.begin() + s.size());
if(result != 0) if(result != 0)
return result; return result;
} }

View File

@ -41,13 +41,16 @@ void test_forward_lookahead_asserts()
TEST_REGEX_SEARCH("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", perl, "abC3", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", perl, "abC3", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", perl, "ABCD3", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", perl, "ABCD3", match_default, make_array(-2, -2));
// bug report test cases:
TEST_REGEX_SEARCH("(?=.{1,10}$).*.", perl, "AAAAA", match_default, make_array(0, 5, -2, -2));
// lookbehind assertions, added 2004-04-30 // lookbehind assertions, added 2004-04-30
TEST_REGEX_SEARCH("/\\*.*(?<=\\*)/", perl, "/**/", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("/\\*.*(?<=\\*)/", perl, "/**/", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("/\\*.*(?<=\\*)/", perl, "/*****/ ", match_default, make_array(0, 7, -2, -2)); TEST_REGEX_SEARCH("/\\*.*(?<=\\*)/", perl, "/*****/ ", match_default, make_array(0, 7, -2, -2));
TEST_REGEX_SEARCH("(?<=['\"]).*?(?=['\"])", perl, " 'ac' ", match_default, make_array(2, 4, -2, -2)); TEST_REGEX_SEARCH("(?<=['\"]).*?(?=['\"])", perl, " 'ac' ", match_default, make_array(2, 4, -2, -2));
TEST_REGEX_SEARCH("(?<=['\"]).*?(?=['\"])", perl, " \"ac\" ", match_default, make_array(2, 4, -2, -2)); TEST_REGEX_SEARCH("(?<=['\"]).*?(?=['\"])", perl, " \"ac\" ", match_default, make_array(2, 4, -2, -2));
TEST_REGEX_SEARCH("(?<=['\"]).*?(?<!\\\\)(?=['\"])", perl, " \"ac\" ", match_default, make_array(2, 4, -2, -2)); TEST_REGEX_SEARCH("(?<=['\"]).*?(?<!\\\\)(?=['\"])", perl, " \"ac\" ", match_default, make_array(2, 4, -2, -2));
TEST_REGEX_SEARCH("(?<=['\"]).*?(?<!\\\\)(?=['\"])", perl, " \"ac\\\"\" ", match_default, make_array(2, 6, -2, -2)); TEST_REGEX_SEARCH("(?<=['\"]).*?(?<!\\\\)(?=['\"])", perl, " \"ac\\\" \" ", match_default, make_array(2, 7, -2, -2));
// lookbehind, with nested lookahead! : // lookbehind, with nested lookahead! :
TEST_REGEX_SEARCH("/\\*.*(?<=(?=[[:punct:]])\\*)/", perl, "/**/", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("/\\*.*(?<=(?=[[:punct:]])\\*)/", perl, "/**/", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("/\\*.*(?<=(?![[:alnum:]])\\*)/", perl, "/**/", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("/\\*.*(?<=(?![[:alnum:]])\\*)/", perl, "/**/", match_default, make_array(0, 4, -2, -2));

View File

@ -15,6 +15,8 @@
#pragma warning(disable:4127) #pragma warning(disable:4127)
#endif #endif
void test_emacs2();
void test_emacs() void test_emacs()
{ {
using namespace boost::regex_constants; using namespace boost::regex_constants;
@ -132,6 +134,13 @@ void test_emacs()
TEST_REGEX_SEARCH("a+\\(?#b+\\)b+", emacs, "xaaabbba", match_default, make_array(1, 7, -2, -2)); TEST_REGEX_SEARCH("a+\\(?#b+\\)b+", emacs, "xaaabbba", match_default, make_array(1, 7, -2, -2));
TEST_REGEX_SEARCH("\\(a\\)\\(?:b\\|$\\)", emacs, "ab", match_default, make_array(0, 2, 0, 1, -2, -2)); TEST_REGEX_SEARCH("\\(a\\)\\(?:b\\|$\\)", emacs, "ab", match_default, make_array(0, 2, 0, 1, -2, -2));
TEST_REGEX_SEARCH("\\(a\\)\\(?:b\\|$\\)", emacs, "a", match_default, make_array(0, 1, 0, 1, -2, -2)); TEST_REGEX_SEARCH("\\(a\\)\\(?:b\\|$\\)", emacs, "a", match_default, make_array(0, 1, 0, 1, -2, -2));
test_emacs2();
}
void test_emacs2()
{
using namespace boost::regex_constants;
TEST_REGEX_SEARCH("\\ss+", emacs, "a b", match_default, make_array(1, 3, -2, -2)); TEST_REGEX_SEARCH("\\ss+", emacs, "a b", match_default, make_array(1, 3, -2, -2));
TEST_REGEX_SEARCH("\\Ss+", emacs, " ab ", match_default, make_array(1, 3, -2, -2)); TEST_REGEX_SEARCH("\\Ss+", emacs, " ab ", match_default, make_array(1, 3, -2, -2));

View File

@ -53,5 +53,15 @@ void test_grep()
TEST_REGEX_SEARCH("a|\\Ab", perl, "b ab", match_default, make_array(0, 1, -2, 2, 3, -2, -2)); TEST_REGEX_SEARCH("a|\\Ab", perl, "b ab", match_default, make_array(0, 1, -2, 2, 3, -2, -2));
TEST_REGEX_SEARCH("a|^b", perl, "b ab\nb", match_default, make_array(0, 1, -2, 2, 3, -2, 5, 6, -2, -2)); TEST_REGEX_SEARCH("a|^b", perl, "b ab\nb", match_default, make_array(0, 1, -2, 2, 3, -2, 5, 6, -2, -2));
TEST_REGEX_SEARCH("a|\\<b", perl, "b ab\nb", match_default, make_array(0, 1, -2, 2, 3, -2, 5, 6, -2, -2)); TEST_REGEX_SEARCH("a|\\<b", perl, "b ab\nb", match_default, make_array(0, 1, -2, 2, 3, -2, 5, 6, -2, -2));
TEST_REGEX_SEARCH("\\Aabc", perl, "abcabc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("^abc", perl, "abcabc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("\\<abc", perl, "abcabc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("\\babc", perl, "abcabc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("(?<=\\Aabc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2));
TEST_REGEX_SEARCH("(?<=^abc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2));
TEST_REGEX_SEARCH("(?<=\\<abc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2));
TEST_REGEX_SEARCH("(?<=\\babc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2));
TEST_REGEX_SEARCH("(?<=^).{2}|(?<=^.{3}).{2}", perl, "123456789", match_default, make_array(0, 2, -2, 3, 5, -2, -2));
} }

View File

@ -209,7 +209,10 @@ void test_icu(const wchar_t&, const test_regex_search_tag& )
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
r.assign(expression.begin(), expression.end(), syntax_options); r.assign(expression.begin(), expression.end(), syntax_options);
#else #else
r.assign(&*expression.begin(), expression.size(), syntax_options); if(expression.size())
r.assign(&*expression.begin(), expression.size(), syntax_options);
else
r.assign(static_cast<UChar32 const*>(0), expression.size(), syntax_options);
#endif #endif
if(r.status()) if(r.status())
{ {
@ -379,7 +382,11 @@ void test_icu(const wchar_t&, const test_invalid_regex_tag&)
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
if(0 == r.assign(expression.begin(), expression.end(), syntax_options | boost::regex_constants::no_except).status()) if(0 == r.assign(expression.begin(), expression.end(), syntax_options | boost::regex_constants::no_except).status())
#else #else
if(0 == r.assign(&*expression.begin(), expression.size(), syntax_options | boost::regex_constants::no_except).status()) if(expression.size())
r.assign(&*expression.begin(), expression.size(), syntax_options | boost::regex_constants::no_except);
else
r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options | boost::regex_constants::no_except);
if(0 == r.status())
#endif #endif
{ {
BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t); BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t);
@ -397,7 +404,10 @@ void test_icu(const wchar_t&, const test_invalid_regex_tag&)
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
r.assign(expression.begin(), expression.end(), syntax_options); r.assign(expression.begin(), expression.end(), syntax_options);
#else #else
r.assign(&*expression.begin(), expression.size(), syntax_options); if(expression.size())
r.assign(&*expression.begin(), expression.size(), syntax_options);
else
r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options);
#endif #endif
#ifdef BOOST_NO_EXCEPTIONS #ifdef BOOST_NO_EXCEPTIONS
if(r.status()) if(r.status())
@ -492,7 +502,10 @@ void test_icu(const wchar_t&, const test_regex_replace_tag&)
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) #if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
r.assign(expression.begin(), expression.end(), syntax_options); r.assign(expression.begin(), expression.end(), syntax_options);
#else #else
r.assign(&*expression.begin(), expression.size(), syntax_options); if(expression.size())
r.assign(&*expression.begin(), expression.size(), syntax_options);
else
r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options);
#endif #endif
if(r.status()) if(r.status())
{ {
@ -552,10 +565,13 @@ void test_icu(const wchar_t&, const test_regex_replace_tag&)
// Now with UnicodeString: // Now with UnicodeString:
// //
UnicodeString expression16u, text16u, format16u, result16u, found16u; UnicodeString expression16u, text16u, format16u, result16u, found16u;
expression16u.setTo(&*expression16.begin(), expression16.size()); if(expression16.size())
text16u.setTo(&*text16.begin(), text16.size()); expression16u.setTo(&*expression16.begin(), expression16.size());
if(text16.size())
text16u.setTo(&*text16.begin(), text16.size());
format16u.setTo(&*format16.begin(), format16.size()-1); format16u.setTo(&*format16.begin(), format16.size()-1);
result16u.setTo(&*result16.begin(), result16.size()); if(result16.size())
result16u.setTo(&*result16.begin(), result16.size());
r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options); r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options);
found16u = boost::u32regex_replace(text16u, r, format16u, opts); found16u = boost::u32regex_replace(text16u, r, format16u, opts);
if(result16u != found16u) if(result16u != found16u)
@ -589,10 +605,13 @@ void test_icu(const wchar_t&, const test_regex_replace_tag&)
// Now with std::string and UTF-8: // Now with std::string and UTF-8:
// //
std::string expression8s, text8s, format8s, result8s, found8s; std::string expression8s, text8s, format8s, result8s, found8s;
expression8s.assign(&*expression8.begin(), expression8.size()); if(expression8.size())
text8s.assign(&*text8.begin(), text8.size()); expression8s.assign(&*expression8.begin(), expression8.size());
if(text8.size())
text8s.assign(&*text8.begin(), text8.size());
format8s.assign(&*format8.begin(), format8.size()-1); format8s.assign(&*format8.begin(), format8.size()-1);
result8s.assign(&*result8.begin(), result8.size()); if(result8.size())
result8s.assign(&*result8.begin(), result8.size());
r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options); r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options);
found8s = boost::u32regex_replace(text8s, r, format8s, opts); found8s = boost::u32regex_replace(text8s, r, format8s, opts);
if(result8s != found8s) if(result8s != found8s)

View File

@ -15,6 +15,8 @@
#pragma warning(disable:4127) #pragma warning(disable:4127)
#endif #endif
void test_options3();
void test_independent_subs() void test_independent_subs()
{ {
using namespace boost::regex_constants; using namespace boost::regex_constants;
@ -258,6 +260,13 @@ void test_options2()
TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "ABxxc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "ABxxc", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "abxxC", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "abxxC", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?<=^.{4})(?:bar|cat)", perl, "fooocat", match_default, make_array(4, 7, -2, -2));
TEST_REGEX_SEARCH("(?<=^.{4})(?:bar|cat)", perl, "foocat", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?<=^a{4})(?:bar|cat)", perl, "aaaacat", match_default, make_array(4, 7, -2, -2));
TEST_REGEX_SEARCH("(?<=^a{4})(?:bar|cat)", perl, "aaacat", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?<=^[[:alpha:]]{4})(?:bar|cat)", perl, "aaaacat", match_default, make_array(4, 7, -2, -2));
TEST_REGEX_SEARCH("(?<=^[[:alpha:]]{4})(?:bar|cat)", perl, "aaacat", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "abxyZZ", match_default, make_array(4, 6, -2, -2)); TEST_REGEX_SEARCH("(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "abxyZZ", match_default, make_array(4, 6, -2, -2));
TEST_REGEX_SEARCH("(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "abXyZZ", match_default, make_array(4, 6, -2, -2)); TEST_REGEX_SEARCH("(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "abXyZZ", match_default, make_array(4, 6, -2, -2));
TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "ZZZ", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "ZZZ", match_default, make_array(0, 3, -2, -2));
@ -315,6 +324,12 @@ void test_options2()
TEST_REGEX_SEARCH("(?s).", perl, "\n", match_default|match_not_dot_newline, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("(?s).", perl, "\n", match_default|match_not_dot_newline, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("(?-s).", perl, "\n", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(?-s).", perl, "\n", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?-s).", perl, "\n", match_default|match_not_dot_newline, make_array(-2, -2)); TEST_REGEX_SEARCH("(?-s).", perl, "\n", match_default|match_not_dot_newline, make_array(-2, -2));
test_options3();
}
void test_options3()
{
using namespace boost::regex_constants;
TEST_REGEX_SEARCH(".+", perl, " \n ", match_default, make_array(0, 5, -2, -2)); TEST_REGEX_SEARCH(".+", perl, " \n ", match_default, make_array(0, 5, -2, -2));
TEST_REGEX_SEARCH(".+", perl, " \n ", match_default|match_not_dot_newline, make_array(0, 2, -2, 3, 5, -2, -2)); TEST_REGEX_SEARCH(".+", perl, " \n ", match_default|match_not_dot_newline, make_array(0, 2, -2, 3, 5, -2, -2));

View File

@ -15,6 +15,8 @@
#pragma warning(disable:4127) #pragma warning(disable:4127)
#endif #endif
void test_simple_repeats2();
void test_simple_repeats() void test_simple_repeats()
{ {
using namespace boost::regex_constants; using namespace boost::regex_constants;
@ -111,6 +113,11 @@ void test_simple_repeats()
TEST_REGEX_SEARCH("^a{0,1}?$", perl, "aaaaa", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("^a{0,1}?$", perl, "aaaaa", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("^(?:a){0,1}?$", perl, "aaaaa", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("^(?:a){0,1}?$", perl, "aaaaa", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("^a(?:bc)?", perl, "abcbc", match_any|match_all, make_array(-2, -2)); TEST_REGEX_SEARCH("^a(?:bc)?", perl, "abcbc", match_any|match_all, make_array(-2, -2));
}
void test_simple_repeats2()
{
using namespace boost::regex_constants;
TEST_INVALID_REGEX("a{}", perl); TEST_INVALID_REGEX("a{}", perl);
TEST_INVALID_REGEX("a{", perl); TEST_INVALID_REGEX("a{", perl);