Almost complete compiler compatibility now...

[SVN r23103]
This commit is contained in:
John Maddock
2004-06-15 11:43:12 +00:00
parent 1d5a14164a
commit 89f635376a
25 changed files with 298 additions and 108 deletions

View File

@ -33,13 +33,6 @@ using namespace std;
#ifndef BOOST_REGEX_NO_FILEITER #ifndef BOOST_REGEX_NO_FILEITER
#include <algorithm> #include <algorithm>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{
using ::strcpy; using ::strcat;
using ::sprintf;
}
#endif
re_type e; re_type e;
// flags for output: // flags for output:
@ -170,18 +163,18 @@ void HandleFile(const char* wild)
{ {
// go through sub directories: // go through sub directories:
char buf[MAX_PATH]; char buf[MAX_PATH];
std::strcpy(buf, start.root()); strcpy(buf, start.root());
int rootlen = strlen(buf); int rootlen = strlen(buf);
if(*buf == 0) if(*buf == 0)
{ {
std::strcpy(buf, "."); strcpy(buf, ".");
std::strcat(buf, directory_iterator::separator()); strcat(buf, directory_iterator::separator());
std::strcat(buf, "*"); strcat(buf, "*");
} }
else else
{ {
std::strcat(buf, directory_iterator::separator()); strcat(buf, directory_iterator::separator());
std::strcat(buf, "*"); strcat(buf, "*");
} }
directory_iterator dstart(buf); directory_iterator dstart(buf);
directory_iterator dend; directory_iterator dend;
@ -192,12 +185,12 @@ void HandleFile(const char* wild)
while(dstart != dend) while(dstart != dend)
{ {
std::sprintf(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); sprintf(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr);
HandleFile(buf); HandleFile(buf);
++dstart; ++dstart;
} }
} }
std::for_each(start, end, process_grep); for_each(start, end, process_grep);
} }
int done = 0; int done = 0;
@ -222,8 +215,8 @@ void HandleArg(const char* arg)
} }
else else
{ {
char* buf = new char[std::strlen(arg) + 8]; char* buf = new char[strlen(arg) + 8];
std::sprintf(buf, "\\<%s\\>", arg); sprintf(buf, "\\<%s\\>", arg);
e.set_expression(buf, use_case ? regex::normal : regbase::normal | regbase::icase); e.set_expression(buf, use_case ? regex::normal : regbase::normal | regbase::icase);
//ei.set_expression(buf); //ei.set_expression(buf);
delete[] buf; delete[] buf;
@ -232,20 +225,20 @@ void HandleArg(const char* arg)
else else
{ {
// we need to convert text to literal: // we need to convert text to literal:
int len2 = std::strlen(arg); int len2 = strlen(arg);
int len = len2 * 5 + 6; int len = len2 * 5 + 6;
char buf[8]; char buf[8];
char* buf2 = new char[len]; char* buf2 = new char[len];
*buf2 = 0; *buf2 = 0;
if(words_only) if(words_only)
std::strcpy(buf2, "\\<"); strcpy(buf2, "\\<");
for(int j = 0; j < len2; ++j) for(int j = 0; j < len2; ++j)
{ {
std::sprintf(buf, "\\0%o", int(arg[j])); sprintf(buf, "\\0%o", int(arg[j]));
std::strcat(buf2, buf); strcat(buf2, buf);
} }
if(words_only) if(words_only)
std::strcat(buf2, "\\>"); strcat(buf2, "\\>");
e.set_expression(buf2, use_case ? regex::normal : regbase::normal | regbase::icase); e.set_expression(buf2, use_case ? regex::normal : regbase::normal | regbase::icase);
//ei.set_expression(buf2); //ei.set_expression(buf2);
delete[] buf2; delete[] buf2;
@ -273,7 +266,7 @@ int main(int argc, char * argv[])
int main(int argc, char * argv[]) int main(int argc, char * argv[])
{ {
std::cout << cout <<
"\n<note>\n" "\n<note>\n"
"This functionality is not available on with this compiler on this platform.\n" "This functionality is not available on with this compiler on this platform.\n"
"</note>\n"; "</note>\n";

View File

@ -47,6 +47,7 @@ public:
{ return m_error_code; } { return m_error_code; }
std::ptrdiff_t position()const std::ptrdiff_t position()const
{ return m_position; } { return m_position; }
void raise()const;
private: private:
regex_constants::error_type m_error_code; regex_constants::error_type m_error_code;
std::ptrdiff_t m_position; std::ptrdiff_t m_position;

View File

@ -265,7 +265,7 @@ 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.end(), f); assign(&*a.begin(), &*a.begin() + a.size(), f);
} }
template <class ST, class SA> template <class ST, class SA>
@ -290,7 +290,7 @@ 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(); const charT* p1 = &*a.begin();
const charT* p2 = &*a.end(); const charT* p2 = &*a.begin() + a.size();
return assign(p1, p2, f); return assign(p1, p2, f);
} }
#else #else
@ -453,32 +453,32 @@ public:
// //
const re_detail::re_syntax_base* get_first_state()const const re_detail::re_syntax_base* get_first_state()const
{ {
assert(m_pimpl.get()); assert(0 != m_pimpl.get());
return m_pimpl->get_first_state(); return m_pimpl->get_first_state();
} }
unsigned get_restart_type()const unsigned get_restart_type()const
{ {
assert(m_pimpl.get()); assert(0 != m_pimpl.get());
return m_pimpl->get_restart_type(); return m_pimpl->get_restart_type();
} }
const unsigned char* get_map()const const unsigned char* get_map()const
{ {
assert(m_pimpl.get()); assert(0 != m_pimpl.get());
return m_pimpl->get_map(); return m_pimpl->get_map();
} }
const ::boost::regex_traits_wrapper<traits>& get_traits()const const ::boost::regex_traits_wrapper<traits>& get_traits()const
{ {
assert(m_pimpl.get()); assert(0 != m_pimpl.get());
return m_pimpl->get_traits(); return m_pimpl->get_traits();
} }
bool can_be_null()const bool can_be_null()const
{ {
assert(m_pimpl.get()); assert(0 != m_pimpl.get());
return m_pimpl->can_be_null(); return m_pimpl->can_be_null();
} }
const re_detail::regex_data<charT, traits>& get_data()const const re_detail::regex_data<charT, traits>& get_data()const
{ {
assert(m_pimpl.get()); assert(0 != m_pimpl.get());
return m_pimpl->get_data(); return m_pimpl->get_data();
} }

View File

@ -33,7 +33,8 @@ struct digraph : public std::pair<charT, charT>
{ {
digraph() : std::pair<charT, charT>(0, 0){} digraph() : std::pair<charT, charT>(0, 0){}
digraph(charT c1) : std::pair<charT, charT>(c1, 0){} digraph(charT c1) : std::pair<charT, charT>(c1, 0){}
digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2){} digraph(charT c1, charT c2) : std::pair<charT, charT>(c1, c2)
{}
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){} digraph(const digraph<charT>& d) : std::pair<charT, charT>(d.first, d.second){}
#endif #endif
@ -407,11 +408,13 @@ re_syntax_base* basic_regex_creator<charT, traits>::append_set(
else else
{ {
if(c1.second) if(c1.second)
s1 = string_type(&c1.first, &c1.second+1); {
s1.append(1, c1.first).append(1, c1.second);
}
else else
s1 = string_type(1, c1.first); s1 = string_type(1, c1.first);
if(c2.second) if(c2.second)
s2 = string_type(&c2.first, &c2.second+1); s2.append(1, c2.first).append(1, c2.second);
else else
s2 = string_type(1, c2.first); s2 = string_type(1, c2.first);
} }
@ -548,13 +551,8 @@ re_syntax_base* basic_regex_creator<charT, traits>::append_set(
while(first != last) while(first != last)
{ {
string_type s; string_type s;
if(first->second) BOOST_ASSERT(static_cast<charT>(0) == first->second);
{ s = m_traits.transform_primary(&first->first, &first->first+1);
charT cs[2] = { first->first, first->second, };
s = m_traits.transform_primary(cs, cs+2);
}
else
s = m_traits.transform_primary(&first->first, &first->first+1);
if(s.empty()) if(s.empty())
return 0; // invalid or unsupported equivalence class return 0; // invalid or unsupported equivalence class
for(unsigned i = 0; i < (1u << CHAR_BIT); ++i) for(unsigned i = 0; i < (1u << CHAR_BIT); ++i)
@ -683,6 +681,13 @@ void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
// we need to calculate how big the backstep is: // we need to calculate how big the backstep is:
static_cast<re_brace*>(state)->index static_cast<re_brace*>(state)->index
= this->calculate_backstep(state->next.p); = this->calculate_backstep(state->next.p);
if(static_cast<re_brace*>(state)->index < 0)
{
// Oops error:
std::string message = this->m_pdata->m_ptraits->error_string(boost::regex_constants::error_brack);
boost::regex_error e(message, boost::regex_constants::error_brack, 0);
e.raise();
}
// fall through: // fall through:
default: default:
state = state->next.p; state = state->next.p;
@ -718,6 +723,7 @@ int basic_regex_creator<charT, traits>::calculate_backstep(re_syntax_base* state
if((static_cast<re_brace*>(state)->index == -1) if((static_cast<re_brace*>(state)->index == -1)
|| (static_cast<re_brace*>(state)->index == -2)) || (static_cast<re_brace*>(state)->index == -2))
return result; return result;
break;
case syntax_element_literal: case syntax_element_literal:
result += static_cast<re_literal*>(state)->length; result += static_cast<re_literal*>(state)->length;
break; break;
@ -1037,7 +1043,7 @@ bool basic_regex_creator<charT, traits>::is_bad_repeat(re_syntax_base* pt)
unsigned id = static_cast<re_repeat*>(pt)->id; unsigned id = static_cast<re_repeat*>(pt)->id;
if(id > sizeof(m_bad_repeats) * CHAR_BIT) if(id > sizeof(m_bad_repeats) * CHAR_BIT)
return true; // run out of bits, assume we can't traverse this one. return true; // run out of bits, assume we can't traverse this one.
return m_bad_repeats & (1u << id); return m_bad_repeats & static_cast<boost::uintmax_t>(1uL << id);
} }
default: default:
return false; return false;
@ -1057,7 +1063,7 @@ void basic_regex_creator<charT, traits>::set_bad_repeat(re_syntax_base* pt)
{ {
unsigned id = static_cast<re_repeat*>(pt)->id; unsigned id = static_cast<re_repeat*>(pt)->id;
if(id <= sizeof(m_bad_repeats) * CHAR_BIT) if(id <= sizeof(m_bad_repeats) * CHAR_BIT)
m_bad_repeats |= (1u << id); m_bad_repeats |= static_cast<boost::uintmax_t>(1uL << id);
} }
default: default:
break; break;

View File

@ -121,7 +121,7 @@ void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_c
{ {
std::string message = this->m_pdata->m_ptraits->error_string(error_code); std::string message = this->m_pdata->m_ptraits->error_string(error_code);
boost::regex_error e(message, error_code, position); boost::regex_error e(message, error_code, position);
boost::throw_exception(e); e.raise();
} }
template <class charT, class traits> template <class charT, class traits>
@ -1109,10 +1109,7 @@ charT basic_regex_parser<charT, traits>::unescape_character()
template <class charT, class traits> template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_backref() bool basic_regex_parser<charT, traits>::parse_backref()
{ {
if(m_position == m_end) BOOST_ASSERT(m_position != m_end);
{
fail(regex_constants::error_escape, m_position - m_end);
}
int i = this->m_traits.toi(m_position, m_position + 1, 10); int i = this->m_traits.toi(m_position, m_position + 1, 10);
if((i > 0) && (this->m_backrefs & (1u << (i-1)))) if((i > 0) && (this->m_backrefs & (1u << (i-1))))
{ {

View File

@ -230,7 +230,7 @@ cpp_regex_traits_char_layer<charT>::cpp_regex_traits_char_layer(const std::local
{ {
std::string m("Unable to open message catalog: "); std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name); std::runtime_error err(m + cat_name);
boost::throw_exception(err); boost::re_detail::raise_runtime_error(err);
} }
} }
// //
@ -401,6 +401,24 @@ private:
char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const; char_class_type lookup_classname_imp(const charT* p1, const charT* p2) const;
}; };
#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION)
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_blank;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_word;
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_unicode;
#ifdef __GNUC__
template <class charT>
typename cpp_regex_traits_implementation<charT>::native_mask_type const cpp_regex_traits_implementation<charT>::mask_base;
#else
template <class charT>
typename cpp_regex_traits_implementation<charT>::char_class_type const cpp_regex_traits_implementation<charT>::mask_base;
#endif
#endif
template <class charT> template <class charT>
typename cpp_regex_traits_implementation<charT>::string_type typename cpp_regex_traits_implementation<charT>::string_type
cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const cpp_regex_traits_implementation<charT>::transform_primary(const charT* p1, const charT* p2) const
@ -454,7 +472,7 @@ typename cpp_regex_traits_implementation<charT>::string_type
if(pos != m_custom_collate_names.end()) if(pos != m_custom_collate_names.end())
return pos->second; return pos->second;
} }
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
std::string name(p1, p2); std::string name(p1, p2);
#else #else
std::string name; std::string name;
@ -463,7 +481,7 @@ typename cpp_regex_traits_implementation<charT>::string_type
name.append(1, char(*p0++)); name.append(1, char(*p0++));
#endif #endif
name = lookup_default_collate_name(name); name = lookup_default_collate_name(name);
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
if(name.size()) if(name.size())
return string_type(name.begin(), name.end()); return string_type(name.begin(), name.end());
#else #else
@ -502,7 +520,7 @@ cpp_regex_traits_implementation<charT>::cpp_regex_traits_implementation(const st
{ {
std::string m("Unable to open message catalog: "); std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name); std::runtime_error err(m + cat_name);
boost::throw_exception(err); boost::re_detail::raise_runtime_error(err);
} }
} }
// //

