diff --git a/example/jgrep/main.cpp b/example/jgrep/main.cpp index c625f494..32ea68b2 100644 --- a/example/jgrep/main.cpp +++ b/example/jgrep/main.cpp @@ -33,13 +33,6 @@ using namespace std; #ifndef BOOST_REGEX_NO_FILEITER #include -#ifdef BOOST_NO_STDC_NAMESPACE -namespace std{ - using ::strcpy; using ::strcat; - using ::sprintf; -} -#endif - re_type e; // flags for output: @@ -170,18 +163,18 @@ void HandleFile(const char* wild) { // go through sub directories: char buf[MAX_PATH]; - std::strcpy(buf, start.root()); + strcpy(buf, start.root()); int rootlen = strlen(buf); if(*buf == 0) { - std::strcpy(buf, "."); - std::strcat(buf, directory_iterator::separator()); - std::strcat(buf, "*"); + strcpy(buf, "."); + strcat(buf, directory_iterator::separator()); + strcat(buf, "*"); } else { - std::strcat(buf, directory_iterator::separator()); - std::strcat(buf, "*"); + strcat(buf, directory_iterator::separator()); + strcat(buf, "*"); } directory_iterator dstart(buf); directory_iterator dend; @@ -192,12 +185,12 @@ void HandleFile(const char* wild) 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); ++dstart; } } - std::for_each(start, end, process_grep); + for_each(start, end, process_grep); } int done = 0; @@ -222,8 +215,8 @@ void HandleArg(const char* arg) } else { - char* buf = new char[std::strlen(arg) + 8]; - std::sprintf(buf, "\\<%s\\>", arg); + char* buf = new char[strlen(arg) + 8]; + sprintf(buf, "\\<%s\\>", arg); e.set_expression(buf, use_case ? regex::normal : regbase::normal | regbase::icase); //ei.set_expression(buf); delete[] buf; @@ -232,20 +225,20 @@ void HandleArg(const char* arg) else { // we need to convert text to literal: - int len2 = std::strlen(arg); + int len2 = strlen(arg); int len = len2 * 5 + 6; char buf[8]; char* buf2 = new char[len]; *buf2 = 0; if(words_only) - std::strcpy(buf2, "\\<"); + strcpy(buf2, "\\<"); for(int j = 0; j < len2; ++j) { - std::sprintf(buf, "\\0%o", int(arg[j])); - std::strcat(buf2, buf); + sprintf(buf, "\\0%o", int(arg[j])); + strcat(buf2, buf); } if(words_only) - std::strcat(buf2, "\\>"); + strcat(buf2, "\\>"); e.set_expression(buf2, use_case ? regex::normal : regbase::normal | regbase::icase); //ei.set_expression(buf2); delete[] buf2; @@ -273,7 +266,7 @@ int main(int argc, char * argv[]) int main(int argc, char * argv[]) { - std::cout << + cout << "\n\n" "This functionality is not available on with this compiler on this platform.\n" "\n"; diff --git a/include/boost/regex/pattern_except.hpp b/include/boost/regex/pattern_except.hpp index 19078fa1..51d202e7 100644 --- a/include/boost/regex/pattern_except.hpp +++ b/include/boost/regex/pattern_except.hpp @@ -47,6 +47,7 @@ public: { return m_error_code; } std::ptrdiff_t position()const { return m_position; } + void raise()const; private: regex_constants::error_type m_error_code; std::ptrdiff_t m_position; diff --git a/include/boost/regex/v4/basic_regex.hpp b/include/boost/regex/v4/basic_regex.hpp index 5260f870..40b72775 100644 --- a/include/boost/regex/v4/basic_regex.hpp +++ b/include/boost/regex/v4/basic_regex.hpp @@ -265,7 +265,7 @@ public: { typedef typename traits::string_type seq_type; seq_type a(arg_first, arg_last); - assign(&*a.begin(), &*a.end(), f); + assign(&*a.begin(), &*a.begin() + a.size(), f); } template @@ -290,7 +290,7 @@ public: typedef typename traits::string_type seq_type; seq_type a(arg_first, arg_last); const charT* p1 = &*a.begin(); - const charT* p2 = &*a.end(); + const charT* p2 = &*a.begin() + a.size(); return assign(p1, p2, f); } #else @@ -453,32 +453,32 @@ public: // 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(); } unsigned get_restart_type()const { - assert(m_pimpl.get()); + assert(0 != m_pimpl.get()); return m_pimpl->get_restart_type(); } const unsigned char* get_map()const { - assert(m_pimpl.get()); + assert(0 != m_pimpl.get()); return m_pimpl->get_map(); } const ::boost::regex_traits_wrapper& get_traits()const { - assert(m_pimpl.get()); + assert(0 != m_pimpl.get()); return m_pimpl->get_traits(); } bool can_be_null()const { - assert(m_pimpl.get()); + assert(0 != m_pimpl.get()); return m_pimpl->can_be_null(); } const re_detail::regex_data& get_data()const { - assert(m_pimpl.get()); + assert(0 != m_pimpl.get()); return m_pimpl->get_data(); } diff --git a/include/boost/regex/v4/basic_regex_creator.hpp b/include/boost/regex/v4/basic_regex_creator.hpp index 863e3cad..d6563c59 100644 --- a/include/boost/regex/v4/basic_regex_creator.hpp +++ b/include/boost/regex/v4/basic_regex_creator.hpp @@ -33,7 +33,8 @@ struct digraph : public std::pair { digraph() : std::pair(0, 0){} digraph(charT c1) : std::pair(c1, 0){} - digraph(charT c1, charT c2) : std::pair(c1, c2){} + digraph(charT c1, charT c2) : std::pair(c1, c2) + {} #if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) digraph(const digraph& d) : std::pair(d.first, d.second){} #endif @@ -407,11 +408,13 @@ re_syntax_base* basic_regex_creator::append_set( else { if(c1.second) - s1 = string_type(&c1.first, &c1.second+1); + { + s1.append(1, c1.first).append(1, c1.second); + } else s1 = string_type(1, c1.first); if(c2.second) - s2 = string_type(&c2.first, &c2.second+1); + s2.append(1, c2.first).append(1, c2.second); else s2 = string_type(1, c2.first); } @@ -548,13 +551,8 @@ re_syntax_base* basic_regex_creator::append_set( while(first != last) { string_type s; - if(first->second) - { - 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); + BOOST_ASSERT(static_cast(0) == first->second); + s = m_traits.transform_primary(&first->first, &first->first+1); if(s.empty()) return 0; // invalid or unsupported equivalence class for(unsigned i = 0; i < (1u << CHAR_BIT); ++i) @@ -683,6 +681,13 @@ void basic_regex_creator::create_startmaps(re_syntax_base* state) // we need to calculate how big the backstep is: static_cast(state)->index = this->calculate_backstep(state->next.p); + if(static_cast(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: default: state = state->next.p; @@ -718,6 +723,7 @@ int basic_regex_creator::calculate_backstep(re_syntax_base* state if((static_cast(state)->index == -1) || (static_cast(state)->index == -2)) return result; + break; case syntax_element_literal: result += static_cast(state)->length; break; @@ -1037,7 +1043,7 @@ bool basic_regex_creator::is_bad_repeat(re_syntax_base* pt) unsigned id = static_cast(pt)->id; if(id > sizeof(m_bad_repeats) * CHAR_BIT) 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(1uL << id); } default: return false; @@ -1057,7 +1063,7 @@ void basic_regex_creator::set_bad_repeat(re_syntax_base* pt) { unsigned id = static_cast(pt)->id; if(id <= sizeof(m_bad_repeats) * CHAR_BIT) - m_bad_repeats |= (1u << id); + m_bad_repeats |= static_cast(1uL << id); } default: break; diff --git a/include/boost/regex/v4/basic_regex_parser.hpp b/include/boost/regex/v4/basic_regex_parser.hpp index 8bb7867f..f2b26752 100644 --- a/include/boost/regex/v4/basic_regex_parser.hpp +++ b/include/boost/regex/v4/basic_regex_parser.hpp @@ -121,7 +121,7 @@ void basic_regex_parser::fail(regex_constants::error_type error_c { std::string message = this->m_pdata->m_ptraits->error_string(error_code); boost::regex_error e(message, error_code, position); - boost::throw_exception(e); + e.raise(); } template @@ -1109,10 +1109,7 @@ charT basic_regex_parser::unescape_character() template bool basic_regex_parser::parse_backref() { - if(m_position == m_end) - { - fail(regex_constants::error_escape, m_position - m_end); - } + BOOST_ASSERT(m_position != m_end); int i = this->m_traits.toi(m_position, m_position + 1, 10); if((i > 0) && (this->m_backrefs & (1u << (i-1)))) { diff --git a/include/boost/regex/v4/cpp_regex_traits.hpp b/include/boost/regex/v4/cpp_regex_traits.hpp index 5b71eadd..1bc2d8ee 100644 --- a/include/boost/regex/v4/cpp_regex_traits.hpp +++ b/include/boost/regex/v4/cpp_regex_traits.hpp @@ -230,7 +230,7 @@ cpp_regex_traits_char_layer::cpp_regex_traits_char_layer(const std::local { std::string m("Unable to open message catalog: "); 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; }; +#if !defined(BOOST_NO_INCLASS_MEMBER_INITIALIZATION) + +template +typename cpp_regex_traits_implementation::char_class_type const cpp_regex_traits_implementation::mask_blank; +template +typename cpp_regex_traits_implementation::char_class_type const cpp_regex_traits_implementation::mask_word; +template +typename cpp_regex_traits_implementation::char_class_type const cpp_regex_traits_implementation::mask_unicode; +#ifdef __GNUC__ +template +typename cpp_regex_traits_implementation::native_mask_type const cpp_regex_traits_implementation::mask_base; +#else +template +typename cpp_regex_traits_implementation::char_class_type const cpp_regex_traits_implementation::mask_base; +#endif + +#endif + template typename cpp_regex_traits_implementation::string_type cpp_regex_traits_implementation::transform_primary(const charT* p1, const charT* p2) const @@ -454,7 +472,7 @@ typename cpp_regex_traits_implementation::string_type if(pos != m_custom_collate_names.end()) 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); #else std::string name; @@ -463,7 +481,7 @@ typename cpp_regex_traits_implementation::string_type name.append(1, char(*p0++)); #endif 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()) return string_type(name.begin(), name.end()); #else @@ -502,7 +520,7 @@ cpp_regex_traits_implementation::cpp_regex_traits_implementation(const st { std::string m("Unable to open message catalog: "); std::runtime_error err(m + cat_name); - boost::throw_exception(err); + boost::re_detail::raise_runtime_error(err); } } // diff --git a/include/boost/regex/v4/match_results.hpp b/include/boost/regex/v4/match_results.hpp index 0de349ac..8bdefac1 100644 --- a/include/boost/regex/v4/match_results.hpp +++ b/include/boost/regex/v4/match_results.hpp @@ -106,7 +106,7 @@ public: const sub_match& s = m_subs[sub]; if(s.matched) { - result = s; + result = s.str(); } } return result; diff --git a/include/boost/regex/v4/perl_matcher_non_recursive.hpp b/include/boost/regex/v4/perl_matcher_non_recursive.hpp index 8bb9dc92..df612996 100644 --- a/include/boost/regex/v4/perl_matcher_non_recursive.hpp +++ b/include/boost/regex/v4/perl_matcher_non_recursive.hpp @@ -38,7 +38,13 @@ inline void inplace_destroy(T* p) 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) {} }; @@ -629,7 +635,7 @@ bool perl_matcher::match_char_repeat() if(::boost::is_random_access_iterator::value) { 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); while((position != end) && (traits_inst.translate(*position, icase) == what)) { @@ -696,7 +702,7 @@ bool perl_matcher::match_set_repeat() if(::boost::is_random_access_iterator::value) { 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); while((position != end) && map[static_cast(traits_inst.translate(*position, icase))]) { @@ -764,7 +770,7 @@ bool perl_matcher::match_long_set_repeat() if(::boost::is_random_access_iterator::value) { 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); while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase))) { diff --git a/include/boost/regex/v4/regex_token_iterator.hpp b/include/boost/regex/v4/regex_token_iterator.hpp index 056c4e5f..e3674a38 100644 --- a/include/boost/regex/v4/regex_token_iterator.hpp +++ b/include/boost/regex/v4/regex_token_iterator.hpp @@ -67,7 +67,8 @@ public: : end(last), re(*p), flags(f), subs(v){} #if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\ || 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 regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f) : end(last), re(*p), flags(f) @@ -195,7 +196,8 @@ public: } #if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\ || 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 regex_token_iterator(BidirectionalIterator a, BidirectionalIterator b, const regex_type& re, const T& submatches, match_flag_type m = match_default) diff --git a/include/boost/regex/v4/regex_traits.hpp b/include/boost/regex/v4/regex_traits.hpp index 866076e1..a19b092b 100644 --- a/include/boost/regex/v4/regex_traits.hpp +++ b/include/boost/regex/v4/regex_traits.hpp @@ -73,7 +73,7 @@ struct regex_traits : public implementationT // required "standard" ones: // 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) #else template @@ -126,7 +126,7 @@ struct compute_wrapper_base { 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 struct compute_wrapper_base { diff --git a/include/boost/regex/v4/regex_traits_defaults.hpp b/include/boost/regex/v4/regex_traits_defaults.hpp index e5376e91..904c0620 100644 --- a/include/boost/regex/v4/regex_traits_defaults.hpp +++ b/include/boost/regex/v4/regex_traits_defaults.hpp @@ -83,7 +83,7 @@ inline bool is_combining(wchar_t c) { return is_combining_implementation(static_cast(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) template<> inline bool is_combining(wchar_t c) diff --git a/include/boost/regex/v4/sub_match.hpp b/include/boost/regex/v4/sub_match.hpp index 2160d8da..e42633b0 100644 --- a/include/boost/regex/v4/sub_match.hpp +++ b/include/boost/regex/v4/sub_match.hpp @@ -46,7 +46,7 @@ struct sub_match : public std::pair template operator std::basic_string ()const { - return std::basic_string(first, second); + return std::basic_string(this->first, this->second); } #else operator std::basic_string ()const diff --git a/include/boost/regex/v4/w32_regex_traits.hpp b/include/boost/regex/v4/w32_regex_traits.hpp index 19667e07..38221713 100644 --- a/include/boost/regex/v4/w32_regex_traits.hpp +++ b/include/boost/regex/v4/w32_regex_traits.hpp @@ -138,6 +138,14 @@ public: } 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: string_type get_default_message(regex_constants::syntax_type); @@ -160,7 +168,7 @@ w32_regex_traits_char_layer::w32_regex_traits_char_layer(::boost::re_deta { std::string m("Unable to open message catalog: "); 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(c)]; } + char tolower(char c)const + { + return m_lower_map[static_cast(c)]; + } + bool isctype(boost::uint32_t mask, char c) + { + return m_type_map[static_cast(c)] & mask; + } private: 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(); }; @@ -266,7 +284,7 @@ public: typedef typename string_type::size_type size_type; string_type temp(p1, p2); 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()); } return result; @@ -307,7 +325,7 @@ typename w32_regex_traits_implementation::string_type result.assign(p1, p2); typedef typename string_type::size_type size_type; 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()); break; } @@ -344,7 +362,7 @@ typename w32_regex_traits_implementation::string_type if(pos != m_custom_collate_names.end()) 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); #else std::string name; @@ -353,7 +371,7 @@ typename w32_regex_traits_implementation::string_type name.append(1, char(*p0++)); #endif 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()) return string_type(name.begin(), name.end()); #else @@ -386,7 +404,7 @@ w32_regex_traits_implementation::w32_regex_traits_implementation(::boost: { std::string m("Unable to open message catalog: "); 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 { - 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 { - 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 { - return ::boost::re_detail::w32_tolower(c, this->m_pimpl->m_locale); + return this->m_pimpl->tolower(c); } charT toupper(charT c) const { @@ -567,7 +585,7 @@ public: bool isctype(charT c, char_class_type f) const { if((f & re_detail::w32_regex_traits_implementation::mask_base) - && (::boost::re_detail::w32_is(this->m_pimpl->m_locale, f & re_detail::w32_regex_traits_implementation::mask_base, c))) + && (this->m_pimpl->isctype(f & re_detail::w32_regex_traits_implementation::mask_base, c))) return true; else if((f & re_detail::w32_regex_traits_implementation::mask_unicode) && re_detail::is_extended(c)) return true; @@ -581,7 +599,8 @@ public: } 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) { diff --git a/src/c_regex_traits.cpp b/src/c_regex_traits.cpp index 697dc17c..b6caef94 100644 --- a/src/c_regex_traits.cpp +++ b/src/c_regex_traits.cpp @@ -76,8 +76,8 @@ c_regex_traits::string_type BOOST_REGEX_CALL c_regex_traits::transfo { result.assign(p1, p2); for(std::string::size_type i = 0; i < result.size(); ++i) - result[i] = (std::tolower)(static_cast(result[i])); - result = transform(&*result.begin(), &*result.end()); + result[i] = static_cast((std::tolower)(static_cast(result[i]))); + result = transform(&*result.begin(), &*result.begin() + result.size()); break; } case ::boost::re_detail::sort_fixed: @@ -151,8 +151,8 @@ c_regex_traits::char_class_type BOOST_REGEX_CALL c_regex_traits::loo { std::string s(p1, p2); for(std::string::size_type i = 0; i < s.size(); ++i) - s[i] = (std::tolower)(static_cast(s[i])); - id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.end()); + s[i] = static_cast((std::tolower)(static_cast(s[i]))); + id = ::boost::re_detail::get_default_class_id(&*s.begin(), &*s.begin() + s.size()); } BOOST_ASSERT(id+1 < sizeof(masks) / sizeof(masks[0])); return masks[id+1]; diff --git a/src/cpp_regex_traits.cpp b/src/cpp_regex_traits.cpp index 4faf7f8c..d7566e3a 100644 --- a/src/cpp_regex_traits.cpp +++ b/src/cpp_regex_traits.cpp @@ -18,6 +18,7 @@ #define BOOST_REGEX_SOURCE #include +#include #ifdef BOOST_NO_STDC_NAMESPACE namespace std{ @@ -47,7 +48,7 @@ void cpp_regex_traits_char_layer::init() { std::string m("Unable to open message catalog: "); std::runtime_error err(m + cat_name); - boost::throw_exception(err); + boost::re_detail::raise_runtime_error(err); } } // diff --git a/src/fileiter.cpp b/src/fileiter.cpp index 2ad4c121..1e2f19f1 100644 --- a/src/fileiter.cpp +++ b/src/fileiter.cpp @@ -28,6 +28,7 @@ #else #include #endif +#include #include #if defined(BOOST_NO_STDC_NAMESPACE) @@ -104,7 +105,7 @@ void mapfile::open(const char* file) hmap = 0; hfile = 0; std::runtime_error err("Unable to create file mapping."); - boost::throw_exception(err); + boost::re_detail::raise_runtime_error(err); } _first = static_cast(MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0)); if(_first == 0) diff --git a/src/regex.cpp b/src/regex.cpp index 2a5b2d70..dc7a221d 100644 --- a/src/regex.cpp +++ b/src/regex.cpp @@ -51,10 +51,28 @@ namespace boost{ // types - this ensures that exceptions can be thrown // 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) - : 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) - : std::runtime_error(::boost::re_detail::get_default_error_string(err)), m_error_code(err), m_position(0) {} -regex_error::~regex_error() throw() {} + : std::runtime_error(::boost::re_detail::get_default_error_string(err)) + , m_error_code(err) + , m_position(0) +{ +} + +regex_error::~regex_error() throw() +{ +} + +void regex_error::raise()const +{ + ::boost::throw_exception(*this); +} + namespace re_detail{ diff --git a/src/regex_raw_buffer.cpp b/src/regex_raw_buffer.cpp index 5d7d2d1f..3d38a591 100644 --- a/src/regex_raw_buffer.cpp +++ b/src/regex_raw_buffer.cpp @@ -2,6 +2,7 @@ #define BOOST_REGEX_SOURCE #include +#include #include #include diff --git a/src/w32_regex_traits.cpp b/src/w32_regex_traits.cpp index 120ee806..a292a595 100644 --- a/src/w32_regex_traits.cpp +++ b/src/w32_regex_traits.cpp @@ -21,6 +21,7 @@ #if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) #include +#include #define WIN32_LEAN_AND_MEAN #define NOMINMAX @@ -53,7 +54,7 @@ void w32_regex_traits_char_layer::init() { std::string m("Unable to open message catalog: "); 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::init() m_char_map[i] = regex_constants::escape_type_not_class; } }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(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() @@ -146,7 +158,7 @@ BOOST_REGEX_DECL cat_type BOOST_REGEX_CALL w32_cat_open(const std::string& name) 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]; 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 buf; + return std::string(buf); } #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]; 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 buf; + return std::wstring(buf); } #endif 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 bytes // size of destination buffer ); - if(bytes > result.size()) + if(bytes > static_cast(result.size())) return std::string(p1, p2); 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(&*result.begin()), // destination buffer *of bytes* bytes // size of destination buffer ); - if(bytes > result.size()) + if(bytes > static_cast(result.size())) return std::wstring(p1, p2); while(result.size() && result[result.size()-1] == L'\0') { diff --git a/src/wc_regex_traits.cpp b/src/wc_regex_traits.cpp index a4230a04..c38bbd1a 100644 --- a/src/wc_regex_traits.cpp +++ b/src/wc_regex_traits.cpp @@ -69,19 +69,19 @@ c_regex_traits::string_type BOOST_REGEX_CALL c_regex_traits::t result.assign(p1, p2); for(std::wstring::size_type i = 0; i < result.size(); ++i) result[i] = (std::towlower)(result[i]); - result = this->transform(&*result.begin(), &*result.end()); + result = this->transform(&*result.begin(), &*result.begin() + result.size()); break; } case ::boost::re_detail::sort_fixed: { // 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); break; } case ::boost::re_detail::sort_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; for(i = 0; i < result.size(); ++i) { @@ -144,7 +144,7 @@ c_regex_traits::char_class_type BOOST_REGEX_CALL c_regex_traits::isctype(wchar_t c, char_class_typ c_regex_traits::string_type BOOST_REGEX_CALL c_regex_traits::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); #else std::string name; @@ -178,7 +178,7 @@ c_regex_traits::string_type BOOST_REGEX_CALL c_regex_traits::l name.append(1, char(*p0++)); #endif 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()) return string_type(name.begin(), name.end()); #else @@ -200,6 +200,11 @@ c_regex_traits::string_type BOOST_REGEX_CALL c_regex_traits::l int BOOST_REGEX_CALL c_regex_traits::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* ep; int result = std::wcstol(b, &ep, radix); diff --git a/test/concepts/concept_check.cpp b/test/concepts/concept_check.cpp index 59d0f1ff..1af01638 100644 --- a/test/concepts/concept_check.cpp +++ b/test/concepts/concept_check.cpp @@ -22,7 +22,6 @@ #include #endif -boost::re_detail::digraph get_next_set_literal(); int main() { diff --git a/test/regress/basic_tests.cpp b/test/regress/basic_tests.cpp index 0ef3a2e9..ec84858c 100644 --- a/test/regress/basic_tests.cpp +++ b/test/regress/basic_tests.cpp @@ -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, "", 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("(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, "\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)); +} +void test_simple_repeats() +{ + using namespace boost::regex_constants; // simple repeats: 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*", 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*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, "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("*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("\\<*", perl); TEST_INVALID_REGEX("\\>*", perl); @@ -156,6 +164,8 @@ void basic_tests() TEST_INVALID_REGEX("a{", 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("{1}", perl); @@ -163,9 +173,11 @@ void basic_tests() TEST_INVALID_REGEX("a{1b}", perl); TEST_INVALID_REGEX("a{1,b}", perl); TEST_INVALID_REGEX("a{1,2v}", perl); + TEST_INVALID_REGEX("a{2,1}", perl); // 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|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, "aaa", match_default, make_array(0, 2, -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\\{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("\\{1\\}", basic); @@ -191,6 +204,7 @@ void basic_tests() TEST_INVALID_REGEX("a\\{1b\\}", basic); TEST_INVALID_REGEX("a\\{1,b\\}", 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("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[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[]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, "a-c", match_default, make_array(0, 3, -2, -2)); TEST_INVALID_REGEX("a[b", extended); + TEST_INVALID_REGEX("a[", extended); TEST_INVALID_REGEX("a[]", extended); // now some ranges: @@ -265,13 +281,18 @@ void test_sets() TEST_INVALID_REGEX("a[3-1]c", extended); TEST_INVALID_REGEX("a[1-3-5]c", extended); TEST_INVALID_REGEX("a[1-", extended); + TEST_INVALID_REGEX("a[\\9]", perl); // and some classes 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[[", 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[[:]:]]b", extended); TEST_INVALID_REGEX("a[[:-:]]b", extended); @@ -295,6 +316,7 @@ void test_sets() // perl or awk regular expressions: // 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, "\\", 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)); +} +void test_sets2() +{ + using namespace boost::regex_constants; // collating elements 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)); @@ -330,6 +356,11 @@ void test_sets() 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("[[.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("[a[:>:]]", perl); 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, "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: // @@ -370,6 +423,11 @@ void test_sets() 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("[[=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: // @@ -403,6 +461,13 @@ void test_anchors() 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", 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, "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)); @@ -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("^(.)\\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", 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 // 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)); @@ -491,6 +557,8 @@ void test_character_escapes() 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("\\", perl); + TEST_INVALID_REGEX("\\c", perl); TEST_INVALID_REGEX("\\x}", perl); TEST_INVALID_REGEX("\\x", perl); TEST_INVALID_REGEX("\\x{yy", perl); @@ -506,6 +574,11 @@ void test_character_escapes() #if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) TEST_REGEX_SEARCH_W(L"\\X", perl, L"a\x0300\x0301", match_default, make_array(0, 3, -2, -2)); #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() @@ -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, "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, 5, -2, -2)); // word boundary: 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)); @@ -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\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(0, 3, -2, -2)); // word start: 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("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("abc(?:\\Z|$)", perl, "abc\n\n", match_default, make_array(0, 3, -2, -2)); } 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)); test(char(0), test_regex_search_tag()); }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{ std::string st(big_text); test_info::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, "?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("X", literal, "XX", match_default, "Y", "YY"); } 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, "/**/", 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("(?<=", 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)a|b|c)", 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)(?(?::set_info(__FILE__, __LINE__, @@ -1792,7 +1898,7 @@ void test_options() make_array(1, 13, -2, -2)); test(char(0), test_regex_search_tag()); }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{ std::string st(big_expression); test_info::set_info(__FILE__, __LINE__, @@ -1809,7 +1915,7 @@ void test_options() make_array(0, 42, -2, -2)); test(char(0), test_regex_search_tag()); }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{ std::string st(big_expression); test_info::set_info(__FILE__, __LINE__, @@ -1826,7 +1932,7 @@ void test_options() make_array(2, 40, -2, -2)); test(char(0), test_regex_search_tag()); }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{ std::string st(big_expression); test_info::set_info(__FILE__, __LINE__, @@ -1843,7 +1949,7 @@ void test_options() make_array(0, 61, -2, -2)); test(char(0), test_regex_search_tag()); }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{ std::string st(big_expression); test_info::set_info(__FILE__, __LINE__, @@ -1860,7 +1966,7 @@ void test_options() make_array(17, 32, -2, -2)); test(char(0), test_regex_search_tag()); }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{ std::string st(big_expression); test_info::set_info(__FILE__, __LINE__, diff --git a/test/regress/main.cpp b/test/regress/main.cpp index 937200b0..5464e7ba 100644 --- a/test/regress/main.cpp +++ b/test/regress/main.cpp @@ -7,8 +7,10 @@ int error_count = 0; int cpp_main(int argc, char * argv[]) { basic_tests(); + test_simple_repeats(); test_alt(); test_sets(); + test_sets2(); test_anchors(); test_backrefs(); test_character_escapes(); @@ -26,6 +28,7 @@ int cpp_main(int argc, char * argv[]) test_nosubs(); test_conditionals(); test_options(); + test_options2(); return error_count; } diff --git a/test/regress/test.hpp b/test/regress/test.hpp index af62f6ce..5dd8eac5 100644 --- a/test/regress/test.hpp +++ b/test/regress/test.hpp @@ -138,8 +138,10 @@ const int* make_array(int first, ...); // define the test group proceedures: // void basic_tests(); +void test_simple_repeats(); void test_alt(); void test_sets(); +void test_sets2(); void test_anchors(); void test_backrefs(); void test_character_escapes(); @@ -157,5 +159,6 @@ void test_independent_subs(); void test_nosubs(); void test_conditionals(); void test_options(); +void test_options2(); #endif diff --git a/test/regress/test_deprecated.cpp b/test/regress/test_deprecated.cpp index f74fad1f..520f5abc 100644 --- a/test/regress/test_deprecated.cpp +++ b/test/regress/test_deprecated.cpp @@ -104,7 +104,6 @@ void test_deprecated(const char&, const test_regex_search_tag&) // if(test_info::syntax_options() & ~boost::regex::icase) return; - bool have_catch = false; try{ boost::RegEx e(expression, test_info::syntax_options() & boost::regex::icase); if(e.Search(search_text, test_info::match_options())) @@ -114,11 +113,11 @@ void test_deprecated(const char&, const test_regex_search_tag&) { if(e.Matched(i)) { - if(results[2*i] != e.Position(i)) + if(results[2*i] != static_cast(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); } - if(results[2*i+1] != e.Position(i) + e.Length(i)) + if(results[2*i+1] != static_cast(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); }