View File

@ -106,7 +106,7 @@ public:
const sub_match<BidiIterator>& s = m_subs[sub]; const sub_match<BidiIterator>& s = m_subs[sub];
if(s.matched) if(s.matched)
{ {
result = s; result = s.str();
} }
} }
return result; return result;

View File

@ -38,7 +38,13 @@ inline void inplace_destroy(T* p)
struct saved_state struct saved_state
{ {
unsigned int id; union{
unsigned int id;
// this padding ensures correct alignment on 64-bit platforms:
std::size_t padding1;
std::ptrdiff_t padding2;
void* padding3;
};
saved_state(unsigned i) : id(i) {} saved_state(unsigned i) : id(i) {}
}; };
@ -629,7 +635,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
if(::boost::is_random_access_iterator<BidiIterator>::value) if(::boost::is_random_access_iterator<BidiIterator>::value)
{ {
BidiIterator end = position; BidiIterator end = position;
std::advance(end, (std::min)((unsigned)::boost::re_detail::distance(position, last), desired)); std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position); BidiIterator origin(position);
while((position != end) && (traits_inst.translate(*position, icase) == what)) while((position != end) && (traits_inst.translate(*position, icase) == what))
{ {
@ -696,7 +702,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
if(::boost::is_random_access_iterator<BidiIterator>::value) if(::boost::is_random_access_iterator<BidiIterator>::value)
{ {
BidiIterator end = position; BidiIterator end = position;
std::advance(end, (std::min)((unsigned)::boost::re_detail::distance(position, last), desired)); std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position); BidiIterator origin(position);
while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))]) while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{ {
@ -764,7 +770,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
if(::boost::is_random_access_iterator<BidiIterator>::value) if(::boost::is_random_access_iterator<BidiIterator>::value)
{ {
BidiIterator end = position; BidiIterator end = position;
std::advance(end, (std::min)((unsigned)::boost::re_detail::distance(position, last), desired)); std::advance(end, (std::min)((std::size_t)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position); BidiIterator origin(position);
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase))) while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
{ {

View File

@ -67,7 +67,8 @@ public:
: end(last), re(*p), flags(f), subs(v){} : end(last), re(*p), flags(f), subs(v){}
#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\ #if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
|| BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
|| BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
|| BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
template <class T> template <class T>
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f) regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
: end(last), re(*p), flags(f) : end(last), re(*p), flags(f)
@ -195,7 +196,8 @@ public:
} }
#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\ #if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
|| BOOST_WORKAROUND(BOOST_MSVC, < 1300) \ || BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
|| BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) || BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003)) \
|| BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
template <class T> template <class T>
regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re,
const T& submatches, match_flag_type m = match_default) const T& submatches, match_flag_type m = match_default)

View File

@ -73,7 +73,7 @@ struct regex_traits : public implementationT
// required "standard" ones: // required "standard" ones:
// //
namespace re_detail{ namespace re_detail{
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
BOOST_MPL_HAS_XXX_TRAIT_DEF(boost_extensions_tag) BOOST_MPL_HAS_XXX_TRAIT_DEF(boost_extensions_tag)
#else #else
template<class T> template<class T>
@ -126,7 +126,7 @@ struct compute_wrapper_base
{ {
typedef BaseT type; typedef BaseT type;
}; };
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION #if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))
template <class BaseT> template <class BaseT>
struct compute_wrapper_base<BaseT, false> struct compute_wrapper_base<BaseT, false>
{ {

View File

@ -83,7 +83,7 @@ inline bool is_combining<wchar_t>(wchar_t c)
{ {
return is_combining_implementation(static_cast<unsigned short>(c)); return is_combining_implementation(static_cast<unsigned short>(c));
} }
#elif defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T) #elif !defined(__DECCXX) && defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX) #if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
template<> template<>
inline bool is_combining<wchar_t>(wchar_t c) inline bool is_combining<wchar_t>(wchar_t c)

View File

@ -46,7 +46,7 @@ struct sub_match : public std::pair<BidiIterator, BidiIterator>
template <class T, class A> template <class T, class A>
operator std::basic_string<value_type, T, A> ()const operator std::basic_string<value_type, T, A> ()const
{ {
return std::basic_string<value_type, T, A>(first, second); return std::basic_string<value_type, T, A>(this->first, this->second);
} }
#else #else
operator std::basic_string<value_type> ()const operator std::basic_string<value_type> ()const

View File

@ -138,6 +138,14 @@ public:
} }
return i->second; return i->second;
} }
charT tolower(charT c)const
{
return ::boost::re_detail::w32_tolower(c, this->m_locale);
}
bool isctype(boost::uint32_t mask, charT c)
{
return ::boost::re_detail::w32_is(this->m_locale, mask, c);
}
private: private:
string_type get_default_message(regex_constants::syntax_type); string_type get_default_message(regex_constants::syntax_type);
@ -160,7 +168,7 @@ w32_regex_traits_char_layer<charT>::w32_regex_traits_char_layer(::boost::re_deta
{ {
std::string m("Unable to open message catalog: "); std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name); std::runtime_error err(m + cat_name);
boost::throw_exception(err); boost::re_detail::raise_runtime_error(err);
} }
} }
// //
@ -227,9 +235,19 @@ public:
{ {
return m_char_map[static_cast<unsigned char>(c)]; return m_char_map[static_cast<unsigned char>(c)];
} }
char tolower(char c)const
{
return m_lower_map[static_cast<unsigned char>(c)];
}
bool isctype(boost::uint32_t mask, char c)
{
return m_type_map[static_cast<unsigned char>(c)] & mask;
}
private: private:
regex_constants::syntax_type m_char_map[1u << CHAR_BIT]; regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
char m_lower_map[1u << CHAR_BIT];
boost::uint16_t m_type_map[1u << CHAR_BIT];
void init(); void init();
}; };
@ -266,7 +284,7 @@ public:
typedef typename string_type::size_type size_type; typedef typename string_type::size_type size_type;
string_type temp(p1, p2); string_type temp(p1, p2);
for(size_type i = 0; i < temp.size(); ++i) for(size_type i = 0; i < temp.size(); ++i)
temp[i] = ::boost::re_detail::w32_tolower(temp[i], this->m_locale); temp[i] = this->tolower(temp[i]);
result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size()); result = lookup_classname_imp(&*temp.begin(), &*temp.begin() + temp.size());
} }
return result; return result;
@ -307,7 +325,7 @@ typename w32_regex_traits_implementation<charT>::string_type
result.assign(p1, p2); result.assign(p1, p2);
typedef typename string_type::size_type size_type; typedef typename string_type::size_type size_type;
for(size_type i = 0; i < result.size(); ++i) for(size_type i = 0; i < result.size(); ++i)
result[i] = ::boost::re_detail::w32_tolower(result[i], this->m_locale); result[i] = this->tolower(result[i]);
result = this->transform(&*result.begin(), &*result.begin() + result.size()); result = this->transform(&*result.begin(), &*result.begin() + result.size());
break; break;
} }
@ -344,7 +362,7 @@ typename w32_regex_traits_implementation<charT>::string_type
if(pos != m_custom_collate_names.end()) if(pos != m_custom_collate_names.end())
return pos->second; return pos->second;
} }
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
std::string name(p1, p2); std::string name(p1, p2);
#else #else
std::string name; std::string name;
@ -353,7 +371,7 @@ typename w32_regex_traits_implementation<charT>::string_type
name.append(1, char(*p0++)); name.append(1, char(*p0++));
#endif #endif
name = lookup_default_collate_name(name); name = lookup_default_collate_name(name);
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
if(name.size()) if(name.size())
return string_type(name.begin(), name.end()); return string_type(name.begin(), name.end());
#else #else
@ -386,7 +404,7 @@ w32_regex_traits_implementation<charT>::w32_regex_traits_implementation(::boost:
{ {
std::string m("Unable to open message catalog: "); std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name); std::runtime_error err(m + cat_name);
boost::throw_exception(err); boost::re_detail::raise_runtime_error(err);
} }
} }
// //
@ -534,15 +552,15 @@ public:
} }
charT translate_nocase(charT c) const charT translate_nocase(charT c) const
{ {
return ::boost::re_detail::w32_tolower(c, this->m_pimpl->m_locale); return this->m_pimpl->tolower(c);
} }
charT translate(charT c, bool icase) const charT translate(charT c, bool icase) const
{ {
return icase ? ::boost::re_detail::w32_tolower(c, this->m_pimpl->m_locale) : c; return icase ? this->m_pimpl->tolower(c) : c;
} }
charT tolower(charT c) const charT tolower(charT c) const
{ {
return ::boost::re_detail::w32_tolower(c, this->m_pimpl->m_locale); return this->m_pimpl->tolower(c);
} }
charT toupper(charT c) const charT toupper(charT c) const
{ {
@ -567,7 +585,7 @@ public:
bool isctype(charT c, char_class_type f) const bool isctype(charT c, char_class_type f) const
{ {
if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base) if((f & re_detail::w32_regex_traits_implementation<charT>::mask_base)
&& (::boost::re_detail::w32_is(this->m_pimpl->m_locale, f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c))) && (this->m_pimpl->isctype(f & re_detail::w32_regex_traits_implementation<charT>::mask_base, c)))
return true; return true;
else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c)) else if((f & re_detail::w32_regex_traits_implementation<charT>::mask_unicode) && re_detail::is_extended(c))
return true; return true;
@ -581,7 +599,8 @@ public:
} }
int value(charT c, int radix)const int value(charT c, int radix)const
{ {
return ::boost::re_detail::global_value(c); int result = ::boost::re_detail::global_value(c);
return result < radix ? result : -1;
} }
locale_type imbue(locale_type l) locale_type imbue(locale_type l)
{ {

View File

@ -76,8 +76,8 @@ c_regex_traits<char>::string_type BOOST_REGEX_CALL c_regex_traits<char>::transfo
{ {
result.assign(p1, p2); result.assign(p1, p2);
for(std::string::size_type i = 0; i < result.size(); ++i) for(std::string::size_type i = 0; i < result.size(); ++i)
result[i] = (std::tolower)(static_cast<unsigned char>(result[i])); result[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(result[i])));
result = transform(&*result.begin(), &*result.end()); result = transform(&*result.begin(), &*result.begin() + result.size());
break; break;
} }
case ::boost::re_detail::sort_fixed: case ::boost::re_detail::sort_fixed:
@ -151,8 +151,8 @@ c_regex_traits<char>::char_class_type BOOST_REGEX_CALL c_regex_traits<char>::loo
{ {
std::string s(p1, p2); std::string s(p1, p2);
for(std::string::size_type i = 0; i < s.size(); ++i) for(std::string::size_type i = 0; i < s.size(); ++i)
s[i] = (std::tolower)(static_cast<unsigned char>(s[i])); s[i] = static_cast<char>((std::tolower)(static_cast<unsigned char>(s[i])));
id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.end()); id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
} }
BOOST_ASSERT(id+1 < sizeof(masks) / sizeof(masks[0])); BOOST_ASSERT(id+1 < sizeof(masks) / sizeof(masks[0]));
return masks[id+1]; return masks[id+1];

View File

@ -18,6 +18,7 @@
#define BOOST_REGEX_SOURCE #define BOOST_REGEX_SOURCE
#include <boost/regex/regex_traits.hpp> #include <boost/regex/regex_traits.hpp>
#include <boost/regex/pattern_except.hpp>
#ifdef BOOST_NO_STDC_NAMESPACE #ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ namespace std{
@ -47,7 +48,7 @@ void cpp_regex_traits_char_layer<char>::init()
{ {
std::string m("Unable to open message catalog: "); std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name); std::runtime_error err(m + cat_name);
boost::throw_exception(err); boost::re_detail::raise_runtime_error(err);
} }
} }
// //

View File

@ -28,6 +28,7 @@
#else #else
#include <boost/regex/v4/fileiter.hpp> #include <boost/regex/v4/fileiter.hpp>
#endif #endif
#include <boost/regex/pattern_except.hpp>
#include <cstdio> #include <cstdio>
#if defined(BOOST_NO_STDC_NAMESPACE) #if defined(BOOST_NO_STDC_NAMESPACE)
@ -104,7 +105,7 @@ void mapfile::open(const char* file)
hmap = 0; hmap = 0;
hfile = 0; hfile = 0;
std::runtime_error err("Unable to create file mapping."); std::runtime_error err("Unable to create file mapping.");
boost::throw_exception(err); boost::re_detail::raise_runtime_error(err);
} }
_first = static_cast<const char*>(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0)); _first = static_cast<const char*>(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0));
if(_first == 0) if(_first == 0)

View File

@ -51,10 +51,28 @@ namespace boost{
// types - this ensures that exceptions can be thrown // types - this ensures that exceptions can be thrown
// from the dll and caught in an exe. // from the dll and caught in an exe.
regex_error::regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos) regex_error::regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos)
: std::runtime_error(s), m_error_code(err), m_position(pos) {} : std::runtime_error(s)
, m_error_code(err)
, m_position(pos)
{
}
regex_error::regex_error(regex_constants::error_type err) regex_error::regex_error(regex_constants::error_type err)
: std::runtime_error(::boost::re_detail::get_default_error_string(err)), m_error_code(err), m_position(0) {} : std::runtime_error(::boost::re_detail::get_default_error_string(err))
regex_error::~regex_error() throw() {} , m_error_code(err)
, m_position(0)
{
}
regex_error::~regex_error() throw()
{
}
void regex_error::raise()const
{
::boost::throw_exception(*this);
}
namespace re_detail{ namespace re_detail{

View File

@ -2,6 +2,7 @@
#define BOOST_REGEX_SOURCE #define BOOST_REGEX_SOURCE
#include <memory> #include <memory>
#include <cstring>
#include <boost/assert.hpp> #include <boost/assert.hpp>
#include <boost/regex/v4/regex_raw_buffer.hpp> #include <boost/regex/v4/regex_raw_buffer.hpp>

View File

@ -21,6 +21,7 @@
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) #if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
#include <boost/regex/regex_traits.hpp> #include <boost/regex/regex_traits.hpp>
#include <boost/regex/pattern_except.hpp>
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#define NOMINMAX #define NOMINMAX
@ -53,7 +54,7 @@ void w32_regex_traits_char_layer<char>::init()
{ {
std::string m("Unable to open message catalog: "); std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name); std::runtime_error err(m + cat_name);
boost::throw_exception(err); ::boost::re_detail::raise_runtime_error(err);
} }
} }
// //
@ -96,6 +97,17 @@ void w32_regex_traits_char_layer<char>::init()
m_char_map[i] = regex_constants::escape_type_not_class; m_char_map[i] = regex_constants::escape_type_not_class;
} }
}while(0xFF != i++); }while(0xFF != i++);
//
// fill in lower case map:
//
char char_map[1 << CHAR_BIT];
for(int ii = 0; ii < (1 << CHAR_BIT); ++ii)
char_map[ii] = static_cast<char>(ii);
int r = ::LCMapStringA(this->m_locale, LCMAP_LOWERCASE, char_map, 1 << CHAR_BIT, this->m_lower_map, 1 << CHAR_BIT);
BOOST_ASSERT(r == 1 << CHAR_BIT);
r = ::GetStringTypeExA(this->m_locale, CT_CTYPE1, char_map, 1 << CHAR_BIT, this->m_type_map);
BOOST_ASSERT(0 != r);
} }
BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale() BOOST_REGEX_DECL lcid_type BOOST_REGEX_CALL w32_get_default_locale()
@ -146,7 +158,7 @@ BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name)
return result; return result;
} }
BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type id, int i, const std::string& def) BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::string& def)
{ {
char buf[256]; char buf[256];
if(0 == ::LoadStringA( if(0 == ::LoadStringA(
@ -158,11 +170,11 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, l
{ {
return def; return def;
} }
return buf; return std::string(buf);
} }
#ifndef BOOST_NO_WREGEX #ifndef BOOST_NO_WREGEX
BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type id, int i, const std::wstring& def) BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat, lcid_type, int i, const std::wstring& def)
{ {
wchar_t buf[256]; wchar_t buf[256];
if(0 == ::LoadStringW( if(0 == ::LoadStringW(
@ -174,7 +186,7 @@ BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_cat_get(const cat_type& cat,
{ {
return def; return def;
} }
return buf; return std::wstring(buf);
} }
#endif #endif
BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const char* p1, const char* p2) BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const char* p1, const char* p2)
@ -198,7 +210,7 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL w32_transform(lcid_type id, const
&*result.begin(), // destination buffer &*result.begin(), // destination buffer
bytes // size of destination buffer bytes // size of destination buffer
); );
if(bytes > result.size()) if(bytes > static_cast<int>(result.size()))
return std::string(p1, p2); return std::string(p1, p2);
while(result.size() && result[result.size()-1] == '\0') while(result.size() && result[result.size()-1] == '\0')
{ {
@ -229,7 +241,7 @@ BOOST_REGEX_DECL std::wstring BOOST_REGEX_CALL w32_transform(lcid_type id, const
reinterpret_cast<wchar_t*>(&*result.begin()), // destination buffer *of bytes* reinterpret_cast<wchar_t*>(&*result.begin()), // destination buffer *of bytes*
bytes // size of destination buffer bytes // size of destination buffer
); );
if(bytes > result.size()) if(bytes > static_cast<int>(result.size()))
return std::wstring(p1, p2); return std::wstring(p1, p2);
while(result.size() && result[result.size()-1] == L'\0') while(result.size() && result[result.size()-1] == L'\0')
{ {

View File

@ -69,19 +69,19 @@ c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::t
result.assign(p1, p2); result.assign(p1, p2);
for(std::wstring::size_type i = 0; i < result.size(); ++i) for(std::wstring::size_type i = 0; i < result.size(); ++i)
result[i] = (std::towlower)(result[i]); result[i] = (std::towlower)(result[i]);
result = this->transform(&*result.begin(), &*result.end()); result = this->transform(&*result.begin(), &*result.begin() + result.size());
break; break;
} }
case ::boost::re_detail::sort_fixed: case ::boost::re_detail::sort_fixed:
{ {
// get a regular sort key, and then truncate it: // get a regular sort key, and then truncate it:
result = this->transform(&*result.begin(), &*result.end()); result = this->transform(&*result.begin(), &*result.begin() + result.size());
result.erase(s_delim); result.erase(s_delim);
break; break;
} }
case ::boost::re_detail::sort_delim: case ::boost::re_detail::sort_delim:
// get a regular sort key, and then truncate everything after the delim: // get a regular sort key, and then truncate everything after the delim:
result = this->transform(&*result.begin(), &*result.end()); result = this->transform(&*result.begin(), &*result.begin() + result.size());
std::size_t i; std::size_t i;
for(i = 0; i < result.size(); ++i) for(i = 0; i < result.size(); ++i)
{ {
@ -144,7 +144,7 @@ c_regex_traits<wchar_t>::char_class_type BOOST_REGEX_CALL c_regex_traits<wchar_t
std::wstring s(p1, p2); std::wstring s(p1, p2);
for(std::wstring::size_type i = 0; i < s.size(); ++i) for(std::wstring::size_type i = 0; i < s.size(); ++i)
s[i] = (std::towlower)(s[i]); s[i] = (std::towlower)(s[i]);
id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.end()); id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size());
} }
BOOST_ASSERT(id+1 < sizeof(masks) / sizeof(masks[0])); BOOST_ASSERT(id+1 < sizeof(masks) / sizeof(masks[0]));
return masks[id+1]; return masks[id+1];
@ -169,7 +169,7 @@ bool BOOST_REGEX_CALL c_regex_traits<wchar_t>::isctype(wchar_t c, char_class_typ
c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::lookup_collatename(const wchar_t* p1, const wchar_t* p2) const c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::lookup_collatename(const wchar_t* p1, const wchar_t* p2) const
{ {
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
std::string name(p1, p2); std::string name(p1, p2);
#else #else
std::string name; std::string name;
@ -178,7 +178,7 @@ c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::l
name.append(1, char(*p0++)); name.append(1, char(*p0++));
#endif #endif
name = ::boost::re_detail::lookup_default_collate_name(name); name = ::boost::re_detail::lookup_default_collate_name(name);
#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS #if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
if(name.size()) if(name.size())
return string_type(name.begin(), name.end()); return string_type(name.begin(), name.end());
#else #else
@ -200,6 +200,11 @@ c_regex_traits<wchar_t>::string_type BOOST_REGEX_CALL c_regex_traits<wchar_t>::l
int BOOST_REGEX_CALL c_regex_traits<wchar_t>::value(wchar_t c, int radix) const int BOOST_REGEX_CALL c_regex_traits<wchar_t>::value(wchar_t c, int radix) const
{ {
#ifdef __BORLANDC__
// workaround for broken wcstol:
if((std::iswxdigit)(c) == 0)
return -1;
#endif
wchar_t b[2] = { c, '\0', }; wchar_t b[2] = { c, '\0', };
wchar_t* ep; wchar_t* ep;
int result = std::wcstol(b, &ep, radix); int result = std::wcstol(b, &ep, radix);

View File

@ -22,7 +22,6 @@
#include <boost/regex/concepts.hpp> #include <boost/regex/concepts.hpp>
#endif #endif
boost::re_detail::digraph<boost::char_architype> get_next_set_literal();
int main() int main()
{ {

View File

@ -25,6 +25,7 @@ void basic_tests()
TEST_REGEX_SEARCH("()", perl, "zzz", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 2, 2, 2, 2, -2, 3, 3, 3, 3, -2, -2)); TEST_REGEX_SEARCH("()", perl, "zzz", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 2, 2, 2, 2, -2, 3, 3, 3, 3, -2, -2));
TEST_REGEX_SEARCH("()", perl, "", match_default, make_array(0, 0, 0, 0, -2, -2)); TEST_REGEX_SEARCH("()", perl, "", match_default, make_array(0, 0, 0, 0, -2, -2));
TEST_INVALID_REGEX("(", perl); TEST_INVALID_REGEX("(", perl);
TEST_INVALID_REGEX("", perl);
TEST_INVALID_REGEX(")", perl); TEST_INVALID_REGEX(")", perl);
TEST_INVALID_REGEX("(aa", perl); TEST_INVALID_REGEX("(aa", perl);
TEST_INVALID_REGEX("aa)", perl); TEST_INVALID_REGEX("aa)", perl);
@ -74,15 +75,22 @@ void basic_tests()
TEST_REGEX_SEARCH(".", basic, "\n", match_not_dot_null | match_not_dot_newline, make_array(-2, -2)); TEST_REGEX_SEARCH(".", basic, "\n", match_not_dot_null | match_not_dot_newline, make_array(-2, -2));
TEST_REGEX_SEARCH(".", basic, "\r", match_not_dot_null | match_not_dot_newline, make_array(-2, -2)); TEST_REGEX_SEARCH(".", basic, "\r", match_not_dot_null | match_not_dot_newline, make_array(-2, -2));
TEST_REGEX_SEARCH(".", basic, "\0", match_not_dot_null | match_not_dot_newline, make_array(-2, -2)); TEST_REGEX_SEARCH(".", basic, "\0", match_not_dot_null | match_not_dot_newline, make_array(-2, -2));
}
void test_simple_repeats()
{
using namespace boost::regex_constants;
// simple repeats: // simple repeats:
TEST_REGEX_SEARCH("a*", perl, "b", match_default, make_array(0, 0, -2, 1, 1, -2, -2)); TEST_REGEX_SEARCH("a*", perl, "b", match_default, make_array(0, 0, -2, 1, 1, -2, -2));
TEST_REGEX_SEARCH("ab*", perl, "ab", match_default, make_array(0, 2, -2, -2)); TEST_REGEX_SEARCH("ab*", perl, "ab", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("ab*", basic, "ab", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("ab*", perl, "sssabbbbbbsss", match_default, make_array(3, 10, -2, -2)); TEST_REGEX_SEARCH("ab*", perl, "sssabbbbbbsss", match_default, make_array(3, 10, -2, -2));
TEST_REGEX_SEARCH("ab*c*", perl, "a", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("ab*c*", perl, "a", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("ab*c*", perl, "abbb", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("ab*c*", perl, "abbb", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("ab*c*", perl, "accc", match_default, make_array(0, 4, -2, -2)); TEST_REGEX_SEARCH("ab*c*", perl, "accc", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("ab*c*", perl, "abbcc", match_default, make_array(0, 5, -2, -2)); TEST_REGEX_SEARCH("ab*c*", perl, "abbcc", match_default, make_array(0, 5, -2, -2));
TEST_REGEX_SEARCH("*a", basic, "*a", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("^*a", basic, "*a", match_default, make_array(0, 2, -2, -2));
TEST_INVALID_REGEX("*a", perl); TEST_INVALID_REGEX("*a", perl);
TEST_INVALID_REGEX("\\<*", perl); TEST_INVALID_REGEX("\\<*", perl);
TEST_INVALID_REGEX("\\>*", perl); TEST_INVALID_REGEX("\\>*", perl);
@ -156,6 +164,8 @@ void basic_tests()
TEST_INVALID_REGEX("a{", perl); TEST_INVALID_REGEX("a{", perl);
TEST_INVALID_REGEX("a{1", perl); TEST_INVALID_REGEX("a{1", perl);
TEST_INVALID_REGEX("a{1,", perl); TEST_INVALID_REGEX("a{1,", perl);
TEST_INVALID_REGEX("a{1,2", perl);
TEST_INVALID_REGEX("a{ 1 , 2 ", perl);
TEST_INVALID_REGEX("a{ }", perl); TEST_INVALID_REGEX("a{ }", perl);
TEST_INVALID_REGEX("a}", perl); TEST_INVALID_REGEX("a}", perl);
TEST_INVALID_REGEX("{1}", perl); TEST_INVALID_REGEX("{1}", perl);
@ -163,9 +173,11 @@ void basic_tests()
TEST_INVALID_REGEX("a{1b}", perl); TEST_INVALID_REGEX("a{1b}", perl);
TEST_INVALID_REGEX("a{1,b}", perl); TEST_INVALID_REGEX("a{1,b}", perl);
TEST_INVALID_REGEX("a{1,2v}", perl); TEST_INVALID_REGEX("a{1,2v}", perl);
TEST_INVALID_REGEX("a{2,1}", perl);
// now try operator \\{\\} for POSIX basic regexes // now try operator \\{\\} for POSIX basic regexes
TEST_REGEX_SEARCH("a\\{2\\}", basic, "a", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a\\{2\\}", basic, "a", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("a\\{2\\}", basic|no_intervals, "a{2}", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("a\\{2\\}", basic, "aa", match_default, make_array(0, 2, -2, -2)); TEST_REGEX_SEARCH("a\\{2\\}", basic, "aa", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("a\\{2\\}", basic, "aaa", match_default, make_array(0, 2, -2, -2)); TEST_REGEX_SEARCH("a\\{2\\}", basic, "aaa", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("a\\{2,\\}", basic, "a", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a\\{2,\\}", basic, "a", match_default, make_array(-2, -2));
@ -184,6 +196,7 @@ void basic_tests()
TEST_INVALID_REGEX("a\\{", basic); TEST_INVALID_REGEX("a\\{", basic);
TEST_INVALID_REGEX("a\\{1", basic); TEST_INVALID_REGEX("a\\{1", basic);
TEST_INVALID_REGEX("a\\{1,", basic); TEST_INVALID_REGEX("a\\{1,", basic);
TEST_INVALID_REGEX("a\\{1,\\", basic);
TEST_INVALID_REGEX("a\\{ \\}", basic); TEST_INVALID_REGEX("a\\{ \\}", basic);
TEST_INVALID_REGEX("a\\}", basic); TEST_INVALID_REGEX("a\\}", basic);
TEST_INVALID_REGEX("\\{1\\}", basic); TEST_INVALID_REGEX("\\{1\\}", basic);
@ -191,6 +204,7 @@ void basic_tests()
TEST_INVALID_REGEX("a\\{1b\\}", basic); TEST_INVALID_REGEX("a\\{1b\\}", basic);
TEST_INVALID_REGEX("a\\{1,b\\}", basic); TEST_INVALID_REGEX("a\\{1,b\\}", basic);
TEST_INVALID_REGEX("a\\{1,2v\\}", basic); TEST_INVALID_REGEX("a\\{1,2v\\}", basic);
TEST_INVALID_REGEX("a\\{3,1\\}", basic);
} }
@ -237,6 +251,7 @@ void test_sets()
TEST_REGEX_SEARCH("[^bcd]", extended, "e", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[^bcd]", extended, "e", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("a[b]c", extended, "abc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[b]c", extended, "abc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("a[ab]c", extended, "abc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[ab]c", extended, "abc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("a[a^b]*c", extended, "aba^c", match_default, make_array(0, 5, -2, -2));
TEST_REGEX_SEARCH("a[^ab]c", extended, "adc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[^ab]c", extended, "adc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("a[]b]c", extended, "a]c", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[]b]c", extended, "a]c", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("a[[b]c", extended, "a[c", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[[b]c", extended, "a[c", match_default, make_array(0, 3, -2, -2));
@ -245,6 +260,7 @@ void test_sets()
TEST_REGEX_SEARCH("a[^-b]c", extended, "adc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[^-b]c", extended, "adc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("a[b-]c", extended, "a-c", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[b-]c", extended, "a-c", match_default, make_array(0, 3, -2, -2));
TEST_INVALID_REGEX("a[b", extended); TEST_INVALID_REGEX("a[b", extended);
TEST_INVALID_REGEX("a[", extended);
TEST_INVALID_REGEX("a[]", extended); TEST_INVALID_REGEX("a[]", extended);
// now some ranges: // now some ranges:
@ -265,13 +281,18 @@ void test_sets()
TEST_INVALID_REGEX("a[3-1]c", extended); TEST_INVALID_REGEX("a[3-1]c", extended);
TEST_INVALID_REGEX("a[1-3-5]c", extended); TEST_INVALID_REGEX("a[1-3-5]c", extended);
TEST_INVALID_REGEX("a[1-", extended); TEST_INVALID_REGEX("a[1-", extended);
TEST_INVALID_REGEX("a[\\9]", perl);
// and some classes // and some classes
TEST_REGEX_SEARCH("a[[:alpha:]]c", extended, "abc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("a[[:alpha:]]c", extended, "abc", match_default, make_array(0, 3, -2, -2));
TEST_INVALID_REGEX("a[[:unknown:]]c", extended); TEST_INVALID_REGEX("a[[:unknown:]]c", extended);
TEST_INVALID_REGEX("a[[", extended);
TEST_INVALID_REGEX("a[[:", extended); TEST_INVALID_REGEX("a[[:", extended);
TEST_INVALID_REGEX("a[[:a", extended);
TEST_INVALID_REGEX("a[[:alpha", extended); TEST_INVALID_REGEX("a[[:alpha", extended);
TEST_INVALID_REGEX("a[[:alpha:", extended);
TEST_INVALID_REGEX("a[[:alpha:]", extended); TEST_INVALID_REGEX("a[[:alpha:]", extended);
TEST_INVALID_REGEX("a[[:alpha:!", extended);
TEST_INVALID_REGEX("a[[:alpha,:]", extended); TEST_INVALID_REGEX("a[[:alpha,:]", extended);
TEST_INVALID_REGEX("a[[:]:]]b", extended); TEST_INVALID_REGEX("a[[:]:]]b", extended);
TEST_INVALID_REGEX("a[[:-:]]b", extended); TEST_INVALID_REGEX("a[[:-:]]b", extended);
@ -295,6 +316,7 @@ void test_sets()
// perl or awk regular expressions: // perl or awk regular expressions:
// //
TEST_REGEX_SEARCH("[\\n]", perl, "\n", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[\\n]", perl, "\n", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[\\b]", perl, "\b", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[\\n]", basic, "\n", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("[\\n]", basic, "\n", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("[\\n]", basic, "\\", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[\\n]", basic, "\\", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[:class:]", basic|no_char_classes, ":", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[:class:]", basic|no_char_classes, ":", match_default, make_array(0, 1, -2, -2));
@ -321,7 +343,11 @@ void test_sets()
TEST_REGEX_SEARCH("\\W", perl, "`", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("\\W", perl, "`", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\W", perl, "[", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("\\W", perl, "[", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\W", perl, "@", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("\\W", perl, "@", match_default, make_array(0, 1, -2, -2));
}
void test_sets2()
{
using namespace boost::regex_constants;
// collating elements // collating elements
TEST_REGEX_SEARCH("[[.zero.]]", perl, "0", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[.zero.]]", perl, "0", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.one.]]", perl, "1", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[.one.]]", perl, "1", match_default, make_array(0, 1, -2, -2));
@ -330,6 +356,11 @@ void test_sets()
TEST_REGEX_SEARCH("[[.a.]]", perl, "bac", match_default, make_array(1, 2, -2, -2)); TEST_REGEX_SEARCH("[[.a.]]", perl, "bac", match_default, make_array(1, 2, -2, -2));
TEST_REGEX_SEARCH("[[.right-curly-bracket.]]", perl, "}", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[.right-curly-bracket.]]", perl, "}", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.NUL.]]", perl, "\0", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[.NUL.]]", perl, "\0", match_default, make_array(0, 1, -2, -2));
TEST_INVALID_REGEX("[[.", perl);
TEST_INVALID_REGEX("[[.N", perl);
TEST_INVALID_REGEX("[[.NUL", perl);
TEST_INVALID_REGEX("[[.NUL.", perl);
TEST_INVALID_REGEX("[[.NUL.]", perl);
TEST_INVALID_REGEX("[[:<:]z]", perl); TEST_INVALID_REGEX("[[:<:]z]", perl);
TEST_INVALID_REGEX("[a[:>:]]", perl); TEST_INVALID_REGEX("[a[:>:]]", perl);
TEST_REGEX_SEARCH("[[.A.]]", extended|icase, "A", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[.A.]]", extended|icase, "A", match_default, make_array(0, 1, -2, -2));
@ -363,6 +394,28 @@ void test_sets()
TEST_REGEX_SEARCH("[[.Ae.]-b]", basic|icase, "b", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[.Ae.]-b]", basic|icase, "b", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.Ae.]-b]", basic|icase, "B", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[.Ae.]-b]", basic|icase, "B", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]-b]", basic|icase, "AE", match_default, make_array(0, 2, -2, -2)); TEST_REGEX_SEARCH("[[.ae.]-b]", basic|icase, "AE", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]]", perl, "ae", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]]", perl, "aE", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("[[.AE.]]", perl, "AE", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.Ae.]]", perl, "Ae", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]-b]", perl, "a", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("[[.ae.]-b]", perl, "b", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]-b]", perl, "ae", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[a-[.ae.]]", perl, "a", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[a-[.ae.]]", perl, "b", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("[a-[.ae.]]", perl, "ae", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]]", perl|icase, "AE", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]]", perl|icase, "Ae", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.AE.]]", perl|icase, "Ae", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.Ae.]]", perl|icase, "aE", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.AE.]-B]", perl|icase, "a", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("[[.Ae.]-b]", perl|icase, "b", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.Ae.]-b]", perl|icase, "B", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.ae.]-b]", perl|icase, "AE", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.ae.][:lower:]]", perl|icase, "AE", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[.ae.][:lower:]]", perl|icase, "A", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.ae.][=a=]]", perl, "A", match_default, make_array(0, 1, -2, -2));
TEST_INVALID_REGEX("[d-[.ae.]]", perl);
// //
// try some equivalence classes: // try some equivalence classes:
// //
@ -370,6 +423,11 @@ void test_sets()
TEST_REGEX_SEARCH("[[=a=]]", basic, "A", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[=a=]]", basic, "A", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[=ae=]]", basic, "ae", match_default, make_array(0, 2, -2, -2)); TEST_REGEX_SEARCH("[[=ae=]]", basic, "ae", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("[[=right-curly-bracket=]]", basic, "}", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("[[=right-curly-bracket=]]", basic, "}", match_default, make_array(0, 1, -2, -2));
TEST_INVALID_REGEX("[[=", perl);
TEST_INVALID_REGEX("[[=a", perl);
TEST_INVALID_REGEX("[[=ae", perl);
TEST_INVALID_REGEX("[[=ae=", perl);
TEST_INVALID_REGEX("[[=ae=]", perl);
// //
// now some perl style single character classes: // now some perl style single character classes:
// //
@ -403,6 +461,13 @@ void test_anchors()
TEST_REGEX_SEARCH("ab$", extended, "abxx", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("ab$", extended, "abxx", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("ab$", extended, "ab\nzz", match_default, make_array(0, 2, -2, -2)); TEST_REGEX_SEARCH("ab$", extended, "ab\nzz", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("^ab", basic, "ab", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("^ab", basic, "xxabxx", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("^ab", basic, "xx\nabzz", match_default, make_array(3, 5, -2, -2));
TEST_REGEX_SEARCH("ab$", basic, "ab", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("ab$", basic, "abxx", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("ab$", basic, "ab\nzz", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("^ab", extended, "ab", match_default | match_not_bol | match_not_eol, make_array(-2, -2)); TEST_REGEX_SEARCH("^ab", extended, "ab", match_default | match_not_bol | match_not_eol, make_array(-2, -2));
TEST_REGEX_SEARCH("^ab", extended, "xxabxx", match_default | match_not_bol | match_not_eol, make_array(-2, -2)); TEST_REGEX_SEARCH("^ab", extended, "xxabxx", match_default | match_not_bol | match_not_eol, make_array(-2, -2));
TEST_REGEX_SEARCH("^ab", extended, "xx\nabzz", match_default | match_not_bol | match_not_eol, make_array(3, 5, -2, -2)); TEST_REGEX_SEARCH("^ab", extended, "xx\nabzz", match_default | match_not_bol | match_not_eol, make_array(3, 5, -2, -2));
@ -444,6 +509,7 @@ void test_backrefs()
TEST_REGEX_SEARCH("a(b*)c\\1d", perl, "abbcbbbd", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a(b*)c\\1d", perl, "abbcbbbd", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("^(.)\\1", perl, "abc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("^(.)\\1", perl, "abc", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("a([bc])\\1d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); TEST_REGEX_SEARCH("a([bc])\\1d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2));
TEST_REGEX_SEARCH("a\\([bc]\\)\\1d", basic, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2));
// strictly speaking this is at best ambiguous, at worst wrong, this is what most // strictly speaking this is at best ambiguous, at worst wrong, this is what most
// re implimentations will match though. // re implimentations will match though.
TEST_REGEX_SEARCH("a(([bc])\\2)*d", perl, "abbccd", match_default, make_array(0, 6, 3, 5, 3, 4, -2, -2)); TEST_REGEX_SEARCH("a(([bc])\\2)*d", perl, "abbccd", match_default, make_array(0, 6, 3, 5, 3, 4, -2, -2));
@ -491,6 +557,8 @@ void test_character_escapes()
TEST_REGEX_SEARCH("\\x{1b}", perl, "\x1B", match_default, make_array(0, 1, -2, -2)); TEST_REGEX_SEARCH("\\x{1b}", perl, "\x1B", match_default, make_array(0, 1, -2, -2));
TEST_INVALID_REGEX("\\x{}", perl); TEST_INVALID_REGEX("\\x{}", perl);
TEST_INVALID_REGEX("\\x{", perl); TEST_INVALID_REGEX("\\x{", perl);
TEST_INVALID_REGEX("\\", perl);
TEST_INVALID_REGEX("\\c", perl);
TEST_INVALID_REGEX("\\x}", perl); TEST_INVALID_REGEX("\\x}", perl);
TEST_INVALID_REGEX("\\x", perl); TEST_INVALID_REGEX("\\x", perl);
TEST_INVALID_REGEX("\\x{yy", perl); TEST_INVALID_REGEX("\\x{yy", perl);
@ -506,6 +574,11 @@ void test_character_escapes()
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) #if !BOOST_WORKAROUND(__BORLANDC__, < 0x560)
TEST_REGEX_SEARCH_W(L"\\X", perl, L"a\x0300\x0301", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH_W(L"\\X", perl, L"a\x0300\x0301", match_default, make_array(0, 3, -2, -2));
#endif #endif
// unknown escape sequences match themselves:
TEST_REGEX_SEARCH("\\~", perl, "~", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\~", basic, "~", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\~", extended, "~", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\j", extended, "j", match_default, make_array(0, 1, -2, -2));
} }
void test_assertion_escapes() void test_assertion_escapes()
@ -521,6 +594,7 @@ void test_assertion_escapes()
TEST_REGEX_SEARCH("abc\\>", perl, "abcd", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("abc\\>", perl, "abcd", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("abc\\>", perl, "abc\n", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("abc\\>", perl, "abc\n", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("abc\\>", perl, "abc::", match_default, make_array(0,3, -2, -2)); TEST_REGEX_SEARCH("abc\\>", perl, "abc::", match_default, make_array(0,3, -2, -2));
TEST_REGEX_SEARCH("abc(?:\\>..|$)", perl, "abc::", match_default, make_array(0, 5, -2, -2));
// word boundary: // word boundary:
TEST_REGEX_SEARCH("\\babcd", perl, " abcd", match_default, make_array(2, 6, -2, -2)); TEST_REGEX_SEARCH("\\babcd", perl, " abcd", match_default, make_array(2, 6, -2, -2));
TEST_REGEX_SEARCH("\\bab", perl, "cab", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("\\bab", perl, "cab", match_default, make_array(-2, -2));
@ -543,6 +617,7 @@ void test_assertion_escapes()
TEST_REGEX_SEARCH("abc\\'", perl, "abc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("abc\\'", perl, "abc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("abc\\'", perl, "abc\n", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("abc\\'", perl, "abc\n", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("abc\\'", perl, "abc ", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("abc\\'", perl, "abc ", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("abc(?:\\'|$)", perl, "abc", match_default, make_array(0, 3, -2, -2));
// word start: // word start:
TEST_REGEX_SEARCH("[[:<:]]abcd", perl, " abcd", match_default, make_array(2, 6, -2, -2)); TEST_REGEX_SEARCH("[[:<:]]abcd", perl, " abcd", match_default, make_array(2, 6, -2, -2));
@ -565,6 +640,7 @@ void test_assertion_escapes()
TEST_REGEX_SEARCH("\\Gabc", perl, "dabcd", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("\\Gabc", perl, "dabcd", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("a\\Gbc", perl, "abc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a\\Gbc", perl, "abc", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("a\\Aab", perl, "abc", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("a\\Aab", perl, "abc", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("abc(?:\\Z|$)", perl, "abc\n\n", match_default, make_array(0, 3, -2, -2));
} }
void test_tricky_cases() void test_tricky_cases()
@ -833,7 +909,7 @@ void test_tricky_cases2()
make_array(753, 1076, 934, 1005, -2, 2143, 2466, 2324, 2395, -2, -2)); make_array(753, 1076, 934, 1005, -2, 2143, 2466, 2324, 2395, -2, -2));
test(char(0), test_regex_search_tag()); test(char(0), test_regex_search_tag());
}while(0); }while(0);
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) #if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
do{ do{
std::string st(big_text); std::string st(big_text);
test_info<wchar_t>::set_info(__FILE__, __LINE__, test_info<wchar_t>::set_info(__FILE__, __LINE__,
@ -943,6 +1019,7 @@ void test_replace()
TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?1A", "...A,,,A*A?"); TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?1A", "...A,,,A*A?");
TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?1:B", "...B,,,B*B?"); TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?1:B", "...B,,,B*B?");
TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?1A:(?2B))", "...AB,,,AB*AB?"); TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?1A:(?2B))", "...AB,,,AB*AB?");
TEST_REGEX_REPLACE("X", literal, "XX", match_default, "Y", "YY");
} }
void test_non_greedy_repeats() void test_non_greedy_repeats()
@ -1035,9 +1112,22 @@ void test_forward_lookahead_asserts()
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, 6, -2, -2));
// lookbehind, with nested lookahead! :
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("/\\*.*(?<=(?>\\*))/", 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, 4, 2, 3, -2, -2));
// lookbehind with invalid content:
TEST_INVALID_REGEX("(/)\\*.*(?<=\\1)/", perl);
TEST_INVALID_REGEX("/\\*.*(?<=\\*+)/", perl);
TEST_INVALID_REGEX("/\\*.*(?<=\\X)/", perl);
TEST_INVALID_REGEX("/\\*.*(?<=[[.ae.]])/", perl);
TEST_INVALID_REGEX("(?<=[abc]", perl); TEST_INVALID_REGEX("(?<=[abc]", perl);
TEST_INVALID_REGEX("(?<=", perl); TEST_INVALID_REGEX("(?<=", perl);
TEST_INVALID_REGEX("(?<", perl); TEST_INVALID_REGEX("(?<", perl);
TEST_INVALID_REGEX("(?<*", perl);
TEST_INVALID_REGEX("(?", perl); TEST_INVALID_REGEX("(?", perl);
} }
@ -1374,6 +1464,14 @@ void test_conditionals()
TEST_INVALID_REGEX("(a)(?(1)a|b|c)", perl); TEST_INVALID_REGEX("(a)(?(1)a|b|c)", perl);
TEST_INVALID_REGEX("(?(?=a)a|b|c)", perl); TEST_INVALID_REGEX("(?(?=a)a|b|c)", perl);
TEST_INVALID_REGEX("(?(1a)", perl); TEST_INVALID_REGEX("(?(1a)", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(1", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(1)", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(a", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(?", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(?:", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(?<", perl);
TEST_INVALID_REGEX("(?:(a)|b)(?(?<a", perl);
} }
void test_options() void test_options()
@ -1384,6 +1482,7 @@ void test_options()
TEST_INVALID_REGEX("(?g", perl); TEST_INVALID_REGEX("(?g", perl);
TEST_INVALID_REGEX("(?im-sx", perl); TEST_INVALID_REGEX("(?im-sx", perl);
TEST_INVALID_REGEX("(?im-sx:", perl); TEST_INVALID_REGEX("(?im-sx:", perl);
TEST_INVALID_REGEX("(?-g)", perl);
TEST_REGEX_SEARCH("(?-m)^abc", perl, "abc\nabc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("(?-m)^abc", perl, "abc\nabc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("(?m)^abc", perl|no_mod_m, "abc\nabc", match_default, make_array(0, 3, -2, 4, 7, -2, -2)); TEST_REGEX_SEARCH("(?m)^abc", perl|no_mod_m, "abc\nabc", match_default, make_array(0, 3, -2, 4, 7, -2, -2));
TEST_REGEX_SEARCH("(?-m)^abc", perl, "abc\nabc", match_default, make_array(0, 3, -2, -2)); TEST_REGEX_SEARCH("(?-m)^abc", perl, "abc\nabc", match_default, make_array(0, 3, -2, -2));
@ -1439,7 +1538,14 @@ void test_options()
TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "a bcde", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "a bcde", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(a b(?x)c d (?-x)e f)", perl, "a bcde f", match_default, make_array(0, 8, 0, 8, -2, -2)); TEST_REGEX_SEARCH("(a b(?x)c d (?-x)e f)", perl, "a bcde f", match_default, make_array(0, 8, 0, 8, -2, -2));
TEST_REGEX_SEARCH("(a b(?x)c d (?-x)e f)", perl, "abcdef", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(a b(?x)c d (?-x)e f)", perl, "abcdef", match_default, make_array(-2, -2));
}
void test_options2()
{
using namespace boost::regex_constants;
TEST_INVALID_REGEX("(?i-", perl);
TEST_INVALID_REGEX("(?i-s", perl);
TEST_INVALID_REGEX("(?i-sd)", perl);
TEST_REGEX_SEARCH("(a(?i)b)c", perl, "abc", match_default, make_array(0, 3, 0, 2, -2, -2)); TEST_REGEX_SEARCH("(a(?i)b)c", perl, "abc", match_default, make_array(0, 3, 0, 2, -2, -2));
TEST_REGEX_SEARCH("(a(?i)b)c", perl, "aBc", match_default, make_array(0, 3, 0, 2, -2, -2)); TEST_REGEX_SEARCH("(a(?i)b)c", perl, "aBc", match_default, make_array(0, 3, 0, 2, -2, -2));
TEST_REGEX_SEARCH("(a(?i)b)c", perl, "abC", match_default, make_array(-2, -2)); TEST_REGEX_SEARCH("(a(?i)b)c", perl, "abC", match_default, make_array(-2, -2));
@ -1775,7 +1881,7 @@ void test_options()
make_array(0, 25, -2, -2)); make_array(0, 25, -2, -2));
test(char(0), test_regex_search_tag()); test(char(0), test_regex_search_tag());
}while(0); }while(0);
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) #if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
do{ do{
std::string st(big_expression); std::string st(big_expression);
test_info<wchar_t>::set_info(__FILE__, __LINE__, test_info<wchar_t>::set_info(__FILE__, __LINE__,
@ -1792,7 +1898,7 @@ void test_options()
make_array(1, 13, -2, -2)); make_array(1, 13, -2, -2));
test(char(0), test_regex_search_tag()); test(char(0), test_regex_search_tag());
}while(0); }while(0);
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) #if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
do{ do{
std::string st(big_expression); std::string st(big_expression);
test_info<wchar_t>::set_info(__FILE__, __LINE__, test_info<wchar_t>::set_info(__FILE__, __LINE__,
@ -1809,7 +1915,7 @@ void test_options()
make_array(0, 42, -2, -2)); make_array(0, 42, -2, -2));
test(char(0), test_regex_search_tag()); test(char(0), test_regex_search_tag());
}while(0); }while(0);
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) #if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
do{ do{
std::string st(big_expression); std::string st(big_expression);
test_info<wchar_t>::set_info(__FILE__, __LINE__, test_info<wchar_t>::set_info(__FILE__, __LINE__,
@ -1826,7 +1932,7 @@ void test_options()
make_array(2, 40, -2, -2)); make_array(2, 40, -2, -2));
test(char(0), test_regex_search_tag()); test(char(0), test_regex_search_tag());
}while(0); }while(0);
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) #if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
do{ do{
std::string st(big_expression); std::string st(big_expression);
test_info<wchar_t>::set_info(__FILE__, __LINE__, test_info<wchar_t>::set_info(__FILE__, __LINE__,
@ -1843,7 +1949,7 @@ void test_options()
make_array(0, 61, -2, -2)); make_array(0, 61, -2, -2));
test(char(0), test_regex_search_tag()); test(char(0), test_regex_search_tag());
}while(0); }while(0);
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) #if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
do{ do{
std::string st(big_expression); std::string st(big_expression);
test_info<wchar_t>::set_info(__FILE__, __LINE__, test_info<wchar_t>::set_info(__FILE__, __LINE__,
@ -1860,7 +1966,7 @@ void test_options()
make_array(17, 32, -2, -2)); make_array(17, 32, -2, -2));
test(char(0), test_regex_search_tag()); test(char(0), test_regex_search_tag());
}while(0); }while(0);
#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) #if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
do{ do{
std::string st(big_expression); std::string st(big_expression);
test_info<wchar_t>::set_info(__FILE__, __LINE__, test_info<wchar_t>::set_info(__FILE__, __LINE__,

View File

@ -7,8 +7,10 @@ int error_count = 0;
int cpp_main(int argc, char * argv[]) int cpp_main(int argc, char * argv[])
{ {
basic_tests(); basic_tests();
test_simple_repeats();
test_alt(); test_alt();
test_sets(); test_sets();
test_sets2();
test_anchors(); test_anchors();
test_backrefs(); test_backrefs();
test_character_escapes(); test_character_escapes();
@ -26,6 +28,7 @@ int cpp_main(int argc, char * argv[])
test_nosubs(); test_nosubs();
test_conditionals(); test_conditionals();
test_options(); test_options();
test_options2();
return error_count; return error_count;
} }

View File

@ -138,8 +138,10 @@ const int* make_array(int first, ...);
// define the test group proceedures: // define the test group proceedures:
// //
void basic_tests(); void basic_tests();
void test_simple_repeats();
void test_alt(); void test_alt();
void test_sets(); void test_sets();
void test_sets2();
void test_anchors(); void test_anchors();
void test_backrefs(); void test_backrefs();
void test_character_escapes(); void test_character_escapes();
@ -157,5 +159,6 @@ void test_independent_subs();
void test_nosubs(); void test_nosubs();
void test_conditionals(); void test_conditionals();
void test_options(); void test_options();
void test_options2();
#endif #endif

View File

@ -104,7 +104,6 @@ void test_deprecated(const char&, const test_regex_search_tag&)
// //
if(test_info<char>::syntax_options() & ~boost::regex::icase) if(test_info<char>::syntax_options() & ~boost::regex::icase)
return; return;
bool have_catch = false;
try{ try{
boost::RegEx e(expression, test_info<char>::syntax_options() & boost::regex::icase); boost::RegEx e(expression, test_info<char>::syntax_options() & boost::regex::icase);
if(e.Search(search_text, test_info<char>::match_options())) if(e.Search(search_text, test_info<char>::match_options()))
@ -114,11 +113,11 @@ void test_deprecated(const char&, const test_regex_search_tag&)
{ {
if(e.Matched(i)) if(e.Matched(i))
{ {
if(results[2*i] != e.Position(i)) if(results[2*i] != static_cast<int>(e.Position(i)))
{ {
BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the RegEx class (found " << e.Position(i) << " expected " << results[2*i] << ").", char); BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the RegEx class (found " << e.Position(i) << " expected " << results[2*i] << ").", char);
} }
if(results[2*i+1] != e.Position(i) + e.Length(i)) if(results[2*i+1] != static_cast<int>(e.Position(i) + e.Length(i)))
{ {
BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the RegEx class (found " << e.Position(i) + e.Length(i) << " expected " << results[2*i+1] << ").", char); BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the RegEx class (found " << e.Position(i) + e.Length(i) << " expected " << results[2*i+1] << ").", char);
} }