diff options
Diffstat (limited to 'src/boost/libs/regex/test')
69 files changed, 11869 insertions, 0 deletions
diff --git a/src/boost/libs/regex/test/Jamfile.v2 b/src/boost/libs/regex/test/Jamfile.v2 new file mode 100644 index 00000000..49ed730b --- /dev/null +++ b/src/boost/libs/regex/test/Jamfile.v2 @@ -0,0 +1,203 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +project + : requirements + <threading>multi + <link>shared:<define>BOOST_REGEX_DYN_LINK=1 + <toolset>msvc-7.1:<define>TEST_MFC=1 + <toolset>msvc-7.0:<define>TEST_MFC=1 + <toolset>msvc:<asynch-exceptions>on + # There are unidentified linker problems on these platforms: + <toolset>mipspro-7.4:<link>static + <toolset>sun-5.9:<link>static + <warnings>all + <toolset>gcc:<cxxflags>-Wextra + <toolset>gcc:<cxxflags>-Wshadow + <define>U_USING_ICU_NAMESPACE=0 + #<toolset>gcc-mw:<link>static + #<toolset>gcc-mingw:<link>static + #<toolset>gcc-cygwin:<link>static + <toolset>sun:<link>static + ; + +# +# rule for simple regex test programs: +# +rule regex-test ( name : sources + : requirements * : input-files * ) +{ + return [ run $(sources) ../build//boost_regex + : + : $(input-files) + : $(requirements) + : $(name) ] ; +} + +R_SOURCE = +basic_tests.cpp +main.cpp +test_alt.cpp +test_anchors.cpp +test_asserts.cpp +test_backrefs.cpp +test_deprecated.cpp +test_emacs.cpp +test_escapes.cpp +test_grep.cpp +test_locale.cpp +test_mfc.cpp +test_non_greedy_repeats.cpp +test_perl_ex.cpp +test_replace.cpp +test_sets.cpp +test_simple_repeats.cpp +test_tricky_cases.cpp +test_icu.cpp +test_unicode.cpp +test_overloads.cpp +test_operators.cpp +; + +lib boost_regex_recursive : + ../src/c_regex_traits.cpp + ../src/cpp_regex_traits.cpp + ../src/cregex.cpp + ../src/fileiter.cpp + ../src/icu.cpp + ../src/instances.cpp + ../src/posix_api.cpp + ../src/regex.cpp + ../src/regex_debug.cpp + ../src/regex_raw_buffer.cpp + ../src/regex_traits_defaults.cpp + ../src/static_mutex.cpp + ../src/w32_regex_traits.cpp + ../src/wc_regex_traits.cpp + ../src/wide_posix_api.cpp + ../src/winstances.cpp + ../src/usinstances.cpp + ../build//icu_options + : + <define>BOOST_REGEX_RECURSIVE=1 + <link>shared:<define>BOOST_REGEX_DYN_LINK=1 + : + ; + +local regress-sources = regress/$(R_SOURCE) ; + +test-suite regex + : + [ run regress/$(R_SOURCE) ../build//boost_regex ../build//icu_options + : # command line + : # input files + : # requirements + : regex_regress ] + + [ run regress/$(R_SOURCE) ../build//boost_regex + ../../thread/build//boost_thread ../build//icu_options + : # command line + : # input files + : # requirements + <define>TEST_THREADS + : regex_regress_threaded ] + + [ regex-test posix_api_check : c_compiler_checks/posix_api_check.c ] + + [ compile c_compiler_checks/wide_posix_api_check.c + : : wide_posix_api_check_c ] + + [ regex-test posix_api_check_cpp : c_compiler_checks/posix_api_check.cpp ] + + [ regex-test wide_posix_api_check_cpp + : c_compiler_checks/wide_posix_api_check.cpp ] + + [ run pathology/bad_expression_test.cpp + ../build//boost_regex + ] + + [ run pathology/recursion_test.cpp + ../build//boost_regex + ] + + [ run named_subexpressions/named_subexpressions_test.cpp + ../build//boost_regex + ] + + [ run unicode/unicode_iterator_test.cpp ../build//boost_regex : : : release <define>TEST_UTF8 : unicode_iterator_test_utf8 ] + [ run unicode/unicode_iterator_test.cpp ../build//boost_regex : : : release <define>TEST_UTF16 : unicode_iterator_test_utf16 ] + [ run static_mutex/static_mutex_test.cpp + ../../thread/build//boost_thread ../build//boost_regex + ] + [ run object_cache/object_cache_test.cpp ../build//boost_regex + ] + + [ run config_info/regex_config_info.cpp + ../build//boost_regex/<link>static + : # command line + : # input files + : <test-info>always_show_run_output + ] + [ run config_info/regex_config_info.cpp ../build//boost_regex + : # command line + : # input files + : <test-info>always_show_run_output + : regex_dll_config_info + ] + + [ run collate_info/collate_info.cpp ../build//boost_regex + : : : <test-info>always_show_run_output : test_collate_info ] + + + [ link concepts/concept_check.cpp ../build//boost_regex ] + [ link concepts/icu_concept_check.cpp ../build//boost_regex ] + [ link concepts/range_concept_check.cpp ../build//boost_regex ] + [ run concepts/test_bug_11988.cpp ../build//boost_regex ] + + [ run + # sources + captures/captures_test.cpp + captures//boost_regex_extra ../build//icu_options + : # additional args + : # test-files + : # requirements + <threading>multi + <define>BOOST_REGEX_MATCH_EXTRA=1 + <define>BOOST_REGEX_NO_LIB=1 + : # test name + captures_test + ] + +[ run regress/$(R_SOURCE) .//boost_regex_recursive + ../build//icu_options + : # command line + : # input files + : # requirements + <define>BOOST_REGEX_RECURSIVE=1 + : regex_regress_recursive ] + +[ run regress/$(R_SOURCE) ./noeh_test//boost_regex_noeh + ../build//icu_options + : # command line + : # input files + : # requirements + <define>BOOST_NO_EXCEPTIONS=1 + <exception-handling>off + <link>static + <runtime-link>shared + : regex_regress_noeh ] + +; + +compile test_consolidated.cpp ; + +build-project ../example ; + +# `quick` target (for CI) +run quick.cpp ../build//boost_regex ; + +compile test_warnings.cpp + : <toolset>msvc:<warnings>all <toolset>msvc:<warnings-as-errors>on + <toolset>gcc:<warnings>all <toolset>gcc:<warnings-as-errors>on + <toolset>clang:<warnings>all <toolset>clang:<warnings-as-errors>on ; diff --git a/src/boost/libs/regex/test/c_compiler_checks/posix_api_check.c b/src/boost/libs/regex/test/c_compiler_checks/posix_api_check.c new file mode 100644 index 00000000..34abca14 --- /dev/null +++ b/src/boost/libs/regex/test/c_compiler_checks/posix_api_check.c @@ -0,0 +1,64 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE posix_api_compiler_check.c + * VERSION see <boost/version.hpp> + * DESCRIPTION: Verify that POSIX API calls compile: note this is a compile + * time check only. + */ + +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <boost/regex.h> + +const char* expression = "^"; +const char* text = "\n "; +regmatch_t matches[1]; +int flags = REG_EXTENDED | REG_BASIC | REG_NOSPEC | REG_ICASE | REG_NOSUB | + REG_NEWLINE | REG_PEND | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | + REG_NEWLINE_ALT | REG_PERL | REG_AWK | REG_GREP | REG_EGREP; + + +int main() +{ + regex_tA re; + int result; + result = regcompA(&re, expression, REG_AWK); + if(result > (int)REG_NOERROR) + { + char buf[256]; + regerrorA(result, &re, buf, sizeof(buf)); + puts(buf); + return result; + } + assert(re.re_nsub == 0); + matches[0].rm_so = 0; + matches[0].rm_eo = strlen(text); + result = regexecA(&re, text, 1, matches, REG_NOTBOL | REG_NOTEOL | REG_STARTEND); + if(result > (int)REG_NOERROR) + { + char buf[256]; + regerrorA(result, &re, buf, sizeof(buf)); + puts(buf); + regfreeA(&re); + return result; + } + assert((matches[0].rm_so == matches[0].rm_eo) && (matches[0].rm_eo == 1)); + regfreeA(&re); + printf("no errors found\n"); + return 0; +} + + + diff --git a/src/boost/libs/regex/test/c_compiler_checks/posix_api_check.cpp b/src/boost/libs/regex/test/c_compiler_checks/posix_api_check.cpp new file mode 100644 index 00000000..d3ff326a --- /dev/null +++ b/src/boost/libs/regex/test/c_compiler_checks/posix_api_check.cpp @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE posix_api_compiler_check.c + * VERSION see <boost/version.hpp> + * DESCRIPTION: Verify that POSIX API calls compile: note this is a compile + * time check only. + */ + +#include <stdio.h> +#include <string.h> +#include <boost/assert.hpp> +#include <boost/regex.h> +#include "../test_macros.hpp" + +const char* expression = "^"; +const char* text = "\n "; +regmatch_t matches[1]; +int flags = REG_EXTENDED | REG_BASIC | REG_NOSPEC | REG_ICASE | REG_NOSUB | + REG_NEWLINE | REG_PEND | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | + REG_NEWLINE_ALT | REG_PERL | REG_AWK | REG_GREP | REG_EGREP; + + +int main() +{ + regex_tA re; + unsigned int result; + result = regcompA(&re, expression, REG_AWK); + if(result > REG_NOERROR) + { + char buf[256]; + regerrorA(result, &re, buf, sizeof(buf)); + printf("%s", buf); + return result; + } + BOOST_CHECK(re.re_nsub == 0); + matches[0].rm_so = 0; + matches[0].rm_eo = strlen(text); + result = regexecA(&re, text, 1, matches, REG_NOTBOL | REG_NOTEOL | REG_STARTEND); + if(result > REG_NOERROR) + { + char buf[256]; + regerrorA(result, &re, buf, sizeof(buf)); + printf("%s", buf); + regfreeA(&re); + return result; + } + BOOST_CHECK(matches[0].rm_so == matches[0].rm_eo); + regfreeA(&re); + printf("no errors found\n"); + return boost::report_errors(); +} + + + diff --git a/src/boost/libs/regex/test/c_compiler_checks/wide_posix_api_check.c b/src/boost/libs/regex/test/c_compiler_checks/wide_posix_api_check.c new file mode 100644 index 00000000..cd1a287d --- /dev/null +++ b/src/boost/libs/regex/test/c_compiler_checks/wide_posix_api_check.c @@ -0,0 +1,89 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE wide_posix_api_compiler_check.c + * VERSION see <boost/version.hpp> + * DESCRIPTION: Verify that POSIX API calls compile: note this is a compile + * time check only. + */ + +#define UNICODE +#define _UNICODE + +#include <boost/regex.h> +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> + +#ifndef BOOST_NO_WREGEX +#include <wchar.h> + +const wchar_t* expression = L"^"; +const wchar_t* text = L"\n "; +regmatch_t matches[1]; +int flags = REG_EXTENDED | REG_BASIC | REG_NOSPEC | REG_ICASE | REG_NOSUB | + REG_NEWLINE | REG_PEND | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | + REG_NEWLINE_ALT | REG_PERL | REG_AWK | REG_GREP | REG_EGREP; + + +int main() +{ + regex_t re; + int result; + wchar_t buf[256]; + char nbuf[256]; + int i; + result = regcomp(&re, expression, REG_AWK); + if(result > (int)REG_NOERROR) + { + regerror(result, &re, buf, sizeof(buf)); + for(i = 0; i < 256; ++i) + nbuf[i] = (char)(buf[i]); + puts(nbuf); + return result; + } + if(re.re_nsub != 0) + { + regfree(&re); + exit(-1); + } + matches[0].rm_so = 0; + matches[0].rm_eo = wcslen(text); + result = regexec(&re, text, 1, matches, REG_NOTBOL | REG_NOTEOL | REG_STARTEND); + if(result > (int)REG_NOERROR) + { + regerror(result, &re, buf, sizeof(buf)); + for(i = 0; i < 256; ++i) + nbuf[i] = (char)(buf[i]); + puts(nbuf); + regfree(&re); + return result; + } + if((matches[0].rm_so != matches[0].rm_eo) || (matches[0].rm_eo != 1)) + { + regfree(&re); + exit(-1); + } + regfree(&re); + printf("no errors found\n"); + return 0; +} + +#else +# error "This library has not been configured for wide character support" +#endif + + + + diff --git a/src/boost/libs/regex/test/c_compiler_checks/wide_posix_api_check.cpp b/src/boost/libs/regex/test/c_compiler_checks/wide_posix_api_check.cpp new file mode 100644 index 00000000..5c14cb22 --- /dev/null +++ b/src/boost/libs/regex/test/c_compiler_checks/wide_posix_api_check.cpp @@ -0,0 +1,102 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE wide_posix_api_compiler_check.c + * VERSION see <boost/version.hpp> + * DESCRIPTION: Verify that POSIX API calls compile: note this is a compile + * time check only. + */ + +#define UNICODE +#define _UNICODE + +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <stdlib.h> +#include <boost/regex.h> +#include <wchar.h> +#include <iostream> +#include <iomanip> + +#ifndef BOOST_NO_WREGEX + +const wchar_t* expression = L"^"; +const wchar_t* text = L"\n "; +regmatch_t matches[1]; +int flags = REG_EXTENDED | REG_BASIC | REG_NOSPEC | REG_ICASE | REG_NOSUB | + REG_NEWLINE | REG_PEND | REG_NOCOLLATE | REG_ESCAPE_IN_LISTS | + REG_NEWLINE_ALT | REG_PERL | REG_AWK | REG_GREP | REG_EGREP; + + +int main() +{ + regex_t re; + unsigned result; + result = regcomp(&re, expression, REG_AWK); + if(result > REG_NOERROR) + { + wchar_t buf[256]; + regerror(result, &re, buf, sizeof(buf)); + char nbuf[256]; + for(int i = 0; i < 256; ++i) + nbuf[i] = static_cast<char>(buf[i]); + printf("%s", nbuf); + return result; + } + if(re.re_nsub != 0) + { + regfree(&re); + exit(-1); + } + matches[0].rm_so = 0; + matches[0].rm_eo = wcslen(text); + result = regexec(&re, text, 1, matches, REG_NOTBOL | REG_NOTEOL | REG_STARTEND); + if(result > REG_NOERROR) + { + wchar_t buf[256]; + regerror(result, &re, buf, sizeof(buf)); + char nbuf[256]; + for(int i = 0; i < 256; ++i) + nbuf[i] = static_cast<char>(buf[i]); + printf("%s", nbuf); + regfree(&re); + return result; + } + if((matches[0].rm_so != matches[0].rm_eo) || (matches[0].rm_eo != 1)) + { + regfree(&re); + exit(-1); + } + regfree(&re); + printf("%s", "no errors found\n"); + return 0; +} + +#else + +#include <iostream> + +int main() +{ + std::cout << + "\n<note>\n" + "This platform does not provide the needed wide character support for this test.\n" + "</note>\n"; + return 0; +} +#endif + + + + diff --git a/src/boost/libs/regex/test/captures/Jamfile.v2 b/src/boost/libs/regex/test/captures/Jamfile.v2 new file mode 100644 index 00000000..f3ee8905 --- /dev/null +++ b/src/boost/libs/regex/test/captures/Jamfile.v2 @@ -0,0 +1,38 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +project + : source-location ../../src + ; + +EX_SOURCES = + c_regex_traits.cpp + cpp_regex_traits.cpp + cregex.cpp + fileiter.cpp + icu.cpp + instances.cpp + posix_api.cpp + regex.cpp + regex_debug.cpp + regex_raw_buffer.cpp + regex_traits_defaults.cpp + static_mutex.cpp + w32_regex_traits.cpp + wc_regex_traits.cpp + wide_posix_api.cpp + winstances.cpp + usinstances.cpp ; + +lib boost_regex_extra : $(EX_SOURCES) ../../build//icu_options + : + <define>BOOST_REGEX_MATCH_EXTRA=1 + <link>shared:<define>BOOST_REGEX_DYN_LINK=1 + : + ; + + + + diff --git a/src/boost/libs/regex/test/captures/captures_test.cpp b/src/boost/libs/regex/test/captures/captures_test.cpp new file mode 100644 index 00000000..641d1b9b --- /dev/null +++ b/src/boost/libs/regex/test/captures/captures_test.cpp @@ -0,0 +1,177 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE captures_test.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Basic tests for additional captures information. + */ + +#include <boost/regex.hpp> +#include <boost/detail/lightweight_main.hpp> +#include "../test_macros.hpp" +#include <boost/array.hpp> +#include <cstring> + +#ifdef BOOST_HAS_ICU +#include <boost/regex/icu.hpp> +#endif + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +template <int N> +size_t array_size(const char* (&p)[N]) +{ + for(size_t i = 0; i < N; ++i) + if(p[i] == 0) + return i; + return N; +} + +std::wstring make_wstring(const char* p) +{ + return std::wstring(p, p + std::strlen(p)); +} + +#ifdef __sgi +template <class T> +void test_captures(const std::string& regx, const std::string& text, const T& expected) +#else +template <class T> +void test_captures(const std::string& regx, const std::string& text, T& expected) +#endif +{ + boost::regex e(regx); + boost::smatch what; + if(boost::regex_match(text, what, e, boost::match_extra)) + { + unsigned i, j; +#ifndef __sgi + // strange type deduction causes this test to fail on SGI: + BOOST_CHECK(what.size() == ARRAY_SIZE(expected)); +#endif + for(i = 0; i < what.size(); ++i) + { + BOOST_CHECK(what.captures(i).size() == array_size(expected[i])); + for(j = 0; j < what.captures(i).size(); ++j) + { + BOOST_CHECK(what.captures(i)[j] == expected[i][j]); + } + } + } + + std::wstring wre(regx.begin(), regx.end()); + std::wstring wtext(text.begin(), text.end()); + boost::wregex we(wre); + boost::wsmatch wwhat; + if(boost::regex_match(wtext, wwhat, we, boost::match_extra)) + { + unsigned i, j; +#ifndef __sgi + // strange type deduction causes this test to fail on SGI: + BOOST_CHECK(wwhat.size() == ARRAY_SIZE(expected)); +#endif + for(i = 0; i < wwhat.size(); ++i) + { + BOOST_CHECK(wwhat.captures(i).size() == array_size(expected[i])); + for(j = 0; j < wwhat.captures(i).size(); ++j) + { + BOOST_CHECK(wwhat.captures(i)[j] == make_wstring(expected[i][j])); + } + } + } + +#ifdef BOOST_HAS_ICU + boost::u32regex ure = boost::make_u32regex(regx); + what = boost::smatch(); + if(boost::u32regex_match(text, what, ure, boost::match_extra)) + { + unsigned i, j; +#ifndef __sgi + // strange type deduction causes this test to fail on SGI: + BOOST_CHECK(what.size() == ARRAY_SIZE(expected)); +#endif + for(i = 0; i < what.size(); ++i) + { + BOOST_CHECK(what.captures(i).size() == array_size(expected[i])); + for(j = 0; j < what.captures(i).size(); ++j) + { + BOOST_CHECK(what.captures(i)[j] == expected[i][j]); + } + } + } +#endif +} + +int cpp_main(int , char* []) +{ + typedef const char* pchar; + pchar e1[4][5] = + { + { "aBBcccDDDDDeeeeeeee", }, + { "a", "BB", "ccc", "DDDDD", "eeeeeeee", }, + { "a", "ccc", "eeeeeeee", }, + { "BB", "DDDDD", }, + }; + test_captures("(([[:lower:]]+)|([[:upper:]]+))+", "aBBcccDDDDDeeeeeeee", e1); + pchar e2[4][2] = + { + { "abd" }, + { "b", "" }, + { "" }, + }; + test_captures("a(b+|((c)*))+d", "abd", e2); + pchar e3[3][1] = + { + { "abcbar" }, + { "abc" }, + }; + test_captures("(.*)bar|(.*)bah", "abcbar", e3); + pchar e4[3][1] = + { + { "abcbah" }, + { 0, }, + { "abc" }, + }; + test_captures("(.*)bar|(.*)bah", "abcbah", e4); + pchar e5[2][16] = + { + { "now is the time for all good men to come to the aid of the party" }, + { "now", "is", "the", "time", "for", "all", "good", "men", "to", "come", "to", "the", "aid", "of", "the", "party" }, + }; + test_captures("^(?:(\\w+)|(?>\\W+))*$", "now is the time for all good men to come to the aid of the party", e5); + pchar e6[2][16] = + { + { "now is the time for all good men to come to the aid of the party" }, + { "now", "is", "the", "time", "for", "all", "good", "men", "to", "come", "to", "the", "aid", "of", "the", "party" }, + }; + test_captures("^(?>(\\w+)\\W*)*$", "now is the time for all good men to come to the aid of the party", e6); + pchar e7[4][14] = + { + { "now is the time for all good men to come to the aid of the party" }, + { "now" }, + { "is", "the", "time", "for", "all", "good", "men", "to", "come", "to", "the", "aid", "of", "the" }, + { "party" }, + }; + test_captures("^(\\w+)\\W+(?>(\\w+)\\W+)*(\\w+)$", "now is the time for all good men to come to the aid of the party", e7); + pchar e8[5][9] = + { + { "now is the time for all good men to come to the aid of the party" } , + { "now" }, + { "is", "for", "men", "to", "of" }, + { "the", "time", "all", "good", "to", "come", "the", "aid", "the" }, + { "party" }, + }; + test_captures("^(\\w+)\\W+(?>(\\w+)\\W+(?:(\\w+)\\W+){0,2})*(\\w+)$", "now is the time for all good men to come to the aid of the party", e8); + return 0; +} + diff --git a/src/boost/libs/regex/test/collate_info/collate_info.cpp b/src/boost/libs/regex/test/collate_info/collate_info.cpp new file mode 100644 index 00000000..da96745c --- /dev/null +++ b/src/boost/libs/regex/test/collate_info/collate_info.cpp @@ -0,0 +1,255 @@ +/* + * + * Copyright (c) 2005 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +// most of the workarounds and headers we need are already in here: +#include <boost/regex.hpp> +#include <boost/regex/v4/primary_transform.hpp> +#include <assert.h> +#include <boost/detail/lightweight_main.hpp> +#include <iostream> +#include <iomanip> + +#ifdef BOOST_INTEL +#pragma warning(disable:1418 981 983 2259) +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ + using ::strxfrm; +#ifndef BOOST_NO_WREGEX + using ::wcsxfrm; +#endif +} +#endif + +#include <iostream> + +template <class charT> +int make_int(charT c) +{ + return c; +} + +int make_int(char c) +{ + return static_cast<unsigned char>(c); +} + +template <class charT> +void print_string(const std::basic_string<charT>& s) +{ + typedef typename std::basic_string<charT>::size_type size_type; + std::cout.put(static_cast<unsigned char>('"')); + for(size_type i = 0; i < s.size(); ++i) + { + if((s[i] > ' ') && (s[i] <= 'z')) + { + std::cout.put(static_cast<unsigned char>(s[i])); + } + else + { + std::cout << "\\x" << std::hex << make_int(s[i]); + } + } + std::cout.put(static_cast<unsigned char>('"')); +} + +void print_c_char(char c) +{ + char buf[50]; + const char cbuf[2] = { c, 0, }; + std::size_t len = std::strxfrm(buf, cbuf, 50); + std:: cout << len << " "; + std::string s(buf); + print_string(s); +} +#ifndef BOOST_NO_WREGEX +void print_c_char(wchar_t c) +{ + wchar_t buf[50]; + const wchar_t cbuf[2] = { c, 0, }; + std::size_t len = std::wcsxfrm(buf, cbuf, 50); + std:: cout << len << " "; + std::wstring s(buf); + print_string(s); +} +#endif +template <class charT> +void print_c_info(charT, const char* name) +{ + std::cout << "Info for " << name << " C API's:" << std::endl; + std::cout << " \"a\" : "; + print_c_char(charT('a')); + std::cout << std::endl; + std::cout << " \"A\" : "; + print_c_char(charT('A')); + std::cout << std::endl; + std::cout << " \"z\" : "; + print_c_char(charT('z')); + std::cout << std::endl; + std::cout << " \"Z\" : "; + print_c_char(charT('Z')); + std::cout << std::endl; + std::cout << " \";\" : "; + print_c_char(charT(';')); + std::cout << std::endl; + std::cout << " \"{\" : "; + print_c_char(charT('{')); + std::cout << std::endl; +} + +template <class charT> +void print_cpp_char(charT c) +{ +#ifndef BOOST_NO_STD_LOCALE + std::locale l; + const std::collate<charT>& col = BOOST_USE_FACET(std::collate<charT>, l); + std::basic_string<charT> result = col.transform(&c, &c+1); + std::cout << result.size() << " "; + print_string(result); + std::size_t n = result.find(charT(0)); + if(n != std::basic_string<charT>::npos) + { + std::cerr << "(Error in location of null, found: " << n << ")"; + } +#endif +} + +template <class charT> +void print_cpp_info(charT, const char* name) +{ + std::cout << "Info for " << name << " C++ locale API's:" << std::endl; + std::cout << " \"a\" : "; + print_cpp_char(charT('a')); + std::cout << std::endl; + std::cout << " \"A\" : "; + print_cpp_char(charT('A')); + std::cout << std::endl; + std::cout << " \"z\" : "; + print_cpp_char(charT('z')); + std::cout << std::endl; + std::cout << " \"Z\" : "; + print_cpp_char(charT('Z')); + std::cout << std::endl; + std::cout << " \";\" : "; + print_cpp_char(charT(';')); + std::cout << std::endl; + std::cout << " \"{\" : "; + print_cpp_char(charT('{')); + std::cout << std::endl; +} + +template <class traits> +void print_sort_syntax(const traits& pt, const char* name) +{ + std::cout << "Sort Key Syntax for type " << name << ":\n"; + typedef typename traits::char_type char_type; + char_type delim; + unsigned result = ::boost::BOOST_REGEX_DETAIL_NS::find_sort_syntax(&pt, &delim); + std::cout << " "; + switch(result) + { + case boost::BOOST_REGEX_DETAIL_NS::sort_C: + std::cout << "sort_C"; + break; + case boost::BOOST_REGEX_DETAIL_NS::sort_fixed: + std::cout << "sort_fixed" << " " << static_cast<int>(delim); + break; + case boost::BOOST_REGEX_DETAIL_NS::sort_delim: + { + std::cout << "sort_delim" << " "; + std::basic_string<char_type> s(1, delim); + print_string(s); + } + break; + case boost::BOOST_REGEX_DETAIL_NS::sort_unknown: + std::cout << "sort_unknown"; + break; + default: + std::cout << "bad_value"; + break; + } + std::cout << std::endl; + + typedef typename traits::string_type string_type; + typedef typename traits::char_type char_type; + + char_type c[5] = { 'a', 'A', ';', '{', '}', }; + for(int i = 0; i < 5; ++i) + { + string_type s(1, c[i]); + string_type sk = pt.transform(s.c_str(), s.c_str() + s.size()); + string_type skp = pt.transform_primary(s.c_str(), s.c_str() + s.size()); + print_string(s); + std::cout << " "; + print_string(sk); + std::cout << " "; + print_string(skp); + std::cout << std::endl; + } +} + +#ifndef BOOST_NO_STD_LOCALE +template <class charT> +void print_ctype_info(charT, const char* name) +{ + std::locale l; + const std::ctype<charT>& ct = BOOST_USE_FACET(std::ctype<charT>, l); + typedef typename std::ctype<charT>::mask mask_type; + mask_type m = static_cast<mask_type>(std::ctype<charT>::lower | std::ctype<charT>::upper); + bool result = ct.is(m, static_cast<charT>('a')) && ct.is(m , static_cast<charT>('A')); + std::cout << "Checking std::ctype<" << name << ">::is(mask, c):" << std::endl; +#ifdef BOOST_REGEX_BUGGY_CTYPE_FACET + std::cout << " Boost.Regex believes this facet to be buggy..." << std::endl; +#else + std::cout << " Boost.Regex believes this facet to be correct..." << std::endl; +#endif + std::cout << " Actual behavior, appears to be " << (result ? "correct." : "buggy.") << std::endl; + assert(ct.is(std::ctype<charT>::alnum, 'a')); + assert(ct.is(std::ctype<charT>::alnum, 'A')); + assert(ct.is(std::ctype<charT>::alnum, '0')); +} +#endif + +int cpp_main(int /*argc*/, char * /*argv*/[]) +{ + print_c_info(char(0), "char"); +#ifndef BOOST_NO_WREGEX + print_c_info(wchar_t(0), "wchar_t"); +#endif + print_cpp_info(char(0), "char"); +#ifndef BOOST_NO_WREGEX + print_cpp_info(wchar_t(0), "wchar_t"); +#endif + +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) + boost::c_regex_traits<char> a; + print_sort_syntax(a, "boost::c_regex_traits<char>"); +#ifndef BOOST_NO_WREGEX + boost::c_regex_traits<wchar_t> b; + print_sort_syntax(b, "boost::c_regex_traits<wchar_t>"); +#endif +#endif +#ifndef BOOST_NO_STD_LOCALE + boost::cpp_regex_traits<char> c; + print_sort_syntax(c, "boost::cpp_regex_traits<char>"); +#ifndef BOOST_NO_WREGEX + boost::cpp_regex_traits<wchar_t> d; + print_sort_syntax(d, "boost::cpp_regex_traits<wchar_t>"); +#endif + print_ctype_info(char(0), "char"); +#ifndef BOOST_NO_WREGEX + print_ctype_info(wchar_t(0), "wchar_t"); +#endif +#endif + return 0; +} + diff --git a/src/boost/libs/regex/test/concepts/concept_check.cpp b/src/boost/libs/regex/test/concepts/concept_check.cpp new file mode 100644 index 00000000..21448f21 --- /dev/null +++ b/src/boost/libs/regex/test/concepts/concept_check.cpp @@ -0,0 +1,105 @@ +/* + * + * Copyright (c) 2003 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include <boost/config.hpp> + +#if defined(BOOST_MSVC) +// this lets us compile at warning level 4 without seeing concept-check related warnings +# pragma warning(disable:4100) +#endif +#ifdef __BORLANDC__ +#pragma option -w-8019 -w-8004 -w-8008 +#endif +#ifdef BOOST_INTEL +#pragma warning(disable:1418 981 983 595 383) +#endif + +#include <boost/regex.hpp> +#include <boost/detail/workaround.hpp> +#if !BOOST_WORKAROUND(_MSC_VER, < 1310) && !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__GNUC__, < 3) +#include <boost/regex/concepts.hpp> +#endif + + +int main() +{ + // VC6 and VC7 can't cope with the iterator architypes, + // don't bother testing as it doesn't work: +#if !BOOST_WORKAROUND(_MSC_VER, < 1310) && !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__GNUC__, < 3) + boost::function_requires< + boost::RegexTraitsConcept< + boost::regex_traits<char> + > + >(); +#ifndef BOOST_NO_STD_LOCALE + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex<char, boost::cpp_regex_traits<char> > + > + >(); +#ifndef BOOST_NO_WREGEX + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex<wchar_t, boost::cpp_regex_traits<wchar_t> > + > + >(); +#endif +#endif +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex<char, boost::c_regex_traits<char> > + > + >(); +#ifndef BOOST_NO_WREGEX + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex<wchar_t, boost::c_regex_traits<wchar_t> > + > + >(); +#endif +#endif +#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex<char, boost::w32_regex_traits<char> > + > + >(); +#ifndef BOOST_NO_WREGEX + boost::function_requires< + boost::BoostRegexConcept< + boost::basic_regex<wchar_t, boost::w32_regex_traits<wchar_t> > + > + >(); +#endif +#endif + // + // now test the regex_traits concepts: + // + typedef boost::basic_regex<char, boost::regex_traits_architype<char> > regex_traits_tester_type1; + boost::function_requires< + boost::BoostRegexConcept< + regex_traits_tester_type1 + > + >(); +#if !defined(__MWERKS__) && !defined(__SUNPRO_CC) // MWCW tries to instantiate std::basic_string<boost::char_architype>, not sure whose bug this is.... + typedef boost::basic_regex<boost::char_architype, boost::regex_traits_architype<boost::char_architype> > regex_traits_tester_type2; + boost::function_requires< + boost::BaseRegexConcept< + regex_traits_tester_type2 + > + >(); +#endif // __MWERKS__ +#endif + return 0; +} + + diff --git a/src/boost/libs/regex/test/concepts/icu_concept_check.cpp b/src/boost/libs/regex/test/concepts/icu_concept_check.cpp new file mode 100644 index 00000000..a55bb387 --- /dev/null +++ b/src/boost/libs/regex/test/concepts/icu_concept_check.cpp @@ -0,0 +1,249 @@ +/* + * + * Copyright (c) 2003 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +// +// This define keep ICU in it's own namespace: helps us to track bugs that would +// otherwise go unnoticed: +// +#define U_USING_ICU_NAMESPACE 0 + +#include <boost/regex/config.hpp> + +#if defined(BOOST_MSVC) +// this lets us compile at warning level 4 without seeing concept-check related warnings +# pragma warning(disable:4100) +#endif +#ifdef __BORLANDC__ +#pragma option -w-8019 -w-8004 -w-8008 +#endif + +#ifdef BOOST_HAS_ICU + +#include <boost/regex/icu.hpp> +#include <boost/detail/workaround.hpp> +#if !BOOST_WORKAROUND(_MSC_VER, < 1310) && !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__GNUC__, < 3) +#include <boost/regex/concepts.hpp> +#endif + +template <class I> +void check_token_iterator(I i) +{ + typedef typename I::value_type value_type; + typedef typename value_type::value_type char_type; + typedef std::basic_string<char_type> string_type; + + I j; + + std::vector<string_type> v; + + while (i != j) + { + v.push_back(i->str()); + ++i; + } + +} + +template <class I> +void check_iterator(I i) +{ + typedef typename I::value_type value_type; + + std::vector <value_type> v(i, I()); + (void)v; + +} +int main() +{ + // VC6 and VC7 can't cope with the iterator architypes, + // don't bother testing as it doesn't work: +#if !BOOST_WORKAROUND(_MSC_VER, < 1310) && !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) && !BOOST_WORKAROUND(__GNUC__, < 3) + boost::function_requires< + boost::RegexTraitsConcept< + boost::icu_regex_traits + > + >(); + boost::function_requires< + boost::BoostRegexConcept< + boost::u32regex + > + >(); + // + // Now test additional function overloads: + // + bool b; + unsigned long buf[2] = { 0, }; + const void* pb = buf; + typedef boost::bidirectional_iterator_archetype<char> utf8_arch1; + typedef boost::bidirectional_iterator_archetype<unsigned char> utf8_arch2; + typedef boost::bidirectional_iterator_archetype<UChar> utf16_arch; + typedef boost::bidirectional_iterator_archetype<wchar_t> wchar_arch; + boost::match_results<utf8_arch1> m1; + boost::match_results<utf8_arch2> m2; + boost::match_results<utf16_arch> m3; + boost::match_results<wchar_arch> m4; + boost::match_results<const char*> cm1; + boost::match_results<const unsigned char*> cm2; + boost::match_results<const UChar*> cm3; + boost::match_results<const wchar_t*> cm4; + boost::match_results<std::string::const_iterator> sm1; + boost::match_results<std::wstring::const_iterator> sm2; + boost::u32regex e1; + boost::regex_constants::match_flag_type flgs = boost::regex_constants::match_default; + std::string s1; + std::wstring s2; + U_NAMESPACE_QUALIFIER UnicodeString us; + b = boost::u32regex_match(utf8_arch1(), utf8_arch1(), m1, e1, flgs); + b = boost::u32regex_match(utf8_arch1(), utf8_arch1(), m1, e1); + b = boost::u32regex_match(utf8_arch2(), utf8_arch2(), m2, e1, flgs); + b = boost::u32regex_match(utf8_arch2(), utf8_arch2(), m2, e1); + b = boost::u32regex_match(utf16_arch(), utf16_arch(), m3, e1, flgs); + b = boost::u32regex_match(utf16_arch(), utf16_arch(), m3, e1); + b = boost::u32regex_match(wchar_arch(), wchar_arch(), m4, e1, flgs); + b = boost::u32regex_match(wchar_arch(), wchar_arch(), m4, e1); + b = boost::u32regex_match((const char*)(pb), cm1, e1, flgs); + b = boost::u32regex_match((const char*)(pb), cm1, e1); + b = boost::u32regex_match((const unsigned char*)(pb), cm2, e1, flgs); + b = boost::u32regex_match((const unsigned char*)(pb), cm2, e1); + b = boost::u32regex_match((const UChar*)(pb), cm3, e1, flgs); + b = boost::u32regex_match((const UChar*)(pb), cm3, e1); + b = boost::u32regex_match((const wchar_t*)(pb), cm4, e1, flgs); + b = boost::u32regex_match((const wchar_t*)(pb), cm4, e1); + b = boost::u32regex_match(s1, sm1, e1, flgs); + b = boost::u32regex_match(s1, sm1, e1); + b = boost::u32regex_match(s2, sm2, e1, flgs); + b = boost::u32regex_match(s2, sm2, e1); + b = boost::u32regex_match(us, cm3, e1, flgs); + b = boost::u32regex_match(us, cm3, e1); + + b = boost::u32regex_search(utf8_arch1(), utf8_arch1(), m1, e1, flgs); + b = boost::u32regex_search(utf8_arch1(), utf8_arch1(), m1, e1); + b = boost::u32regex_search(utf8_arch2(), utf8_arch2(), m2, e1, flgs); + b = boost::u32regex_search(utf8_arch2(), utf8_arch2(), m2, e1); + b = boost::u32regex_search(utf16_arch(), utf16_arch(), m3, e1, flgs); + b = boost::u32regex_search(utf16_arch(), utf16_arch(), m3, e1); + b = boost::u32regex_search(wchar_arch(), wchar_arch(), m4, e1, flgs); + b = boost::u32regex_search(wchar_arch(), wchar_arch(), m4, e1); + b = boost::u32regex_search((const char*)(pb), cm1, e1, flgs); + b = boost::u32regex_search((const char*)(pb), cm1, e1); + b = boost::u32regex_search((const unsigned char*)(pb), cm2, e1, flgs); + b = boost::u32regex_search((const unsigned char*)(pb), cm2, e1); + b = boost::u32regex_search((const UChar*)(pb), cm3, e1, flgs); + b = boost::u32regex_search((const UChar*)(pb), cm3, e1); + b = boost::u32regex_search((const wchar_t*)(pb), cm4, e1, flgs); + b = boost::u32regex_search((const wchar_t*)(pb), cm4, e1); + b = boost::u32regex_search(s1, sm1, e1, flgs); + b = boost::u32regex_search(s1, sm1, e1); + b = boost::u32regex_search(s2, sm2, e1, flgs); + b = boost::u32regex_search(s2, sm2, e1); + b = boost::u32regex_search(us, cm3, e1, flgs); + b = boost::u32regex_search(us, cm3, e1); + boost::output_iterator_archetype<char> out1 = boost::detail::dummy_constructor(); + out1 = boost::u32regex_replace(out1, utf8_arch1(), utf8_arch1(), e1, (const char*)(pb), flgs); + boost::output_iterator_archetype<unsigned char> out2 = boost::detail::dummy_constructor(); + out2 = boost::u32regex_replace(out2, utf8_arch2(), utf8_arch2(), e1, (const unsigned char*)(pb), flgs); + boost::output_iterator_archetype<UChar> out3 = boost::detail::dummy_constructor(); + out3 = boost::u32regex_replace(out3, utf16_arch(), utf16_arch(), e1, (const UChar*)(pb), flgs); + boost::output_iterator_archetype<wchar_t> out4 = boost::detail::dummy_constructor(); + out4 = boost::u32regex_replace(out4, wchar_arch(), wchar_arch(), e1, (const wchar_t*)(pb), flgs); + + out1 = boost::u32regex_replace(out1, utf8_arch1(), utf8_arch1(), e1, s1, flgs); + out2 = boost::u32regex_replace(out2, utf8_arch2(), utf8_arch2(), e1, s1, flgs); + out3 = boost::u32regex_replace(out3, utf16_arch(), utf16_arch(), e1, s1, flgs); + out4 = boost::u32regex_replace(out4, wchar_arch(), wchar_arch(), e1, s1, flgs); + out1 = boost::u32regex_replace(out1, utf8_arch1(), utf8_arch1(), e1, s2, flgs); + out2 = boost::u32regex_replace(out2, utf8_arch2(), utf8_arch2(), e1, s2, flgs); + out3 = boost::u32regex_replace(out3, utf16_arch(), utf16_arch(), e1, s2, flgs); + out4 = boost::u32regex_replace(out4, wchar_arch(), wchar_arch(), e1, s2, flgs); + out1 = boost::u32regex_replace(out1, utf8_arch1(), utf8_arch1(), e1, us, flgs); + out2 = boost::u32regex_replace(out2, utf8_arch2(), utf8_arch2(), e1, us, flgs); + out3 = boost::u32regex_replace(out3, utf16_arch(), utf16_arch(), e1, us, flgs); + out4 = boost::u32regex_replace(out4, wchar_arch(), wchar_arch(), e1, us, flgs); + // string overloads: + s1 = boost::u32regex_replace(s1, e1, (const char*)(pb), flgs); + s2 = boost::u32regex_replace(s2, e1, (const wchar_t*)(pb), flgs); + s1 = boost::u32regex_replace(s1, e1, s1, flgs); + s2 = boost::u32regex_replace(s2, e1, s2, flgs); + s1 = boost::u32regex_replace(s1, e1, (const char*)(pb)); + s2 = boost::u32regex_replace(s2, e1, (const wchar_t*)(pb)); + s1 = boost::u32regex_replace(s1, e1, s1); + s2 = boost::u32regex_replace(s2, e1, s2); + + std::vector<int> subs1; + int subs2[2] = { 1, 2 }; + + check_token_iterator(boost::make_u32regex_token_iterator((const char*)(pb), e1, 0, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const char*)(pb), e1, 0)); + check_token_iterator(boost::make_u32regex_token_iterator((const char*)(pb), e1)); + check_token_iterator(boost::make_u32regex_token_iterator((const UChar*)(pb), e1, 0, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const UChar*)(pb), e1, 0)); + check_token_iterator(boost::make_u32regex_token_iterator((const UChar*)(pb), e1)); + check_token_iterator(boost::make_u32regex_token_iterator((const wchar_t*)(pb), e1, 0, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const wchar_t*)(pb), e1, 0)); + check_token_iterator(boost::make_u32regex_token_iterator((const wchar_t*)(pb), e1)); + check_token_iterator(boost::make_u32regex_token_iterator(s1, e1, 0, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(s1, e1, 0)); + check_token_iterator(boost::make_u32regex_token_iterator(s1, e1)); + check_token_iterator(boost::make_u32regex_token_iterator(s2, e1, 0, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(s2, e1, 0)); + check_token_iterator(boost::make_u32regex_token_iterator(s2, e1)); + check_token_iterator(boost::make_u32regex_token_iterator(us, e1, 0, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(us, e1, 0)); + check_token_iterator(boost::make_u32regex_token_iterator(us, e1)); + + check_token_iterator(boost::make_u32regex_token_iterator((const char*)(pb), e1, subs2, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const char*)(pb), e1, subs2)); + check_token_iterator(boost::make_u32regex_token_iterator((const UChar*)(pb), e1, subs2, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const UChar*)(pb), e1, subs2)); + check_token_iterator(boost::make_u32regex_token_iterator((const wchar_t*)(pb), e1, subs2, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const wchar_t*)(pb), e1, subs2)); + check_token_iterator(boost::make_u32regex_token_iterator(s1, e1, subs2, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(s1, e1, subs2)); + check_token_iterator(boost::make_u32regex_token_iterator(s2, e1, subs2, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(s2, e1, subs2)); + check_token_iterator(boost::make_u32regex_token_iterator(us, e1, subs2, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(us, e1, subs2)); + + check_token_iterator(boost::make_u32regex_token_iterator((const char*)(pb), e1, subs1, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const char*)(pb), e1, subs1)); + check_token_iterator(boost::make_u32regex_token_iterator((const UChar*)(pb), e1, subs1, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const UChar*)(pb), e1, subs1)); + check_token_iterator(boost::make_u32regex_token_iterator((const wchar_t*)(pb), e1, subs1, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator((const wchar_t*)(pb), e1, subs1)); + check_token_iterator(boost::make_u32regex_token_iterator(s1, e1, subs1, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(s1, e1, subs1)); + check_token_iterator(boost::make_u32regex_token_iterator(s2, e1, subs1, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(s2, e1, subs1)); + check_token_iterator(boost::make_u32regex_token_iterator(us, e1, subs1, boost::regex_constants::match_default)); + check_token_iterator(boost::make_u32regex_token_iterator(us, e1, subs1)); + + check_iterator(boost::make_u32regex_iterator((const char*)(pb), e1, boost::regex_constants::match_default)); + check_iterator(boost::make_u32regex_iterator((const char*)(pb), e1)); + check_iterator(boost::make_u32regex_iterator((const UChar*)(pb), e1, boost::regex_constants::match_default)); + check_iterator(boost::make_u32regex_iterator((const UChar*)(pb), e1)); + check_iterator(boost::make_u32regex_iterator((const wchar_t*)(pb), e1, boost::regex_constants::match_default)); + check_iterator(boost::make_u32regex_iterator((const wchar_t*)(pb), e1)); + check_iterator(boost::make_u32regex_iterator(s1, e1, boost::regex_constants::match_default)); + check_iterator(boost::make_u32regex_iterator(s2, e1)); + check_iterator(boost::make_u32regex_iterator(us, e1)); + +#endif + return 0; +} + +#else + +int main() +{ + return 0; +} + +#endif diff --git a/src/boost/libs/regex/test/concepts/range_concept_check.cpp b/src/boost/libs/regex/test/concepts/range_concept_check.cpp new file mode 100644 index 00000000..f6afd700 --- /dev/null +++ b/src/boost/libs/regex/test/concepts/range_concept_check.cpp @@ -0,0 +1,41 @@ +/* +* +* Copyright (c) 2015 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + +#include <boost/regex.hpp> +#include <boost/range/concepts.hpp> + +template <class T> +void use_val(const T&){} + +template <class T> +void check() +{ + BOOST_CONCEPT_ASSERT((boost::ForwardRangeConcept<T>)); + BOOST_CONCEPT_ASSERT((boost_concepts::ReadableIteratorConcept<typename boost::range_iterator<T>::type>)); + BOOST_CONCEPT_ASSERT((boost_concepts::RandomAccessTraversalConcept<typename boost::range_iterator<T>::type>)); + +#ifndef BOOST_NO_CXX11_RANGE_BASED_FOR + const T val; + for(auto item : val) + { + use_val(item); + } +#endif +} + +int main() +{ + check<boost::smatch>(); + check<boost::cmatch>(); + + check <boost::sub_match<const char*> >(); + return 0; +} diff --git a/src/boost/libs/regex/test/concepts/test_bug_11988.cpp b/src/boost/libs/regex/test/concepts/test_bug_11988.cpp new file mode 100644 index 00000000..7376f39a --- /dev/null +++ b/src/boost/libs/regex/test/concepts/test_bug_11988.cpp @@ -0,0 +1,115 @@ +/* +* +* Copyright (c) 2016 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + +#include <boost/config.hpp> + +#ifndef BOOST_NO_CXX11_CHAR32_T + +#include <cstddef> + +namespace boost { + + std::size_t hash_value(char32_t const& c) { return c; } + +} + +#include <boost/regex.hpp> + +struct char32_traits +{ + typedef char32_t char_type; + typedef std::size_t size_type; + typedef std::vector<char32_t> string_type; + typedef int locale_type; // not used + typedef unsigned char_class_type; + + static size_type length(const char32_t* p) + { + size_type result = 0; + while(*p) + { + ++p; + ++result; + } + return result; + } + static char_type translate(char_type c) { return c; } + static char_type translate_nocase(char_type c) { return c; } + static string_type transform(const char32_t* p1, const char32_t* p2) + { + return string_type(p1, p2); + } + static string_type transform_primary(const char32_t* p1, const char32_t* p2) + { + return string_type(p1, p2); + } + static char_class_type lookup_classname(const char32_t* p1, const char32_t* p2) + { + std::string s(p1, p2); + return boost::c_regex_traits<char>::lookup_classname(s.c_str(), s.c_str() + s.length()); + return 0; + } + static string_type lookup_collatename(const char32_t* p1, const char32_t* p2) + { + return string_type(p1, p2); + } + static bool isctype(char_type c, char_class_type t) + { + if(c < 0xff) + return boost::c_regex_traits<char>::isctype(c, t); + return false; + } + static boost::intmax_t value(char_type c, int radix) + { + switch(radix) + { + case 8: + if((c >= '0') && (c <= '7')) + return c - '0'; + break; + case 10: + if((c >= '0') && (c <= '9')) + return c - '0'; + break; + case 16: + if((c >= '0') && (c <= '9')) + return c - '0'; + if((c >= 'a') && (c <= 'f')) + return (c - 'a') + 10; + if((c >= 'A') && (c <= 'F')) + return (c - 'A') + 10; + break; + } + return -1; + } + static locale_type imbue(locale_type) { return 0; } + static locale_type getloc() { return 0; } +}; + + +int main() +{ + char32_t big_char[] = { 0xF, 0xFF, 0xFFF, 0xFFFF, 0xFFFFF, 0xFFFFFF, 0xFFFFFFF, 0xFFFFFFFF, 0 }; + + boost::basic_regex<char32_t, char32_traits> e(U"\\x{F}\\x{FF}\\x{FFF}\\x{FFFF}\\x{FFFFF}\\x{FFFFFF}\\x{FFFFFFF}\\x{FFFFFFFF}"); + + if(!regex_match(big_char, e)) + { + return 1; + } + return 0; +} + +#else + +int main() { return 0; } + +#endif diff --git a/src/boost/libs/regex/test/config_info/regex_config_info.cpp b/src/boost/libs/regex/test/config_info/regex_config_info.cpp new file mode 100644 index 00000000..211e9ec0 --- /dev/null +++ b/src/boost/libs/regex/test/config_info/regex_config_info.cpp @@ -0,0 +1,73 @@ +/* + * + * Copyright (c) 2003 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +// +// This program extends config_info to print out regex library +// configuration information. We do this by redfining the main +// provided by config_info, our real main will call it later: +// +#ifndef OLD_MAIN +# define OLD_MAIN info_main +#endif + +#define main OLD_MAIN +#include <libs/config/test/config_info.cpp> +#undef main +#ifndef NEW_MAIN +# define NEW_MAIN main +#endif +#include <boost/regex.hpp> + +int NEW_MAIN() +{ + OLD_MAIN(); + + print_separator(); + PRINT_MACRO(BOOST_REGEX_USER_CONFIG); + PRINT_MACRO(BOOST_REGEX_USE_C_LOCALE); + PRINT_MACRO(BOOST_REGEX_USE_CPP_LOCALE); + PRINT_MACRO(BOOST_REGEX_HAS_DLL_RUNTIME); + PRINT_MACRO(BOOST_REGEX_DYN_LINK); + PRINT_MACRO(BOOST_REGEX_NO_LIB); + PRINT_MACRO(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE); + PRINT_MACRO(BOOST_REGEX_NO_W32); + PRINT_MACRO(BOOST_REGEX_NO_BOOL); + PRINT_MACRO(BOOST_REGEX_NO_EXTERNAL_TEMPLATES); + PRINT_MACRO(BOOST_REGEX_NO_FWD); + PRINT_MACRO(BOOST_REGEX_V3); + PRINT_MACRO(BOOST_REGEX_HAS_MS_STACK_GUARD); + PRINT_MACRO(BOOST_REGEX_RECURSIVE); + PRINT_MACRO(BOOST_REGEX_NON_RECURSIVE); + PRINT_MACRO(BOOST_REGEX_BLOCKSIZE); + PRINT_MACRO(BOOST_REGEX_MAX_BLOCKS); + PRINT_MACRO(BOOST_REGEX_MAX_CACHE_BLOCKS); + PRINT_MACRO(BOOST_NO_WREGEX); + PRINT_MACRO(BOOST_REGEX_NO_FILEITER); + PRINT_MACRO(BOOST_REGEX_STATIC_LINK); + PRINT_MACRO(BOOST_REGEX_DYN_LINK); + PRINT_MACRO(BOOST_REGEX_DECL); + PRINT_MACRO(BOOST_REGEX_CALL); + PRINT_MACRO(BOOST_REGEX_CCALL); + PRINT_MACRO(BOOST_REGEX_MAX_STATE_COUNT); + PRINT_MACRO(BOOST_REGEX_BUGGY_CTYPE_FACET); + PRINT_MACRO(BOOST_REGEX_MATCH_EXTRA); + PRINT_MACRO(BOOST_HAS_ICU); + PRINT_MACRO(BOOST_REGEX_HAS_OTHER_WCHAR_T); + +#if defined(BOOST_REGEX_CONFIG_INFO) && !defined(NO_RECURSE) + print_regex_library_info(); +#endif + + return 0; +} + + + diff --git a/src/boost/libs/regex/test/de_fuzz/Jamfile.v2 b/src/boost/libs/regex/test/de_fuzz/Jamfile.v2 new file mode 100644 index 00000000..4306ba7c --- /dev/null +++ b/src/boost/libs/regex/test/de_fuzz/Jamfile.v2 @@ -0,0 +1,37 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +import testing ; + +lib Fuzzer : : <search>. ; + +run narrow.cpp [ glob ../../src/*.cpp ] Fuzzer + : # additional args + -dict=dictionary.txt -workers=3 corpus -runs=5000 + : # test-files + : # requirements + <toolset>clang <cxxflags>-fsanitize-coverage=trace-pc-guard + <cxxflags>-fsanitize=address <cxxflags>-fsanitize=undefined + <cxxflags>-fno-sanitize-recover=undefined <cxxflags>-fno-optimize-sibling-calls + <cxxflags>-fno-omit-frame-pointer + <include>../../../.. + <linkflags>-fsanitize=address <linkflags>-fsanitize=undefined + debug +; + +run wide.cpp [ glob ../../src/*.cpp ] Fuzzer + : # additional args + -dict=dictionary.txt -workers=3 corpus -runs=5000 + : # test-files + : # requirements + <toolset>clang <cxxflags>-fsanitize-coverage=trace-pc-guard + <cxxflags>-fsanitize=address <cxxflags>-fsanitize=undefined + <cxxflags>-fno-sanitize-recover=undefined <cxxflags>-fno-optimize-sibling-calls + <cxxflags>-fno-omit-frame-pointer + <include>../../../.. + <linkflags>-fsanitize=address <linkflags>-fsanitize=undefined + debug +; + diff --git a/src/boost/libs/regex/test/de_fuzz/dictionary.txt b/src/boost/libs/regex/test/de_fuzz/dictionary.txt new file mode 100644 index 00000000..bd145050 --- /dev/null +++ b/src/boost/libs/regex/test/de_fuzz/dictionary.txt @@ -0,0 +1,195 @@ + +r1="." +r2="[" +r3="{" +r4="}" +r5="(" +r6=")" +r7="\\" +r8="*" +r9="+" +r10="?" +r11="|" +r12="^" +r13="$" +r14="]" +r15="{4}" +r15="{4,}" +r16="{4, 10}" +r17="*?" +r18="+?" +r19="??" +r20="*+" +r21="++" +r22="?+" +r23="{4}?" +r24="{4,}?" +r25="{4, 10}?" +r26="{4}" +r27="{4,}" +r28="{4, 10}" +r29="\\1" +r30="g1" +r31="g{1}" +r32="g-1" +r33="g{one}" +r34="\\k<one>" +r35="[abc]" +r36="[a-c]" +r36="[^abc]" +r37="[[:alnum:]]" +r38="[[:alpha:]]" +r39="[[:blank:]]" +r40="[[:cntrl:]]" +r41="[[:d:]]" +r42="[[:digit:]]" +r43="[[:grpah:]]" +r44="[[:l:]]" +r45="[[:lower:]]" +r46="[[:print:]]" +r47="[[:punct:]]" +r48="[[:s:]]" +r49="[[:space:]]" +r50="[[:unicode:]]" +r51="[[:u:]]" +r52="[[:upper:]]" +r53="[[:w:]]" +r54="[[:word:]]" +r55="[[:xdigit:]]" +r56="[[:ASCII:]]" +r57="[[:Any:]]" +r58="[[:Assigned:]]" +r59="[[:Other:]]" +r60="[[:Control:]]" +r61="[[:Format:]]" +r62="[[:Not Assigned:]]" +r63="[[:Private Use:]]" +r64="[[:Surrogate:]]" +r65="[[:Letter:]]" +r66="[[:Lowercase Letter:]]" +r67="[[:Modifier Letter:]]" +r68="[[:Other Letter:]]" +r69="[[:Titlecase:]]" +r70="[[:Uppercae Letter:]]" +r71="[[:Mark:]]" +r72="[[:Mc:]]" +r73="[[:Me:]]" +r74="[[:Mn:]]" +r75="[[:N*:]]" +r76="[[:Md:]]" +r77="[[:Nl:]]" +r78="[[:No:]]" +r79="[[:P*:]]" +r80="[[:Pc:]]" +r81="[[:Pd:]]" +r82="[[:Pd:]]" +r83="[[:Pe:]]" +r84="[[:Pf:]]" +r85="[[:Pi:]]" +r86="[[:Po:]]" +r87="[[:Ps:]]" +r88="[[:S*:]]" +r89="[[:Sc:]]" +r90="[[:Sk:]]" +r91="[[:Sm:]]" +r92="[[:So:]]" +r93="[[:Z*:]]" +r94="[[:Zl:]]" +r95="[[:Zp:]]" +r96="[[:Zs:]]" +r98="[[.NUL.]]" +r99="[[.SOH.]]" +r100="[[.alert.]]" +r101="[[=a=]]" +r102="\\a" +r103="\\e" +r104="\\r" +r105="\\n" +r106="\\t" +r107="\\v" +r108="\\b" +r109="\\C9" +r110="\\xcf" +r111="\\x{13}" +r112="\\x{01f4}" +r113="\\0456" +r114="\\N{newline}" +r115="\\d" +r116="\\l" +r117="\\s" +r118="\\u" +r119="\\w" +r120="\\h" +r121="\\v" +r122="\\D" +r123="\\L" +r124="\\S" +r125="\\U" +r126="\\W" +r127="\\H" +r128="\\V" +r129="\\pd" +r130="\\p{digit}" +r131="\\Pd" +r132="\\P{digit}" +r133="\\<" +r134="\\>" +r135="\\b" +r136="\\B" +r137="\\`" +r138="\\'" +r139="\\A" +r140="\\z" +r141="\\Z" +r142="\\G" +r143="\\Q" +r144="\\E" +r145="\\C" +r146="\\R" +r147="\\K" +r148="(?<one>abc)" +r149="(?<one>" +r150="(?'one'abc)" +r151="(?'one'" +r152="(?#annansnsbdgh)" +r153="(?i)" +r154="(?-i)" +r155="(?s)" +r156="(?-s)" +r157="(?m)" +r158="(?-m)" +r153="(?x)" +r154="(?-x)" +r153="(?i:abcd)" +r154="(?-i:abcd)" +r155="(?:" +r156="(?|" +r157="(?=" +r158="(?!" +r159="(?<=" +r160="(?<!" +r170="(>" +r171="(?1)" +r172="(?-1)" +r173="(?+1)" +r174="(?R)" +r175="(?0)" +r176="(?&one)" +r177="(?(?=\\>)" +r178="(?(?!\\>)" +r179="(?(1)" +r180="(?(<one>)" +r181="(?('one')" +r182="(?(R)" +r183="(?(R1)" +r184="(?(R&one)" +r185="(?(DEFINE)" +r186="(*PRUNE)" +r187="(*SKIP)" +r188="(*THEN)" +r189="(*COMMIT)" +r190="(*FAIL)" +r191="(*ACCEPT)" + + + diff --git a/src/boost/libs/regex/test/de_fuzz/narrow.cpp b/src/boost/libs/regex/test/de_fuzz/narrow.cpp new file mode 100644 index 00000000..448c6b78 --- /dev/null +++ b/src/boost/libs/regex/test/de_fuzz/narrow.cpp @@ -0,0 +1,20 @@ + +#include <boost/regex.hpp> + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if(Size < 2) + return 0; + try{ + size_t len = (Data[1] << 8) | Data[0]; + if(len > Size - 2) len = Size - 2; + std::string str((char*)(Data + 2), len); + std::string text((char*)(Data + len), Size - len); + boost::regex e(str); + boost::smatch what; + regex_search(text, what, e, boost::match_default|boost::match_partial); + } + catch(const std::exception&){} + return 0; +} + diff --git a/src/boost/libs/regex/test/de_fuzz/wide.cpp b/src/boost/libs/regex/test/de_fuzz/wide.cpp new file mode 100644 index 00000000..b719adaa --- /dev/null +++ b/src/boost/libs/regex/test/de_fuzz/wide.cpp @@ -0,0 +1,21 @@ + +#include <boost/regex.hpp> + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) +{ + if(Size < 2) + return 0; + std::vector<wchar_t> v(Data, Data + Size); + try{ + size_t len = (Data[1] << 8) | Data[0]; + if(len > Size - 2) len = Size - 2; + std::wstring str(&v[0] + 2, len); + std::wstring text(&v[0] + len, Size - len); + boost::wregex e(str); + boost::wsmatch what; + regex_search(text, what, e, boost::match_default|boost::match_partial); + } + catch(const std::exception&){} + return 0; +} + diff --git a/src/boost/libs/regex/test/named_subexpressions/named_subexpressions_test.cpp b/src/boost/libs/regex/test/named_subexpressions/named_subexpressions_test.cpp new file mode 100644 index 00000000..a92c02b8 --- /dev/null +++ b/src/boost/libs/regex/test/named_subexpressions/named_subexpressions_test.cpp @@ -0,0 +1,112 @@ +/* + * + * Copyright (c) 2009 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include <boost/regex.hpp> +#include <boost/detail/lightweight_main.hpp> +#include "../test_macros.hpp" + +#ifdef BOOST_INTEL +#pragma warning(disable:1418 981 983 383) +#endif + +template <class charT> +void test_named_subexpressions(charT) +{ + // + // Really this is just a test that the overloaded access functions work correctly: + // + static const charT e[] = + { + '(', '?', '\'', 'o', 'n', 'e', '\'', 'a', '+', ')', '(', '?', '<', 't', 'w', 'o', '>', 'b', '+', ')', '\0' + }; + static const charT t[] = + { + 'm', 'm', 'a', 'a', 'a', 'b', 'b', 'n', 'n', '\0' + }; + static const charT one[] = + { + 'o', 'n', 'e', '\0' + }; + static const charT two[] = + { + 't', 'w', 'o', '\0' + }; + static const std::basic_string<charT> s_one(one); + static const std::basic_string<charT> s_two(two); + static const charT result1[] = { 'a', 'a', 'a', '\0' }; + static const charT result2[] = { 'b', 'b', '\0' }; + static const std::basic_string<charT> s_result1(result1); + static const std::basic_string<charT> s_result2(result2); + + static const char* c_one = "one"; + static const char* c_two = "two"; + static const std::string cs_one(c_one); + static const std::string cs_two(c_two); + + boost::basic_regex<charT> expression(e); + boost::match_results<const charT*> what; + if(regex_search(t, what, expression)) + { + BOOST_CHECK(what.length(1) == 3); + BOOST_CHECK(what.length(one) == 3); + BOOST_CHECK(what.length(s_one) == 3); + BOOST_CHECK(what.length(c_one) == 3); + BOOST_CHECK(what.length(cs_one) == 3); + BOOST_CHECK(what.position(1) == 2); + BOOST_CHECK(what.position(one) == 2); + BOOST_CHECK(what.position(s_one) == 2); + BOOST_CHECK(what.position(c_one) == 2); + BOOST_CHECK(what.position(cs_one) == 2); + BOOST_CHECK(what.str(1) == s_result1); + BOOST_CHECK(what.str(one) == s_result1); + BOOST_CHECK(what.str(s_one) == s_result1); + BOOST_CHECK(what.str(c_one) == s_result1); + BOOST_CHECK(what.str(cs_one) == s_result1); + BOOST_CHECK(what[1] == s_result1); + BOOST_CHECK(what[one] == s_result1); + BOOST_CHECK(what[s_one] == s_result1); + BOOST_CHECK(what[c_one] == s_result1); + BOOST_CHECK(what[cs_one] == s_result1); + + BOOST_CHECK(what.length(2) == 2); + BOOST_CHECK(what.length(two) == 2); + BOOST_CHECK(what.length(s_two) == 2); + BOOST_CHECK(what.length(c_two) == 2); + BOOST_CHECK(what.length(cs_two) == 2); + BOOST_CHECK(what.position(2) == 5); + BOOST_CHECK(what.position(two) == 5); + BOOST_CHECK(what.position(s_two) == 5); + BOOST_CHECK(what.position(c_two) == 5); + BOOST_CHECK(what.position(cs_two) == 5); + BOOST_CHECK(what.str(2) == s_result2); + BOOST_CHECK(what.str(two) == s_result2); + BOOST_CHECK(what.str(s_two) == s_result2); + BOOST_CHECK(what.str(c_two) == s_result2); + BOOST_CHECK(what.str(cs_two) == s_result2); + BOOST_CHECK(what[2] == s_result2); + BOOST_CHECK(what[two] == s_result2); + BOOST_CHECK(what[s_two] == s_result2); + BOOST_CHECK(what[c_two] == s_result2); + BOOST_CHECK(what[cs_two] == s_result2); + } + else + { + BOOST_ERROR("Expected match not found"); + } +} + +int cpp_main( int , char* [] ) +{ + test_named_subexpressions(char(0)); + test_named_subexpressions(wchar_t(0)); + return 0; +} + diff --git a/src/boost/libs/regex/test/noeh_test/Jamfile.v2 b/src/boost/libs/regex/test/noeh_test/Jamfile.v2 new file mode 100644 index 00000000..dcaa84b9 --- /dev/null +++ b/src/boost/libs/regex/test/noeh_test/Jamfile.v2 @@ -0,0 +1,50 @@ +# copyright John Maddock 2011 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +project + : requirements + <threading>multi + <link>shared:<define>BOOST_REGEX_DYN_LINK=1 + <toolset>msvc-7.1:<define>TEST_MFC=1 + <toolset>msvc-7.0:<define>TEST_MFC=1 + <toolset>msvc:<asynch-exceptions>on + # There are unidentified linker problems on these platforms: + <toolset>mipspro-7.4:<link>static + <toolset>sun-5.9:<link>static + <warnings>all + <toolset>gcc:<cxxflags>-Wextra + <toolset>gcc:<cxxflags>-Wshadow + <define>U_USING_ICU_NAMESPACE=0 + #<toolset>gcc-mw:<link>static + #<toolset>gcc-mingw:<link>static + <toolset>gcc-cygwin:<link>static + ; + + +lib boost_regex_noeh : + ../../src/c_regex_traits.cpp + ../../src/cpp_regex_traits.cpp + ../../src/cregex.cpp + ../../src/fileiter.cpp + ../../src/icu.cpp + ../../src/instances.cpp + ../../src/posix_api.cpp + ../../src/regex.cpp + ../../src/regex_debug.cpp + ../../src/regex_raw_buffer.cpp + ../../src/regex_traits_defaults.cpp + ../../src/static_mutex.cpp + ../../src/w32_regex_traits.cpp + ../../src/wc_regex_traits.cpp + ../../src/wide_posix_api.cpp + ../../src/winstances.cpp + ../../src/usinstances.cpp + ../../build//icu_options + : + <link>static + <define>BOOST_NO_EXCEPTIONS=1 + <exception-handling>off + : + ;
\ No newline at end of file diff --git a/src/boost/libs/regex/test/object_cache/object_cache_test.cpp b/src/boost/libs/regex/test/object_cache/object_cache_test.cpp new file mode 100644 index 00000000..50d883be --- /dev/null +++ b/src/boost/libs/regex/test/object_cache/object_cache_test.cpp @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE object_cache_test.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Test code for a generic object cache. + */ +#include <boost/regex/pending/object_cache.hpp> +#include <boost/detail/lightweight_main.hpp> +#include "../test_macros.hpp" + +class test_object +{ +public: + test_object(int i) + : m_value(i) + { + ++s_count; + } + int value()const + { + return m_value; + } + static int count() + { + return s_count; + } +private: + int m_value; + static int s_count; +}; + +int test_object::s_count = 0; + +static const int max_cache_size = 5; + +int cpp_main(int /*argc*/, char * /*argv*/[]) +{ + int i; + for(i = 0; i < 20; ++i) + { + boost::shared_ptr<const test_object> p = boost::object_cache<int, test_object>::get(i, max_cache_size); + BOOST_CHECK(p->value() == i); + p = boost::object_cache<int, test_object>::get(i, max_cache_size); + BOOST_CHECK(p->value() == i); + if(i) + { + p = boost::object_cache<int, test_object>::get(i-1, max_cache_size); + BOOST_CHECK(p->value() == i-1); + } + } + int current_count = test_object::count(); + for(int j = 0; j < 10; ++j) + { + for(i = 20 - max_cache_size; i < 20; ++i) + { + boost::shared_ptr<const test_object> p = boost::object_cache<int, test_object>::get(i, max_cache_size); + BOOST_CHECK(p->value() == i); + p = boost::object_cache<int, test_object>::get(i, max_cache_size); + BOOST_CHECK(p->value() == i); + } + } + BOOST_CHECK(current_count == test_object::count()); + return 0; +} + + diff --git a/src/boost/libs/regex/test/pathology/bad_expression_test.cpp b/src/boost/libs/regex/test/pathology/bad_expression_test.cpp new file mode 100644 index 00000000..6e701539 --- /dev/null +++ b/src/boost/libs/regex/test/pathology/bad_expression_test.cpp @@ -0,0 +1,60 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE: recursion_test.cpp + * VERSION: see <boost/version.hpp> + * DESCRIPTION: Test for indefinite recursion and/or stack overrun. + */ + +#include <boost/regex.hpp> +#include <boost/detail/lightweight_main.hpp> +#include "../test_macros.hpp" +#include <string> + +#ifdef BOOST_INTEL +#pragma warning(disable:1418 981 983 383) +#endif + +int cpp_main( int , char* [] ) +{ + std::string bad_text(1024, ' '); + std::string good_text(200, ' '); + good_text.append("xyz"); + + boost::smatch what; + + boost::regex e1("(.+)+xyz"); + + BOOST_CHECK(boost::regex_search(good_text, what, e1)); + BOOST_CHECK_THROW(boost::regex_search(bad_text, what, e1), std::runtime_error); + BOOST_CHECK(boost::regex_search(good_text, what, e1)); + + BOOST_CHECK(boost::regex_match(good_text, what, e1)); + BOOST_CHECK_THROW(boost::regex_match(bad_text, what, e1), std::runtime_error); + BOOST_CHECK(boost::regex_match(good_text, what, e1)); + + boost::regex e2("abc|[[:space:]]+(xyz)?[[:space:]]+xyz"); + + BOOST_CHECK(boost::regex_search(good_text, what, e2)); + BOOST_CHECK_THROW(boost::regex_search(bad_text, what, e2), std::runtime_error); + BOOST_CHECK(boost::regex_search(good_text, what, e2)); + + bad_text.assign((std::string::size_type)500000, 'a'); + e2.assign("aaa*@"); + BOOST_CHECK_THROW(boost::regex_search(bad_text, what, e2), std::runtime_error); + good_text.assign((std::string::size_type)5000, 'a'); + BOOST_CHECK(0 == boost::regex_search(good_text, what, e2)); + + return 0; +} + diff --git a/src/boost/libs/regex/test/pathology/recursion_test.cpp b/src/boost/libs/regex/test/pathology/recursion_test.cpp new file mode 100644 index 00000000..c0438e6e --- /dev/null +++ b/src/boost/libs/regex/test/pathology/recursion_test.cpp @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE: recursion_test.cpp + * VERSION: see <boost/version.hpp> + * DESCRIPTION: Test for indefinite recursion and/or stack overrun. + */ + +#include <boost/regex.hpp> +#include <boost/detail/lightweight_main.hpp> +#include "../test_macros.hpp" +#include <string> + +#ifdef BOOST_INTEL +#pragma warning(disable:1418 981 983 383) +#endif + +int cpp_main( int , char* [] ) +{ + // this regex will recurse twice for each whitespace character matched: + boost::regex e("([[:space:]]|.)+"); + + std::string bad_text(1024*1024*4, ' '); + std::string good_text(200, ' '); + + boost::smatch what; + + // + // Over and over: We want to make sure that after a stack error has + // been triggered, that we can still conduct a good search and that + // subsequent stack failures still do the right thing: + // + BOOST_CHECK(boost::regex_search(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_search(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_search(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_search(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_search(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_search(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_search(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_search(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_search(good_text, what, e)); + + BOOST_CHECK(boost::regex_match(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_match(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_match(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_match(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_match(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_match(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_match(good_text, what, e)); + BOOST_CHECK_THROW(boost::regex_match(bad_text, what, e), std::runtime_error); + BOOST_CHECK(boost::regex_match(good_text, what, e)); + + return 0; +} + diff --git a/src/boost/libs/regex/test/profile/Makefile b/src/boost/libs/regex/test/profile/Makefile new file mode 100644 index 00000000..f1b3def7 --- /dev/null +++ b/src/boost/libs/regex/test/profile/Makefile @@ -0,0 +1,16 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + + +regress : + g++ -fprofile-arcs -ftest-coverage -DBOOST_REGEX_RECURSIVE -DBOOST_REGEX_BLOCKSIZE=512 -DBOOST_REGEX_MAX_CACHE_BLOCKS=0 -DBOOST_REGEX_MATCH_EXTRA -g -I../../../../ -o regress ../regress/*.cpp ../../src/*.cpp ../../../test/src/ex*.cpp ../../../test/src/cpp_main.cpp + ./regress + gcov basic_tests.cpp + + + + + + diff --git a/src/boost/libs/regex/test/quick.cpp b/src/boost/libs/regex/test/quick.cpp new file mode 100644 index 00000000..0598823d --- /dev/null +++ b/src/boost/libs/regex/test/quick.cpp @@ -0,0 +1,55 @@ + +// Copyright 1998-2002 John Maddock +// Copyright 2017 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +// See library home page at http://www.boost.org/libs/regex + +#include <boost/regex.hpp> +#include <boost/core/lightweight_test.hpp> +#include <string> + +bool validate_card_format(const std::string& s) +{ + static const boost::regex e("(\\d{4}[- ]){3}\\d{4}"); + return boost::regex_match(s, e); +} + +const boost::regex card_rx("\\A(\\d{3,4})[- ]?(\\d{4})[- ]?(\\d{4})[- ]?(\\d{4})\\z"); +const std::string machine_format("\\1\\2\\3\\4"); +const std::string human_format("\\1-\\2-\\3-\\4"); + +std::string machine_readable_card_number(const std::string& s) +{ + return boost::regex_replace(s, card_rx, machine_format, boost::match_default | boost::format_sed); +} + +std::string human_readable_card_number(const std::string& s) +{ + return boost::regex_replace(s, card_rx, human_format, boost::match_default | boost::format_sed); +} + +int main() +{ + std::string s[ 4 ] = { "0000111122223333", "0000 1111 2222 3333", "0000-1111-2222-3333", "000-1111-2222-3333" }; + + BOOST_TEST( !validate_card_format( s[0] ) ); + BOOST_TEST_EQ( machine_readable_card_number( s[0] ), s[0] ); + BOOST_TEST_EQ( human_readable_card_number( s[0] ), s[2] ); + + BOOST_TEST( validate_card_format( s[1] ) ); + BOOST_TEST_EQ( machine_readable_card_number( s[1] ), s[0] ); + BOOST_TEST_EQ( human_readable_card_number( s[1] ), s[2] ); + + BOOST_TEST( validate_card_format( s[2] ) ); + BOOST_TEST_EQ( machine_readable_card_number( s[2] ), s[0] ); + BOOST_TEST_EQ( human_readable_card_number( s[2] ), s[2] ); + + BOOST_TEST( !validate_card_format( s[3] ) ); + + return boost::report_errors(); +} diff --git a/src/boost/libs/regex/test/regress/basic_tests.cpp b/src/boost/libs/regex/test/regress/basic_tests.cpp new file mode 100644 index 00000000..25f00c24 --- /dev/null +++ b/src/boost/libs/regex/test/regress/basic_tests.cpp @@ -0,0 +1,212 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE basic_tests.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: main regex test declarations. + */ + +#include <boost/detail/workaround.hpp> + +#if BOOST_WORKAROUND(__BORLANDC__, < 0x560) +// we get unresolved externals from basic_string +// unless we do this, a well known Borland bug: +#define _RWSTD_COMPILE_INSTANTIATE +#endif + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void basic_tests() +{ + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("a", basic, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a", basic, "bba", match_default, make_array(2, 3, -2, -2)); + TEST_REGEX_SEARCH("Z", perl, "aaa", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("Z", perl, "xxxxZZxxx", match_default, make_array(4, 5, -2, 5, 6, -2, -2)); + // and some simple brackets: + TEST_REGEX_SEARCH("(a)", perl, "zzzaazz", match_default, make_array(3, 4, 3, 4, -2, 4, 5, 4, 5, -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_INVALID_REGEX("(", perl); + TEST_INVALID_REGEX("", perl|no_empty_expressions); + TEST_REGEX_SEARCH("", perl, "abc", match_default, make_array(0, 0, -2, 1, 1, -2, 2, 2, -2, 3, 3, -2, -2)); + TEST_INVALID_REGEX(")", perl); + TEST_INVALID_REGEX("(aa", perl); + TEST_INVALID_REGEX("aa)", perl); + TEST_REGEX_SEARCH("a", perl, "b", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\(\\)", perl, "()", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)", perl, "(a)", match_default, make_array(0, 3, -2, -2)); + TEST_INVALID_REGEX("\\()", perl); + TEST_INVALID_REGEX("(\\)", perl); + TEST_REGEX_SEARCH("p(a)rameter", perl, "ABCparameterXYZ", match_default, make_array(3, 12, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("[pq](a)rameter", perl, "ABCparameterXYZ", match_default, make_array(3, 12, 4, 5, -2, -2)); + + // now try escaped brackets: + TEST_REGEX_SEARCH("\\(a\\)", basic, "zzzaazz", match_default, make_array(3, 4, 3, 4, -2, 4, 5, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("\\(\\)", basic, "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("\\(\\)", basic, "", match_default, make_array(0, 0, 0, 0, -2, -2)); + TEST_INVALID_REGEX("\\(", basic); + TEST_INVALID_REGEX("\\)", basic); + TEST_INVALID_REGEX("\\", basic); + TEST_INVALID_REGEX("\\(aa", basic); + TEST_INVALID_REGEX("aa\\)", basic); + TEST_REGEX_SEARCH("()", basic, "()", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("(a)", basic, "(a)", match_default, make_array(0, 3, -2, -2)); + TEST_INVALID_REGEX("\\()", basic); + TEST_INVALID_REGEX("(\\)", basic); + TEST_REGEX_SEARCH("p\\(a\\)rameter", basic, "ABCparameterXYZ", match_default, make_array(3, 12, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("[pq]\\(a\\)rameter", basic, "ABCparameterXYZ", match_default, make_array(3, 12, 4, 5, -2, -2)); + + // now move on to "." wildcards + TEST_REGEX_SEARCH(".", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl, "\n", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl, "\r", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl, "a", match_not_dot_newline, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl, "\n", match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", perl, "\r", match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", perl, "\0", match_not_dot_newline, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl, "\n", match_not_dot_null | match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", perl, "\r", match_not_dot_null | match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", perl, "\0", match_not_dot_null | match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", basic, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", basic, "\n", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", basic, "\r", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", basic, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", basic, "a", match_not_dot_newline, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", basic, "\n", match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", basic, "\r", match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", basic, "\0", match_not_dot_newline, make_array(0, 1, -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, "\0", match_not_dot_null | match_not_dot_newline, make_array(-2, -2)); +} + +void test_non_marking_paren() +{ + using namespace boost::regex_constants; + // + // non-marking parenthesis added 25/04/00 + // + TEST_REGEX_SEARCH("(?:abc)+", perl, "xxabcabcxx", match_default, make_array(2, 8, -2, -2)); + TEST_REGEX_SEARCH("(?:a+)(b+)", perl, "xaaabbbx", match_default, make_array(1, 7, 4, 7, -2, -2)); + TEST_REGEX_SEARCH("(a+)(?:b+)", perl, "xaaabbba", match_default, make_array(1, 7, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("(?:(a+)b+)", perl, "xaaabbba", match_default, make_array(1, 7, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("(?:a+(b+))", perl, "xaaabbba", match_default, make_array(1, 7, 4, 7, -2, -2)); + TEST_REGEX_SEARCH("a+(?#b+)b+", perl, "xaaabbba", match_default, make_array(1, 7, -2, -2)); + TEST_REGEX_SEARCH("(a)(?:b|$)", perl, "ab", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)(?:b|$)", perl, "a", match_default, make_array(0, 1, 0, 1, -2, -2)); +} + +void test_partial_match() +{ + using namespace boost::regex_constants; + // + // try some partial matches: + // + TEST_REGEX_SEARCH("(xyz)(.*)abc", perl, "xyzaaab", match_default|match_partial, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", perl, "xyz", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", perl, "xy", match_default|match_partial, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", perl, "x", match_default|match_partial, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", perl, "", match_default|match_partial, make_array(-2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", perl, "aaaa", match_default|match_partial, make_array(-2, -2)); + TEST_REGEX_SEARCH(".abc", perl, "aaab", match_default|match_partial, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("a[_]", perl, "xxa", match_default|match_partial, make_array(2, 3, -2, -2)); + TEST_REGEX_SEARCH(".{4,}", perl, "xxa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH(".{4,}", perl, "xxa", match_default|match_partial|match_not_dot_null, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("[\\x0-\\xff]{4,}", perl, "xxa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a{4,}", perl, "aaa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\w{4,}", perl, "aaa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH(".*?<tag>", perl, "aaa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a*?<tag>", perl, "aaa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\w*?<tag>", perl, "aaa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(\\w)*?<tag>", perl, "aaa", match_default|match_partial, make_array(0, 3, -2, -2)); + + TEST_REGEX_SEARCH("(xyz)(.*)abc", boost::regex::extended, "xyzaaab", match_default|match_partial, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", boost::regex::extended, "xyz", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", boost::regex::extended, "xy", match_default|match_partial, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", boost::regex::extended, "x", match_default|match_partial, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", boost::regex::extended, "", match_default|match_partial, make_array(-2, -2)); + TEST_REGEX_SEARCH("(xyz)(.*)abc", boost::regex::extended, "aaaa", match_default|match_partial, make_array(-2, -2)); + TEST_REGEX_SEARCH(".abc", boost::regex::extended, "aaab", match_default|match_partial, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("a[_]", boost::regex::extended, "xxa", match_default|match_partial, make_array(2, 3, -2, -2)); + TEST_REGEX_SEARCH(".{4,}", boost::regex::extended, "xxa", match_default|match_partial, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH(".{4,}", boost::regex::extended, "xxa", match_default|match_partial|match_not_dot_null, make_array(0, 3, -2, -2)); +} + +void test_nosubs() +{ + using namespace boost::regex_constants; + // subtleties of matching with no sub-expressions marked + TEST_REGEX_SEARCH("a(b?c)+d", perl, "accd", match_default|match_nosubs, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(wee|week)(knights|night)", perl, "weeknights", match_default|match_nosubs, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH(".*", perl, "abc", match_default|match_nosubs, make_array(0, 3, -2, 3, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl, "abd", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl, "acd", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl, "abbd", match_default|match_nosubs, make_array(0, 4, -2, -2)); + + TEST_REGEX_SEARCH("a(b*|c|e)d", perl, "acd", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl, "ad", match_default|match_nosubs, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", perl, "abc", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", perl, "ac", match_default|match_nosubs, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", perl, "abc", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", perl, "abbbc", match_default|match_nosubs, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c", perl, "ac", match_default|match_nosubs, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("(a|ab)(bc([de]+)f|cde)", perl, "abcdef", match_default|match_nosubs, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", perl, "abc", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", perl, "ac", match_default|match_nosubs, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("a([bc]+)c", perl, "abc", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)c", perl, "abcc", match_default|match_nosubs, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)bc", perl, "abcbc", match_default|match_nosubs, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a(bb+|b)b", perl, "abb", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", perl, "abb", match_default|match_nosubs, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", perl, "abbb", match_default|match_nosubs, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)bb", perl, "abbb", match_default|match_nosubs, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(.*).*", perl, "abcdef", match_default|match_nosubs, make_array(0, 6, -2, 6, 6, -2, -2)); + TEST_REGEX_SEARCH("(a*)*", perl, "bc", match_default|match_nosubs, make_array(0, 0, -2, 1, 1, -2, 2, 2, -2, -2)); + + TEST_REGEX_SEARCH("a(b?c)+d", perl|nosubs, "accd", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(wee|week)(knights|night)", perl|nosubs, "weeknights", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH(".*", perl|nosubs, "abc", match_default, make_array(0, 3, -2, 3, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl|nosubs, "abd", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl|nosubs, "acd", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl|nosubs, "abbd", match_default, make_array(0, 4, -2, -2)); + + TEST_REGEX_SEARCH("a(b*|c|e)d", perl|nosubs, "acd", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl|nosubs, "ad", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", perl|nosubs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", perl|nosubs, "ac", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", perl|nosubs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", perl|nosubs, "abbbc", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c", perl|nosubs, "ac", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("(a|ab)(bc([de]+)f|cde)", perl|nosubs, "abcdef", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", perl|nosubs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", perl|nosubs, "ac", match_default, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("a([bc]+)c", perl|nosubs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)c", perl|nosubs, "abcc", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)bc", perl|nosubs, "abcbc", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a(bb+|b)b", perl|nosubs, "abb", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", perl|nosubs, "abb", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", perl|nosubs, "abbb", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)bb", perl|nosubs, "abbb", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(.*).*", perl|nosubs, "abcdef", match_default, make_array(0, 6, -2, 6, 6, -2, -2)); + TEST_REGEX_SEARCH("(a*)*", perl|nosubs, "bc", match_default, make_array(0, 0, -2, 1, 1, -2, 2, 2, -2, -2)); +} + + diff --git a/src/boost/libs/regex/test/regress/bcb6.mak b/src/boost/libs/regex/test/regress/bcb6.mak new file mode 100644 index 00000000..319ef60b --- /dev/null +++ b/src/boost/libs/regex/test/regress/bcb6.mak @@ -0,0 +1,215 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regress +# +# Borland C++ tools +# +# BCROOT defines the root directory of your bcb install +# +!ifndef BCROOT +BCROOT=$(MAKEDIR)\.. +!endif +# +# sources to compile for each test: +# +SOURCES=*.cpp + +BCC32 = $(BCROOT)\bin\Bcc32.exe +TLINK32 = $(BCROOT)\bin\ILink32.exe + +IDE_LinkFLAGS32 = -L$(BCROOT)\LIB +LINKOPTS= -ap -Tpe -x +CFLAGS= -tWC -DSTRICT; -Vx -Ve -w-inl -w-aus -w-csu -w-eff -w-rch -I$(BCROOT)\include;..\..\..\..\; -L..\..\..\..\stage\lib -L$(BCROOT)\lib\obj -L$(BCROOT)\lib\release -L..\..\build\bcb $(CXXFLAGS) + +BPI= vcl.bpi rtl.bpi vclx.bpi vcle.lib + +BPL= vcl.lib rtl.lib vcle.lib + + +all :: r1.exe r2.exe r3.exe r4.exe r5.exe r6.exe r1m.exe r2m.exe r3m.exe r4m.exe r5m.exe r6m.exe r1v.exe r2v.exe r3v.exe r4v.exe r5v.exe r6v.exe r1l.exe r2l.exe r3l.exe r4l.exe r5l.exe r6l.exe r1lm.exe r2lm.exe r3lm.exe r4lm.exe r5lm.exe r6lm.exe r1lv.exe r2lv.exe r3lv.exe r4lv.exe r5lv.exe r6lv.exe + -copy ..\..\build\bcb6\*.dll + -copy ..\..\..\..\stage\lib\*bcb*.dll + echo testing static single threaded version.... + r1 tests.txt test1252.txt + r2 tests.txt + r3 tests.txt + r4 tests.txt test1252.txt + r5 tests.txt + r6 tests.txt + echo testing static multi-threaded version.... + r1m tests.txt test1252.txt + r2m tests.txt + r3m tests.txt + r4m tests.txt test1252.txt + r5m tests.txt + r6m tests.txt + echo testing static VCL version.... + r1v tests.txt test1252.txt + r2v tests.txt + r3v tests.txt + r4v tests.txt test1252.txt + r5v tests.txt + r6v tests.txt + echo testing dll single threaded version.... + r1l tests.txt test1252.txt + r2l tests.txt + r3l tests.txt + r4l tests.txt test1252.txt + r5l tests.txt + r6l tests.txt + echo testing dll multi-threaded version.... + r1lm tests.txt test1252.txt + r2lm tests.txt + r3lm tests.txt + r4lm tests.txt test1252.txt + r5lm tests.txt + r6lm tests.txt + echo testing dll VCL version.... + r1lv tests.txt test1252.txt + r2lv tests.txt + r3lv tests.txt + r4lv tests.txt test1252.txt + r5lv tests.txt + r6lv tests.txt + + +r1.exe : $(SOURCES) + $(BCC32) -tWM- -D_NO_VCL $(CFLAGS) -er1.exe -DBOOST_RE_TEST_LOCALE_W32 $(SOURCES) + +r2.exe : $(SOURCES) + $(BCC32) -tWM- -D_NO_VCL $(CFLAGS) -er2.exe -DBOOST_RE_TEST_LOCALE_C $(SOURCES) + +r3.exe : $(SOURCES) + $(BCC32) -tWM- -D_NO_VCL $(CFLAGS) -er3.exe -DBOOST_RE_TEST_LOCALE_CPP $(SOURCES) + +r4.exe : $(SOURCES) + $(BCC32) -tWM- -D_NO_VCL $(CFLAGS) -er4.exe -DBOOST_RE_TEST_LOCALE_W32 -DTEST_UNICODE $(SOURCES) + +r5.exe : $(SOURCES) + $(BCC32) -tWM- -D_NO_VCL $(CFLAGS) -er5.exe -DBOOST_RE_TEST_LOCALE_C -DTEST_UNICODE $(SOURCES) + +r6.exe : $(SOURCES) + $(BCC32) -tWM- -D_NO_VCL $(CFLAGS) -er6.exe -DBOOST_RE_TEST_LOCALE_CPP -DTEST_UNICODE $(SOURCES) + + +r1m.exe : $(SOURCES) + $(BCC32) -tWM -D_NO_VCL $(CFLAGS) -er1m.exe -DBOOST_RE_TEST_LOCALE_W32 $(SOURCES) + +r2m.exe : $(SOURCES) + $(BCC32) -tWM -D_NO_VCL $(CFLAGS) -er2m.exe -DBOOST_RE_TEST_LOCALE_C $(SOURCES) + +r3m.exe : $(SOURCES) + $(BCC32) -tWM -D_NO_VCL $(CFLAGS) -er3m.exe -DBOOST_RE_TEST_LOCALE_CPP $(SOURCES) + +r4m.exe : $(SOURCES) + $(BCC32) -tWM -D_NO_VCL $(CFLAGS) -er4m.exe -DBOOST_RE_TEST_LOCALE_W32 -DTEST_UNICODE $(SOURCES) + +r5m.exe : $(SOURCES) + $(BCC32) -tWM -D_NO_VCL $(CFLAGS) -er5m.exe -DBOOST_RE_TEST_LOCALE_C -DTEST_UNICODE $(SOURCES) + +r6m.exe : $(SOURCES) + $(BCC32) -tWM -D_NO_VCL $(CFLAGS) -er6m.exe -DBOOST_RE_TEST_LOCALE_CPP -DTEST_UNICODE $(SOURCES) + + +r1v.exe : $(SOURCES) + $(BCC32) -tWM -tWV $(CFLAGS) -er1v.exe -DBOOST_RE_TEST_LOCALE_W32 $(SOURCES) $(BPL) + +r2v.exe : $(SOURCES) + $(BCC32) -tWM -tWV $(CFLAGS) -er2v.exe -DBOOST_RE_TEST_LOCALE_C $(SOURCES) $(BPL) + +r3v.exe : $(SOURCES) + $(BCC32) -tWM -tWV $(CFLAGS) -er3v.exe -DBOOST_RE_TEST_LOCALE_CPP $(SOURCES) $(BPL) + +r4v.exe : $(SOURCES) + $(BCC32) -tWM -tWV $(CFLAGS) -er4v.exe -DBOOST_RE_TEST_LOCALE_W32 -DTEST_UNICODE $(SOURCES) $(BPL) + +r5v.exe : $(SOURCES) + $(BCC32) -tWM -tWV $(CFLAGS) -er5v.exe -DBOOST_RE_TEST_LOCALE_C -DTEST_UNICODE $(SOURCES) $(BPL) + +r6v.exe : $(SOURCES) + $(BCC32) -tWM -tWV $(CFLAGS) -er6v.exe -DBOOST_RE_TEST_LOCALE_CPP -DTEST_UNICODE $(SOURCES) $(BPL) + + +r1l.exe : $(SOURCES) + $(BCC32) -tWM- -tWR -D_NO_VCL $(CFLAGS) -er1l.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_W32 $(SOURCES) + +r2l.exe : $(SOURCES) + $(BCC32) -tWM- -tWR -D_NO_VCL $(CFLAGS) -er2l.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_C $(SOURCES) + +r3l.exe : $(SOURCES) + $(BCC32) -tWM- -tWR -D_NO_VCL $(CFLAGS) -er3l.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_CPP $(SOURCES) + +r4l.exe : $(SOURCES) + $(BCC32) -tWM- -tWR -D_NO_VCL $(CFLAGS) -er4l.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_W32 -DTEST_UNICODE $(SOURCES) + +r5l.exe : $(SOURCES) + $(BCC32) -tWM- -tWR -D_NO_VCL $(CFLAGS) -er5l.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_C -DTEST_UNICODE $(SOURCES) + +r6l.exe : $(SOURCES) + $(BCC32) -tWM- -tWR -D_NO_VCL $(CFLAGS) -er6l.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_CPP -DTEST_UNICODE $(SOURCES) + + +r1lm.exe : $(SOURCES) + $(BCC32) -tWM -tWR -D_NO_VCL $(CFLAGS) -er1lm.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_W32 $(SOURCES) + +r2lm.exe : $(SOURCES) + $(BCC32) -tWM -tWR -D_NO_VCL $(CFLAGS) -er2lm.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_C $(SOURCES) + +r3lm.exe : $(SOURCES) + $(BCC32) -tWM -tWR -D_NO_VCL $(CFLAGS) -er3lm.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_CPP $(SOURCES) + +r4lm.exe : $(SOURCES) + $(BCC32) -tWM -tWR -D_NO_VCL $(CFLAGS) -er4lm.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_W32 -DTEST_UNICODE $(SOURCES) + +r5lm.exe : $(SOURCES) + $(BCC32) -tWM -tWR -D_NO_VCL $(CFLAGS) -er5lm.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_C -DTEST_UNICODE $(SOURCES) + +r6lm.exe : $(SOURCES) + $(BCC32) -tWM -tWR -D_NO_VCL $(CFLAGS) -er6lm.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_CPP -DTEST_UNICODE $(SOURCES) + + +r1lv.exe : $(SOURCES) + $(BCC32) -tWM -tWR -tWV -tWC $(CFLAGS) -er1lv.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_W32 $(SOURCES) $(BPI) + +r2lv.exe : $(SOURCES) + $(BCC32) -tWM -tWR -tWV -tWC $(CFLAGS) -er2lv.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_C $(SOURCES) $(BPI) + +r3lv.exe : $(SOURCES) + $(BCC32) -tWM -tWR -tWV -tWC $(CFLAGS) -er3lv.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_CPP $(SOURCES) $(BPI) + +r4lv.exe : $(SOURCES) + $(BCC32) -tWM -tWR -tWV -tWC $(CFLAGS) -er4lv.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_W32 -DTEST_UNICODE $(SOURCES) $(BPI) + +r5lv.exe : $(SOURCES) + $(BCC32) -tWM -tWR -tWV -tWC $(CFLAGS) -er5lv.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_C -DTEST_UNICODE $(SOURCES) $(BPI) + +r6lv.exe : $(SOURCES) + $(BCC32) -tWM -tWR -tWV -tWC $(CFLAGS) -er6lv.exe -DBOOST_REGEX_DYN_LINK -DBOOST_RE_TEST_LOCALE_CPP -DTEST_UNICODE $(SOURCES) $(BPI) + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/boost/libs/regex/test/regress/gcc.mak b/src/boost/libs/regex/test/regress/gcc.mak new file mode 100644 index 00000000..83b2ea3b --- /dev/null +++ b/src/boost/libs/regex/test/regress/gcc.mak @@ -0,0 +1,74 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regression tests +# +# g++ 2.95 and greater +# +CXX= g++ $(INCLUDES) -L../../../../stage/lib -I../../../../ -I./ $(CXXFLAGS) -L../../build/gcc $(LDFLAGS) +# +# sources to compile for each test: +# +SOURCES=*.cpp + +total : gcc_regress + export LD_LIBRARY_PATH="../../build/gcc:$LD_LIBRARY_PATH" && ./gcc_regress tests.txt + +gcc_regress : $(SOURCES) + $(CXX) -O2 -o gcc_regress $(SOURCES) ../../build/gcc/libboost_regex-gcc*.a $(LIBS) + +debug : $(SOURCES) + $(CXX) -g -o gcc_regress $(SOURCES) ../../build/gcc/libboost_regex-gcc-d*.a $(LIBS) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/boost/libs/regex/test/regress/info.hpp b/src/boost/libs/regex/test/regress/info.hpp new file mode 100644 index 00000000..5c08961e --- /dev/null +++ b/src/boost/libs/regex/test/regress/info.hpp @@ -0,0 +1,268 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE info.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Error handling for test cases. + */ + +#ifndef BOOST_REGEX_REGRESS_INFO_HPP +#define BOOST_REGEX_REGRESS_INFO_HPP +#include <iostream> +#include <string> +#include <boost/regex.hpp> + +#ifdef TEST_THREADS +#include <boost/thread/once.hpp> +#include <boost/thread.hpp> +#endif + +#ifdef GENERATE_CORPUS +#include <boost/lexical_cast.hpp> +#include <fstream> +// +// class de_fuzz_output +// Generates de-fuzzing corpus files +// +template <class charT> +class de_fuzz_output +{ +public: + de_fuzz_output() {} + template <class U> + void add(const U&, const U&) {} +}; +template<> +class de_fuzz_output<char> +{ + std::set<std::pair<std::string, std::string> > data; +public: + de_fuzz_output() {} + void add(const std::string& re, const std::string& text) + { + data.insert(std::make_pair(re, text)); + } + ~de_fuzz_output() + { + unsigned j = 0; + for(typename std::set<std::pair<std::string, std::string> >::const_iterator i = data.begin(); i != data.end(); ++i) + { + std::string filename = "corpus_" + boost::lexical_cast<std::string>(j); + std::fstream ofs(filename.c_str(), std::ios_base::out | std::ios_base::binary); + ofs.put(static_cast<char>(i->first.size() >> 8)); + ofs.put(static_cast<char>(i->first.size() & 0xff)); + ofs.write(i->first.c_str(), i->first.size()); + ofs.write(i->second.c_str(), i->second.size()); + ++j; + } + } +}; +#endif +// +// class test info, +// store information about the test we are about to conduct: +// +template <class charT> +class test_info_base +{ +public: + typedef std::basic_string<charT> string_type; +private: + struct data_type + { + std::string file; + int line; + string_type expression; + boost::regex_constants::syntax_option_type options; + string_type search_text; + boost::regex_constants::match_flag_type match_options; + const int* answer_table; + string_type format_string; + string_type result_string; + bool need_to_print; + std::string expression_type_name; + }; +#ifdef TEST_THREADS + static data_type& do_get_data() + { + static boost::thread_specific_ptr<data_type> pd; + if(pd.get() == 0) + pd.reset(new data_type()); + return *(pd.get()); + } + static void init_data() + { + do_get_data(); + } +#endif + static data_type& data() + { +#ifdef TEST_THREADS + static boost::once_flag f = BOOST_ONCE_INIT; + boost::call_once(f,&init_data); + return do_get_data(); +#else + static data_type d; + return d; +#endif + } +public: + test_info_base(){}; + static void set_info( + const char* file, + int line, + const string_type& ex, + boost::regex_constants::syntax_option_type opt, + const string_type& search_text = string_type(), + boost::regex_constants::match_flag_type match_options = boost::match_default, + const int* answer_table = 0, + const string_type& format_string = string_type(), + const string_type& result_string = string_type()) + { + data_type& dat = data(); + dat.file = file; + dat.line = line; + dat.expression = ex; + dat.options = opt; + dat.search_text = search_text; + dat.match_options = match_options; + dat.answer_table = answer_table; + dat.format_string = format_string; + dat.result_string = result_string; + dat.need_to_print = true; +#ifdef GENERATE_CORPUS + static de_fuzz_output<charT> corpus; + corpus.add(ex, search_text); +#endif + } + static void set_typename(const std::string& n) + { + data().expression_type_name = n; + } + + static const string_type& expression() + { + return data().expression; + } + static boost::regex_constants::syntax_option_type syntax_options() + { + return data().options; + } + static const string_type& search_text() + { + return data().search_text; + } + static boost::regex_constants::match_flag_type match_options() + { + return data().match_options; + } + static const int* answer_table() + { + return data().answer_table; + } + static const string_type& format_string() + { + return data().format_string; + } + static const string_type& result_string() + { + return data().result_string; + } + static bool need_to_print() + { + return data().need_to_print; + } + static const std::string& file() + { + return data().file; + } + static int line() + { + return data().line; + } + static void clear() + { + data().need_to_print = false; + } + static std::string& expression_typename() + { + return data().expression_type_name; + } +}; + +template <class T> +struct test_info + : public test_info_base<wchar_t> +{}; + +template<> +struct test_info<char> + : public test_info_base<char> +{}; + +#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) + +// Some template instantiation modes (namely local, implicit local, and weak) of +// this compiler need an explicit instantiation because otherwise we end up with +// multiple copies of the static variable defined in this method. This explicit +// instantiation generates the static variable with common linkage, which makes +// the linker choose only one of the available definitions. For more details, +// see "man ld". + +template test_info_base<wchar_t>::data_type & test_info_base<wchar_t>::data(); +template test_info_base<char>::data_type & test_info_base<char>::data(); + +#endif + +template <class charT> +std::ostream& operator<<(std::ostream& os, const test_info<charT>&) +{ + if(test_info<charT>::need_to_print()) + { + os << test_info<charT>::file() << ":" << test_info<charT>::line() << ": Error in test here:" << std::endl; + test_info<charT>::clear(); + } + return os; +} +// +// define some test macros: +// +extern int error_count; + +#define BOOST_REGEX_TEST_ERROR(msg, charT)\ + ++error_count;\ + std::cerr << test_info<charT>();\ + std::cerr << " " << __FILE__ << ":" << __LINE__ << ":" << msg \ + << " (While testing " << test_info<charT>::expression_typename() << ")" << std::endl + +class errors_as_warnings +{ +public: + errors_as_warnings() + { + m_saved_error_count = error_count; + } + ~errors_as_warnings() + { + if(m_saved_error_count != error_count) + { + std::cerr << "<note>The above " << (error_count - m_saved_error_count) << " errors are treated as warnings only.</note>" << std::endl; + error_count = m_saved_error_count; + } + } +private: + int m_saved_error_count; +}; + +#endif + diff --git a/src/boost/libs/regex/test/regress/main.cpp b/src/boost/libs/regex/test/regress/main.cpp new file mode 100644 index 00000000..e3e3dd7f --- /dev/null +++ b/src/boost/libs/regex/test/regress/main.cpp @@ -0,0 +1,239 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE main.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: entry point for test program. + */ + +#include "test.hpp" +#include "test_locale.hpp" +#include <stdarg.h> +#include <iostream> +#include <iomanip> + +#ifdef BOOST_HAS_ICU +#include <unicode/uloc.h> +#endif + +#ifdef TEST_THREADS +#include <list> +#include <boost/thread.hpp> +#include <boost/thread/tss.hpp> +#include <boost/shared_ptr.hpp> +#include <boost/array.hpp> + +int* get_array_data(); + +#endif + +int error_count = 0; + +#ifndef TEST_THREADS +#define RUN_TESTS(name) \ + std::cout << "Running test case \"" #name "\".\n";\ + name(); +#else +#define RUN_TESTS(name) \ + name(); +#endif + + +void run_tests() +{ + RUN_TESTS(basic_tests); + RUN_TESTS(test_simple_repeats); + RUN_TESTS(test_alt); + RUN_TESTS(test_sets); + RUN_TESTS(test_sets2); + RUN_TESTS(test_anchors); + RUN_TESTS(test_backrefs); + RUN_TESTS(test_character_escapes); + RUN_TESTS(test_assertion_escapes); + RUN_TESTS(test_tricky_cases); + RUN_TESTS(test_grep); + RUN_TESTS(test_replace); + RUN_TESTS(test_non_greedy_repeats); + RUN_TESTS(test_non_marking_paren); + RUN_TESTS(test_partial_match); + RUN_TESTS(test_forward_lookahead_asserts); + RUN_TESTS(test_fast_repeats); + RUN_TESTS(test_fast_repeats2); + RUN_TESTS(test_independent_subs); + RUN_TESTS(test_nosubs); + RUN_TESTS(test_conditionals); + RUN_TESTS(test_options); + RUN_TESTS(test_options2); +#ifndef TEST_THREADS + RUN_TESTS(test_en_locale); +#endif + RUN_TESTS(test_emacs); + RUN_TESTS(test_operators); + RUN_TESTS(test_overloads); + RUN_TESTS(test_unicode); + RUN_TESTS(test_pocessive_repeats); + RUN_TESTS(test_mark_resets); + RUN_TESTS(test_recursion); + RUN_TESTS(test_verbs); +} + +int cpp_main(int /*argc*/, char * /*argv*/[]) +{ +#ifdef BOOST_HAS_ICU + // + // We need to set the default locale used by ICU, + // otherwise some of our tests using equivalence classes fail. + // + UErrorCode err = U_ZERO_ERROR; + uloc_setDefault("en", &err); + if(err != U_ZERO_ERROR) + { + std::cerr << "Unable to set the default ICU locale to \"en\"." << std::endl; + return -1; + } +#endif +#ifdef TEST_THREADS + try{ + get_array_data(); // initialises data. + } + catch(const std::exception& e) + { + std::cerr << "TSS Initialisation failed with message: " << e.what() << std::endl; + return -1; + } + + std::list<boost::shared_ptr<boost::thread> > threads; + for(int i = 0; i < 5; ++i) + { + try{ + threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&run_tests))); + } + catch(const std::exception& e) + { + std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl; + } + } + std::list<boost::shared_ptr<boost::thread> >::const_iterator a(threads.begin()), b(threads.end()); + while(a != b) + { + (*a)->join(); + ++a; + } +#else + run_tests(); +#endif + return error_count; +} + +#ifdef TEST_THREADS + +int* get_array_data() +{ + static boost::thread_specific_ptr<boost::array<int, 200> > tp; + + if(tp.get() == 0) + tp.reset(new boost::array<int, 200>); + + return tp.get()->data(); +} + +#endif + +const int* make_array(int first, ...) +{ + // + // this function takes a variable number of arguments + // and packs them into an array that we can pass through + // our testing macros (ideally we would use an array literal + // but these can't apparently be used as macro arguments). + // +#ifdef TEST_THREADS + int* data = get_array_data(); +#else + static int data[200]; +#endif + std::fill_n(data, 200, -2); + va_list ap; + va_start(ap, first); + // + // keep packing args, until we get two successive -2 values: + // + int terminator_count; + int next_position = 1; + data[0] = first; + if(first == -2) + terminator_count = 1; + else + terminator_count = 0; + while(terminator_count < 2) + { + data[next_position] = va_arg(ap, int); + if(data[next_position] == -2) + ++terminator_count; + else + terminator_count = 0; + ++next_position; + } + va_end(ap); + return data; +} + +void test(const char& c, const test_regex_replace_tag& tag) +{ + do_test(c, tag); +} +void test(const char& c, const test_regex_search_tag& tag) +{ + do_test(c, tag); +} +void test(const char& c, const test_invalid_regex_tag& tag) +{ + do_test(c, tag); +} + +#ifndef BOOST_NO_WREGEX +void test(const wchar_t& c, const test_regex_replace_tag& tag) +{ + do_test(c, tag); +} +void test(const wchar_t& c, const test_regex_search_tag& tag) +{ + do_test(c, tag); +} +void test(const wchar_t& c, const test_invalid_regex_tag& tag) +{ + do_test(c, tag); +} +#endif + +#ifdef BOOST_NO_EXCEPTIONS +namespace boost{ + +void throw_exception( std::exception const & e ) +{ + std::cerr << e.what() << std::endl; + std::exit(1); +} + +} + +int main(int argc, char * argv[]) +{ + return cpp_main(argc, argv); +} + +#else + +#include <boost/detail/lightweight_main.hpp> + +#endif diff --git a/src/boost/libs/regex/test/regress/sunpro.mak b/src/boost/libs/regex/test/regress/sunpro.mak new file mode 100644 index 00000000..828a6481 --- /dev/null +++ b/src/boost/libs/regex/test/regress/sunpro.mak @@ -0,0 +1,145 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regression tests +# tests every library combination, static/dynamic/multimthread/singlethread/narrow/wide +# +# Sun Workshop 6 and greater: +# +CXX= CC $(INCLUDES) -I../../../../ -I./ $(CXXFLAGS) -L../../../../stage/lib -L../../build/sunpro $(LDFLAGS) +# +# sources to compile for each test: +# +SOURCES=*.cpp + +total : r rm r/regress rm/regress rs rms rs/regress rms/regress rw rmw rw/regress rmw/regress rsw rmsw rsw/regress rmsw/regress + echo testsing narrow character versions: + ./r/regress tests.txt + ./rm/regress tests.txt + ./rs/regress tests.txt + ./rms/regress tests.txt + echo testsing wide character versions; + ./rw/regress tests.txt + ./rmw/regress tests.txt + ./rsw/regress tests.txt + ./rmsw/regress tests.txt + +# +# delete the cache before each build. +# NB this precludes multithread builds: +# +r/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -o r/regress $(SOURCES) -lboost_regex$(LIBSUFFIX) $(LIBS) + +rm/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -mt -o rm/regress $(SOURCES) -lboost_regex_mt$(LIBSUFFIX) $(LIBS) + +rs/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -o rs/regress $(SOURCES) -Bstatic -lboost_regex$(LIBSUFFIX) -Bdynamic $(LIBS) + +rms/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -mt -o rms/regress $(SOURCES) -Bstatic -lboost_regex_mt$(LIBSUFFIX) -Bdynamic $(LIBS) + +rw/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -DTEST_UNICODE -o rw/regress $(SOURCES) -lboost_regex$(LIBSUFFIX) $(LIBS) + +rmw/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -mt -DTEST_UNICODE -o rmw/regress $(SOURCES) -lboost_regex_mt$(LIBSUFFIX) $(LIBS) + +rsw/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -DTEST_UNICODE -o rsw/regress $(SOURCES) -Bstatic -lboost_regex$(LIBSUFFIX) -Bdynamic $(LIBS) + +rmsw/regress : $(SOURCES) + rm -f *.o + rm -fr SunWS_cache + $(CXX) -O2 -mt -DTEST_UNICODE -o rmsw/regress $(SOURCES) -Bstatic -lboost_regex_mt$(LIBSUFFIX) -Bdynamic $(LIBS) + +r: + mkdir -p r + +rm: + mkdir -p rm + +rs: + mkdir -p rs + +rms: + mkdir -p rms + +rw: + mkdir -p rw + +rmw: + mkdir -p rmw + +rsw: + mkdir -p rsw + +rmsw: + mkdir -p rmsw + +clean: + rm -f *.o + rm -fr SunWS_cache + rm -fr r rm rs rms rw rmw rsw rmsw + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/boost/libs/regex/test/regress/test.hpp b/src/boost/libs/regex/test/regress/test.hpp new file mode 100644 index 00000000..d9224e8e --- /dev/null +++ b/src/boost/libs/regex/test/regress/test.hpp @@ -0,0 +1,293 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Macros for test cases. + */ + + +#ifndef BOOST_REGEX_REGRESS_TEST_HPP +#define BOOST_REGEX_REGRESS_TEST_HPP + +#include <boost/regex.hpp> + +#ifdef BOOST_INTEL +// disable Intel's "remarks": +#pragma warning(disable:1418 981 383 1419 7) +#endif + +#include <typeinfo> +#include "test_not_regex.hpp" +#include "test_regex_search.hpp" +#include "test_regex_replace.hpp" +#include "test_deprecated.hpp" +#include "test_mfc.hpp" +#include "test_icu.hpp" +#include "test_locale.hpp" + +#ifdef TEST_THREADS +#include <boost/thread/once.hpp> +#endif + +// +// define test entry proc, this forwards on to the appropriate +// real test: +// +template <class charT, class tagT> +void do_test(const charT& c, const tagT& tag); + +template <class charT, class tagT> +void test(const charT& c, const tagT& tag) +{ + do_test(c, tag); +} +// +// make these non-templates to speed up compilation times: +// +void test(const char&, const test_regex_replace_tag&); +void test(const char&, const test_regex_search_tag&); +void test(const char&, const test_invalid_regex_tag&); + +#ifndef BOOST_NO_WREGEX +void test(const wchar_t&, const test_regex_replace_tag&); +void test(const wchar_t&, const test_regex_search_tag&); +void test(const wchar_t&, const test_invalid_regex_tag&); +#endif + +template <class Regex> +struct call_once_func +{ + Regex* pregex; + void operator()()const + { + return test_empty(*pregex); + } +}; + +template <class charT, class tagT> +void do_test(const charT& c, const tagT& tag) +{ +#ifndef BOOST_NO_STD_LOCALE +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) && defined(TEST_THREADS) + // typeid appears to fail in multithreaded environments: + test_info<charT>::set_typename(""); +#else + test_info<charT>::set_typename(typeid(boost::basic_regex<charT, boost::cpp_regex_traits<charT> >).name()); +#endif + boost::basic_regex<charT, boost::cpp_regex_traits<charT> > e1; +#ifndef TEST_THREADS + static bool done_empty_test = false; + if(done_empty_test == false) + { + test_empty(e1); + done_empty_test = true; + } +#else + boost::once_flag f = BOOST_ONCE_INIT; + call_once_func<boost::basic_regex<charT, boost::cpp_regex_traits<charT> > > proc = { &e1 }; + boost::call_once(f, proc); +#endif + if(test_locale::cpp_locale_state() == test_locale::test_with_locale) + e1.imbue(test_locale::cpp_locale()); + if(test_locale::cpp_locale_state() != test_locale::no_test) + test(e1, tag); +#endif +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) && defined(TEST_THREADS) + // typeid appears to fail in multithreaded environments: + test_info<charT>::set_typename(""); +#else + test_info<charT>::set_typename(typeid(boost::basic_regex<charT, boost::c_regex_traits<charT> >).name()); +#endif + boost::basic_regex<charT, boost::c_regex_traits<charT> > e2; + if(test_locale::c_locale_state() != test_locale::no_test) + test(e2, tag); +#endif +#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32) +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) && defined(TEST_THREADS) + // typeid appears to fail in multithreaded environments: + test_info<charT>::set_typename(""); +#else + test_info<charT>::set_typename(typeid(boost::basic_regex<charT, boost::w32_regex_traits<charT> >).name()); +#endif + boost::basic_regex<charT, boost::w32_regex_traits<charT> > e3; + if(test_locale::win_locale_state() == test_locale::test_with_locale) + e3.imbue(test_locale::win_locale()); + if(test_locale::win_locale_state() != test_locale::no_test) + test(e3, tag); +#endif + // test old depecated code: + test_info<charT>::set_typename("Deprecated interfaces"); + if((test_locale::win_locale_state() == test_locale::test_no_locale) + && (test_locale::c_locale_state() == test_locale::test_no_locale) + &&(test_locale::cpp_locale_state() == test_locale::test_no_locale)) + test_deprecated(c, tag); + // test MFC/ATL wrappers: + test_info<charT>::set_typename("MFC/ATL interfaces"); + if((test_locale::win_locale_state() == test_locale::test_no_locale) + && (test_locale::c_locale_state() == test_locale::test_no_locale) + &&(test_locale::cpp_locale_state() == test_locale::test_no_locale)) + test_mfc(c, tag); + // test ICU code: + test_info<charT>::set_typename("ICU interfaces"); + test_icu(c, tag); +} + +// +// define function to pack args into an array: +// +const int* make_array(int first, ...); + + +// +// define macros for testing invalid regexes: +// +#define TEST_INVALID_REGEX_N(s, f)\ + do{\ + const char e[] = { s };\ + std::string se(e, sizeof(e) - 1);\ + test_info<char>::set_info(__FILE__, __LINE__, se, f);\ + test(char(0), test_invalid_regex_tag());\ + }while(0) + +#ifndef BOOST_NO_WREGEX +#define TEST_INVALID_REGEX_W(s, f)\ + do{\ + const wchar_t e[] = { s };\ + std::wstring se(e, (sizeof(e) / sizeof(wchar_t)) - 1);\ + test_info<wchar_t>::set_info(__FILE__, __LINE__, se, f);\ + test(wchar_t(0), test_invalid_regex_tag());\ + }while(0) +#else +#define TEST_INVALID_REGEX_W(s, f) +#endif + +#define TEST_INVALID_REGEX(s, f)\ + TEST_INVALID_REGEX_N(s, f);\ + TEST_INVALID_REGEX_W(BOOST_JOIN(L, s), f) + +// +// define macros for testing regex searches: +// +#define TEST_REGEX_SEARCH_N(s, f, t, m, a)\ + do{\ + const char e[] = { s };\ + std::string se(e, sizeof(e) - 1);\ + const char st[] = { t };\ + std::string sst(st, sizeof(st) - 1);\ + test_info<char>::set_info(__FILE__, __LINE__, se, f, sst, m, a);\ + test(char(0), test_regex_search_tag());\ + }while(0) + +#ifndef BOOST_NO_WREGEX +#define TEST_REGEX_SEARCH_W(s, f, t, m, a)\ + do{\ + const wchar_t e[] = { s };\ + std::wstring se(e, (sizeof(e) / sizeof(wchar_t)) - 1);\ + const wchar_t st[] = { t };\ + std::wstring sst(st, (sizeof(st) / sizeof(wchar_t)) - 1);\ + test_info<wchar_t>::set_info(__FILE__, __LINE__, se, f, sst, m, a);\ + test(wchar_t(0), test_regex_search_tag());\ + }while(0) +#else +#define TEST_REGEX_SEARCH_W(s, f, t, m, a) +#endif + +#define TEST_REGEX_SEARCH(s, f, t, m, a)\ + TEST_REGEX_SEARCH_N(s, f, t, m, a);\ + TEST_REGEX_SEARCH_W(BOOST_JOIN(L, s), f, BOOST_JOIN(L, t), m, a) + +#if (defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ >= 4)) +#define TEST_REGEX_SEARCH_L(s, f, t, m, a) TEST_REGEX_SEARCH_W(BOOST_JOIN(L, s), f, BOOST_JOIN(L, t), m, a) +#else +#define TEST_REGEX_SEARCH_L(s, f, t, m, a) TEST_REGEX_SEARCH(s, f, t, m, a) +#endif + +// +// define macros for testing regex replaces: +// +#define TEST_REGEX_REPLACE_N(s, f, t, m, fs, r)\ + do{\ + const char e[] = { s };\ + std::string se(e, sizeof(e) - 1);\ + const char st[] = { t };\ + std::string sst(st, sizeof(st) - 1);\ + const char ft[] = { fs };\ + std::string sft(ft, sizeof(ft) - 1);\ + const char rt[] = { r };\ + std::string srt(rt, sizeof(rt) - 1);\ + test_info<char>::set_info(__FILE__, __LINE__, se, f, sst, m, 0, sft, srt);\ + test(char(0), test_regex_replace_tag());\ + }while(0) + +#ifndef BOOST_NO_WREGEX +#define TEST_REGEX_REPLACE_W(s, f, t, m, fs, r)\ + do{\ + const wchar_t e[] = { s };\ + std::wstring se(e, (sizeof(e) / sizeof(wchar_t)) - 1);\ + const wchar_t st[] = { t };\ + std::wstring sst(st, (sizeof(st) / sizeof(wchar_t)) - 1);\ + const wchar_t ft[] = { fs };\ + std::wstring sft(ft, (sizeof(ft) / sizeof(wchar_t)) - 1);\ + const wchar_t rt[] = { r };\ + std::wstring srt(rt, (sizeof(rt) / sizeof(wchar_t)) - 1);\ + test_info<wchar_t>::set_info(__FILE__, __LINE__, se, f, sst, m, 0, sft, srt);\ + test(wchar_t(0), test_regex_replace_tag());\ + }while(0) +#else +#define TEST_REGEX_REPLACE_W(s, f, t, m, fs, r) +#endif + +#define TEST_REGEX_REPLACE(s, f, t, m, fs, r)\ + TEST_REGEX_REPLACE_N(s, f, t, m, fs, r);\ + TEST_REGEX_REPLACE_W(BOOST_JOIN(L, s), f, BOOST_JOIN(L, t), m, BOOST_JOIN(L, fs), BOOST_JOIN(L, r)) + +// +// 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(); +void test_assertion_escapes(); +void test_tricky_cases(); +void test_grep(); +void test_replace(); +void test_non_greedy_repeats(); +void test_non_marking_paren(); +void test_partial_match(); +void test_forward_lookahead_asserts(); +void test_fast_repeats(); +void test_fast_repeats2(); +void test_tricky_cases2(); +void test_independent_subs(); +void test_nosubs(); +void test_conditionals(); +void test_options(); +void test_options2(); +void test_en_locale(); +void test_emacs(); +void test_operators(); +void test_overloads(); +void test_unicode(); +void test_pocessive_repeats(); +void test_mark_resets(); +void test_recursion(); +void test_verbs(); + +#endif diff --git a/src/boost/libs/regex/test/regress/test_alt.cpp b/src/boost/libs/regex/test/regress/test_alt.cpp new file mode 100644 index 00000000..7eb187fc --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_alt.cpp @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_alt() +{ + using namespace boost::regex_constants; + // now test the alternation operator | + TEST_REGEX_SEARCH("a|b", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a|b", perl, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a|b|c", perl, "c", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a|(b)|.", perl, "b", match_default, make_array(0, 1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)|b|.", perl, "a", match_default, make_array(0, 1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)", perl, "ab", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)", perl, "ac", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)", perl, "ad", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(a|b|c)", perl, "c", match_default, make_array(0, 1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a|(b)|.)", perl, "b", match_default, make_array(0, 1, 0, 1, 0, 1, -2, -2)); + TEST_INVALID_REGEX("|c", perl|no_empty_expressions); + TEST_REGEX_SEARCH("|c", perl, " c", match_default, make_array(0, 0, -2, 1, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_INVALID_REGEX("c|", perl|no_empty_expressions); + TEST_REGEX_SEARCH("c|", perl, " c", match_default, make_array(0, 0, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_INVALID_REGEX("(|)", perl|no_empty_expressions); + TEST_REGEX_SEARCH("(|)", perl, " c", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 2, 2, 2, 2, -2, -2)); + TEST_INVALID_REGEX("(a|)", perl|no_empty_expressions); + TEST_REGEX_SEARCH("(a|)", perl, " a", match_default, make_array(0, 0, 0, 0, -2, 1, 2, 1, 2, -2, 2, 2, 2, 2, -2, -2)); + TEST_INVALID_REGEX("(|a)", perl|no_empty_expressions); + TEST_REGEX_SEARCH("(|a)", perl, " a", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 1, 2, 1, 2, -2, 2, 2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\|", perl, "a|", match_default, make_array(0, 2, -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_REGEX_SEARCH("|", basic, "|", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a|", basic|bk_vbar, "a|", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\|b", basic|bk_vbar, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\|b", basic|bk_vbar, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\nb", grep, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\nb", grep, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\nb", egrep, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\nb", egrep, "a", match_default, make_array(0, 1, -2, -2)); +} + diff --git a/src/boost/libs/regex/test/regress/test_anchors.cpp b/src/boost/libs/regex/test/regress/test_anchors.cpp new file mode 100644 index 00000000..b2aabdfd --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_anchors.cpp @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_anchors() +{ + // line anchors: + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xxabxx", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xx\nabzz", match_default, make_array(3, 5, -2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "abxx", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab\nzz", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "\n\n a", match_default, make_array(-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", boost::regex::extended, "ab", match_default | match_not_bol | match_not_eol, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xxabxx", match_default | match_not_bol | match_not_eol, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xx\nabzz", match_default | match_not_bol | match_not_eol, make_array(3, 5, -2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab", match_default | match_not_bol | match_not_eol, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "abxx", match_default | match_not_bol | match_not_eol, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab\nzz", match_default | match_not_bol | match_not_eol, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "ab", match_default | match_single_line, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xxabxx", match_default | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xx\nabzz", match_default | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab", match_default | match_single_line, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "abxx", match_default | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab\nzz", match_default | match_single_line, make_array(-2, -2)); + + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "ab", match_default | match_not_bol | match_not_eol | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xxabxx", match_default | match_not_bol | match_not_eol | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ab", boost::regex::extended, "xx\nabzz", match_default | match_not_bol | match_not_eol | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab", match_default | match_not_bol | match_not_eol | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "abxx", match_default | match_not_bol | match_not_eol | match_single_line, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab$", boost::regex::extended, "ab\nzz", match_default | match_not_bol | match_not_eol | match_single_line, make_array(-2, -2)); + // + // changes to newline handling with 2.11: + // + TEST_REGEX_SEARCH("^.", boost::regex::extended, " \n \r\n ", match_default, make_array(0, 1, -2, 3, 4, -2, 7, 8, -2, -2)); + TEST_REGEX_SEARCH(".$", boost::regex::extended, " \n \r\n ", match_default, make_array(1, 2, -2, 4, 5, -2, 8, 9, -2, -2)); +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) + TEST_REGEX_SEARCH_W(L"^.", boost::regex::extended, L"\x2028 \x2028", match_default, make_array(0, 1, -2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH_W(L".$", boost::regex::extended, L" \x2028 \x2028", match_default, make_array(0, 1, -2, 2, 3, -2, 3, 4, -2, -2)); +#endif +} + diff --git a/src/boost/libs/regex/test/regress/test_asserts.cpp b/src/boost/libs/regex/test/regress/test_asserts.cpp new file mode 100644 index 00000000..6ec2e450 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_asserts.cpp @@ -0,0 +1,72 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_forward_lookahead_asserts() +{ + // + // forward lookahead asserts added 21/01/02 + // + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("((?:(?!a|b)\\w)+)(\\w+)", perl, " xxxabaxxx ", match_default, make_array(2, 11, 2, 5, 5, 11, -2, -2)); + TEST_REGEX_SEARCH("/\\*(?:(?!\\*/).)*\\*/", perl, " /**/ ", match_default, make_array(2, 6, -2, -2)); + TEST_REGEX_SEARCH("/\\*(?:(?!\\*/).)*\\*/", perl, " /***/ ", match_default, make_array(2, 7, -2, -2)); + TEST_REGEX_SEARCH("/\\*(?:(?!\\*/).)*\\*/", perl, " /********/ ", match_default, make_array(2, 12, -2, -2)); + TEST_REGEX_SEARCH("/\\*(?:(?!\\*/).)*\\*/", perl, " /* comment */ ", match_default, make_array(2, 15, -2, -2)); + TEST_REGEX_SEARCH("<\\s*a[^>]*>((?:(?!<\\s*/\\s*a\\s*>).)*)<\\s*/\\s*a\\s*>", perl, " <a href=\"here\">here</a> ", match_default, make_array(1, 24, 16, 20, -2, -2)); + TEST_REGEX_SEARCH("<\\s*a[^>]*>((?:(?!<\\s*/\\s*a\\s*>).)*)<\\s*/\\s*a\\s*>", perl, " <a href=\"here\">here< / a > ", match_default, make_array(1, 28, 16, 20, -2, -2)); + TEST_REGEX_SEARCH("<\\s*a[^>]*>((?:(?!<\\s*/\\s*a\\s*>).)*)(?=<\\s*/\\s*a\\s*>)", perl, " <a href=\"here\">here</a> ", match_default, make_array(1, 20, 16, 20, -2, -2)); + TEST_REGEX_SEARCH("<\\s*a[^>]*>((?:(?!<\\s*/\\s*a\\s*>).)*)(?=<\\s*/\\s*a\\s*>)", perl, " <a href=\"here\">here< / a > ", match_default, make_array(1, 20, 16, 20, -2, -2)); + TEST_REGEX_SEARCH("^(?!^(?:PRN|AUX|CLOCK\\$|NUL|CON|COM\\d|LPT\\d|\\..*)(?:\\..+)?$)[^\\x00-\\x1f\\\\?*:\"|/]+$", perl, "command.com", match_default, make_array(0, 11, -2, -2)); + TEST_REGEX_SEARCH("^(?!^(?:PRN|AUX|CLOCK\\$|NUL|CON|COM\\d|LPT\\d|\\..*)(?:\\..+)?$)[^\\x00-\\x1f\\\\?*:\"|/]+$", perl, "PRN", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?!^(?:PRN|AUX|CLOCK\\$|NUL|CON|COM\\d|LPT\\d|\\..*)(?:\\..+)?$)[^\\x00-\\x1f\\\\?*:\"|/]+$", perl, "COM2", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?=.*\\d).{4,8}$", perl, "abc3", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^(?=.*\\d).{4,8}$", perl, "abc3def4", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("^(?=.*\\d).{4,8}$", perl, "ab2", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?=.*\\d).{4,8}$", perl, "abcdefg", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", perl, "abc3", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", perl, "abC3", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).{4,8}$", perl, "ABCD3", match_default, make_array(-2, -2)); + + // bug report test cases: + TEST_REGEX_SEARCH("(?=.{1,10}$).*.", perl, "AAAAA", match_default, make_array(0, 5, -2, -2)); + + // lookbehind assertions, added 2004-04-30 + TEST_REGEX_SEARCH("/\\*.*(?<=\\*)/", perl, "/**/", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("/\\*.*(?<=\\*)/", perl, "/*****/ ", match_default, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("(?<=['\"]).*?(?=['\"])", perl, " '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, 7, -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("(?<=", perl); + TEST_INVALID_REGEX("(?<", perl); + TEST_INVALID_REGEX("(?<*", perl); + TEST_INVALID_REGEX("(?", perl); +} + diff --git a/src/boost/libs/regex/test/regress/test_backrefs.cpp b/src/boost/libs/regex/test/regress/test_backrefs.cpp new file mode 100644 index 00000000..58f4dedb --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_backrefs.cpp @@ -0,0 +1,107 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_backrefs() +{ + using namespace boost::regex_constants; + TEST_INVALID_REGEX("a(b)\\2c", perl); + TEST_INVALID_REGEX("a(b\\1)c", perl); + TEST_REGEX_SEARCH("a(b*)c\\1d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\1d", perl, "abbcbd", 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("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)); + TEST_REGEX_SEARCH("a(([bc])\\2)*d", perl, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a((b)*\\2)*d", perl, "abbbd", match_default, make_array(0, 5, 1, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("(ab*)[ab]*\\1", perl, "ababaaa", match_default, make_array(0, 4, 0, 2, -2, 4, 7, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("(a)\\1bcd", perl, "aabcd", match_default, make_array(0, 5, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)\\1bc*d", perl, "aabcd", match_default, make_array(0, 5, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)\\1bc*d", perl, "aabd", match_default, make_array(0, 4, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)\\1bc*d", perl, "aabcccd", match_default, make_array(0, 7, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)\\1bc*[ce]d", perl, "aabcccd", match_default, make_array(0, 7, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^(a)\\1b(c)*cd$", perl, "aabcccd", match_default, make_array(0, 7, 0, 1, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("a\\(b*\\)c\\1d", basic, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a\\(b*\\)c\\1d", basic, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a\\(b*\\)c\\1d", basic, "abbcbbbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^\\(.\\)\\1", basic, "abc", match_default, make_array(-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", basic, "abbccd", match_default, make_array(0, 6, 3, 5, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("a\\(\\([bc]\\)\\2\\)*d", basic, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a\\(\\(b\\)*\\2\\)*d", basic, "abbbd", match_default, make_array(0, 5, 1, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\1bcd", basic, "aabcd", match_default, make_array(0, 5, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\1bc*d", basic, "aabcd", match_default, make_array(0, 5, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\1bc*d", basic, "aabd", match_default, make_array(0, 4, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\1bc*d", basic, "aabcccd", match_default, make_array(0, 7, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\1bc*[ce]d", basic, "aabcccd", match_default, make_array(0, 7, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^\\(a\\)\\1b\\(c\\)*cd$", basic, "aabcccd", match_default, make_array(0, 7, 0, 1, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("\\(ab*\\)[ab]*\\1", basic, "ababaaa", match_default, make_array(0, 7, 0, 1, -2, -2)); + // + // Now test the \g version: + // + TEST_INVALID_REGEX("a(b)\\g2c", perl); + TEST_INVALID_REGEX("a(b\\g1)c", perl); + TEST_INVALID_REGEX("a(b\\g0)c", perl); + TEST_REGEX_SEARCH("a(b*)c\\g1d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g1d", perl, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g1d", perl, "abbcbbbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(.)\\g1", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a([bc])\\g1d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); + TEST_INVALID_REGEX("a(b)\\g{2}c", perl); + TEST_INVALID_REGEX("a(b\\g{1})c", perl); + TEST_INVALID_REGEX("a(b\\g{0})c", perl); + TEST_REGEX_SEARCH("a(b*)c\\g{1}d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g{1}d", perl, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g{1}d", perl, "abbcbbbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(.)\\g{1}", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a([bc])\\g{1}d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); + // And again but with negative indexes: + TEST_INVALID_REGEX("a(b)\\g-2c", perl); + TEST_INVALID_REGEX("a(b\\g-1)c", perl); + TEST_INVALID_REGEX("a(b\\g-0)c", perl); + TEST_REGEX_SEARCH("a(b*)c\\g-1d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g-1d", perl, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g-1d", perl, "abbcbbbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(.)\\g1", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a([bc])\\g1d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); + TEST_INVALID_REGEX("a(b)\\g{-2}c", perl); + TEST_INVALID_REGEX("a(b\\g{-1})c", perl); + TEST_REGEX_SEARCH("a(b*)c\\g{-1}d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g{-1}d", perl, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(b*)c\\g{-1}d", perl, "abbcbbbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(.)\\g{-1}", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a([bc])\\g{-1}d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); + + // And again but with named subexpressions: + TEST_REGEX_SEARCH("a(?<foo>(?<bar>(?<bb>(?<aa>b*))))c\\g{foo}d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, 1, 3, 1, 3, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(?<foo>(?<bar>(?<bb>(?<aa>b*))))c\\g{foo}d", perl, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(?<foo>(?<bar>(?<bb>(?<aa>b*))))c\\g{foo}d", perl, "abbcbbbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?<foo>.)\\g{foo}", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(?<foo>[bc])\\g{foo}d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); + + TEST_REGEX_SEARCH("a(?'foo'(?'bar'(?'bb'(?'aa'b*))))c\\g{foo}d", perl, "abbcbbd", match_default, make_array(0, 7, 1, 3, 1, 3, 1, 3, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(?'foo'(?'bar'(?'bb'(?'aa'b*))))c\\g{foo}d", perl, "abbcbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(?'foo'(?'bar'(?'bb'(?'aa'b*))))c\\g{foo}d", perl, "abbcbbbd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?'foo'.)\\g{foo}", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(?'foo'[bc])\\g{foo}d", perl, "abcdabbd", match_default, make_array(4, 8, 5, 6, -2, -2)); +} + diff --git a/src/boost/libs/regex/test/regress/test_deprecated.cpp b/src/boost/libs/regex/test/regress/test_deprecated.cpp new file mode 100644 index 00000000..493c02b2 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_deprecated.cpp @@ -0,0 +1,386 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_deprecated.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Tests for deprecated interfaces. + */ + +#include "test.hpp" +#include <boost/cregex.hpp> + +#ifdef BOOST_MSVC +#pragma warning(disable:4267) +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ + using ::atoi; + using ::wcstol; +} +#endif + +int get_posix_compile_options(boost::regex_constants::syntax_option_type opts) +{ + using namespace boost; + int result = 0; + switch(opts & regbase::main_option_type) + { + case regbase::perl: + result = (opts & regbase::no_perl_ex) ? REG_EXTENDED : REG_PERL; + if(opts & (regbase::no_bk_refs|regbase::no_mod_m|regbase::mod_x|regbase::mod_s|regbase::no_mod_s|regbase::no_escape_in_lists|regbase::no_empty_expressions)) + return -1; + break; + case regbase::basic: + result = REG_BASIC; + if(opts & (regbase::no_char_classes|regbase::no_intervals|regbase::bk_plus_qm|regbase::bk_vbar)) + return -1; + if((opts & regbase::no_escape_in_lists) == 0) + return -1; + break; + default: + return -1; + } + + if(opts & regbase::icase) + result |= REG_ICASE; + if(opts & regbase::nosubs) + result |= REG_NOSUB; + if(opts & regbase::newline_alt) + result |= REG_NEWLINE; + if((opts & regbase::collate) == 0) + result |= REG_NOCOLLATE; + + return result; +} + +int get_posix_match_flags(boost::regex_constants::match_flag_type f) +{ + int result = 0; + if(f & boost::regex_constants::match_not_bol) + result |= boost::REG_NOTBOL; + if(f & boost::regex_constants::match_not_eol) + result |= boost::REG_NOTEOL; + if(f & ~(boost::regex_constants::match_not_bol|boost::regex_constants::match_not_eol)) + return -1; + return result; +} + +void test_deprecated(const char&, const test_regex_search_tag&) +{ + const std::string& expression = test_info<char>::expression(); + if(expression.find('\0') != std::string::npos) + return; + const std::string& search_text = test_info<char>::search_text(); + if(search_text.find('\0') != std::string::npos) + return; + int posix_options = get_posix_compile_options(test_info<char>::syntax_options()); + if(posix_options < 0) + return; + int posix_match_options = get_posix_match_flags(test_info<char>::match_options()); + if(posix_match_options < 0) + return; + const int* results = test_info<char>::answer_table(); + + // OK try and compile the expression: + boost::regex_tA re; + if(boost::regcompA(&re, expression.c_str(), posix_options) != 0) + { + BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" did not compile with the POSIX C API.", char); + return; + } + // try and find the first occurance: + static const unsigned max_subs = 100; + boost::regmatch_t matches[max_subs]; + if(boost::regexecA(&re, search_text.c_str(), max_subs, matches, posix_match_options) == 0) + { + int i = 0; + while(results[2*i] != -2) + { + if((int)max_subs > i) + { + if(results[2*i] != matches[i].rm_so) + { + BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the POSIX C API.", char); + } + if(results[2*i+1] != matches[i].rm_eo) + { + BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the POSIX C API.", char); + } + } + ++i; + } + } + else + { + if(results[0] >= 0) + { + BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" was not found with the POSIX C API.", char); + } + } + // clean up whatever: + boost::regfreeA(&re); + + // + // now try the RegEx class: + // + if(test_info<char>::syntax_options() & ~boost::regex::icase) + return; +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { + boost::RegEx e(expression, (test_info<char>::syntax_options() & boost::regex::icase) != 0); + if(e.error_code()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << e.error_code(), char); + } + if(e.Search(search_text, test_info<char>::match_options())) + { + int i = 0; + while(results[i*2] != -2) + { + if(e.Matched(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); + } + 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); + } + } + else + { + if(results[2*i] >= 0) + { + 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] >= 0) + { + 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); + } + } + ++i; + } + } + else + { + if(results[0] >= 0) + { + BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" was not found with class RegEx.", char); + } + } + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression& r) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile with RegEx class: " << r.what(), char); + } + catch(const std::runtime_error& r) + { + BOOST_REGEX_TEST_ERROR("Unexpected std::runtime_error : " << r.what(), char); + } + catch(const std::exception& r) + { + BOOST_REGEX_TEST_ERROR("Unexpected std::exception: " << r.what(), char); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Unexpected exception of unknown type", char); + } +#endif +} + +void test_deprecated(const wchar_t&, const test_regex_search_tag&) +{ +#ifndef BOOST_NO_WREGEX + const std::wstring& expression = test_info<wchar_t>::expression(); + if(expression.find(L'\0') != std::wstring::npos) + return; + const std::wstring& search_text = test_info<wchar_t>::search_text(); + if(search_text.find(L'\0') != std::wstring::npos) + return; + int posix_options = get_posix_compile_options(test_info<wchar_t>::syntax_options()); + if(posix_options < 0) + return; + int posix_match_options = get_posix_match_flags(test_info<wchar_t>::match_options()); + if(posix_match_options < 0) + return; + const int* results = test_info<wchar_t>::answer_table(); + + // OK try and compile the expression: + boost::regex_tW re; + if(boost::regcompW(&re, expression.c_str(), posix_options) != 0) + { + BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" did not compile with the POSIX C API.", wchar_t); + return; + } + // try and find the first occurance: + static const unsigned max_subs = 100; + boost::regmatch_t matches[max_subs]; + if(boost::regexecW(&re, search_text.c_str(), max_subs, matches, posix_match_options) == 0) + { + int i = 0; + while(results[2*i] != -2) + { + if((int)max_subs > i) + { + if(results[2*i] != matches[i].rm_so) + { + BOOST_REGEX_TEST_ERROR("Mismatch in start of subexpression " << i << " found with the POSIX C API.", wchar_t); + } + if(results[2*i+1] != matches[i].rm_eo) + { + BOOST_REGEX_TEST_ERROR("Mismatch in end of subexpression " << i << " found with the POSIX C API.", wchar_t); + } + } + ++i; + } + } + else + { + if(results[0] >= 0) + { + BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" was not found with the POSIX C API.", wchar_t); + } + } + // clean up whatever: + boost::regfreeW(&re); +#endif +} + +void test_deprecated(const char&, const test_invalid_regex_tag&) +{ + const std::string& expression = test_info<char>::expression(); + if(expression.find('\0') != std::string::npos) + return; + int posix_options = get_posix_compile_options(test_info<char>::syntax_options()); + if(posix_options < 0) + return; + + // OK try and compile the expression: + boost::regex_tA re; + int code = boost::regcompA(&re, expression.c_str(), posix_options); + if(code == 0) + { + boost::regfreeA(&re); + BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" unexpectedly compiled with the POSIX C API.", char); + } + else + { + char buf[100]; + int s = boost::regerrorA(code, &re, 0, 0); + if(s < 100) + s = boost::regerrorA(code, &re, buf, 100); + s = boost::regerrorA(code | boost::REG_ITOA, &re, 0, 0); + if(s < 100) + { + s = boost::regerrorA(code | boost::REG_ITOA, &re, buf, 100); + re.re_endp = buf; + s = boost::regerrorA(code | boost::REG_ATOI, &re, buf, 100); + if(s) + { + int code2 = std::atoi(buf); + if(code2 != code) + { + BOOST_REGEX_TEST_ERROR("Got a bad error code from regerrA with REG_ATOI set: ", char); + } + } + } + } + // + // now try the RegEx class: + // + if(test_info<char>::syntax_options() & ~boost::regex::icase) + return; + bool have_catch = false; +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { + boost::RegEx e(expression, (test_info<char>::syntax_options() & boost::regex::icase) != 0); + if(e.error_code()) + have_catch = true; + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression&) + { + have_catch = true; + } + catch(const std::runtime_error& r) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << r.what(), char); + } + catch(const std::exception& r) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << r.what(), char); + } + catch(...) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", char); + } +#endif + if(!have_catch) + { + // oops expected exception was not thrown: + BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", char); + } +} + +void test_deprecated(const wchar_t&, const test_invalid_regex_tag&) +{ +#ifndef BOOST_NO_WREGEX + const std::wstring& expression = test_info<wchar_t>::expression(); + if(expression.find(L'\0') != std::string::npos) + return; + int posix_options = get_posix_compile_options(test_info<wchar_t>::syntax_options()); + if(posix_options < 0) + return; + + // OK try and compile the expression: + boost::regex_tW re; + int code = boost::regcompW(&re, expression.c_str(), posix_options); + if(code == 0) + { + boost::regfreeW(&re); + BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" unexpectedly compiled with the POSIX C API.", wchar_t); + } + else + { + wchar_t buf[100]; + int s = boost::regerrorW(code, &re, 0, 0); + if(s < 100) + s = boost::regerrorW(code, &re, buf, 100); + s = boost::regerrorW(code | boost::REG_ITOA, &re, 0, 0); + if(s < 100) + { + s = boost::regerrorW(code | boost::REG_ITOA, &re, buf, 100); + re.re_endp = buf; + s = boost::regerrorW(code | boost::REG_ATOI, &re, buf, 100); + if(s) + { + long code2 = std::wcstol(buf, 0, 10); + if(code2 != code) + { + BOOST_REGEX_TEST_ERROR("Got a bad error code from regerrW with REG_ATOI set: ", char); + } + } + } + } +#endif +} diff --git a/src/boost/libs/regex/test/regress/test_deprecated.hpp b/src/boost/libs/regex/test/regress/test_deprecated.hpp new file mode 100644 index 00000000..dc059506 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_deprecated.hpp @@ -0,0 +1,35 @@ +/* + * + * Copyright (c) 1998-2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_deprecated.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Forward declare deprecated test functions. + */ + +#ifndef BOOST_REGEX_TEST_DEPRECATED +#define BOOST_REGEX_TEST_DEPRECATED + +template <class charT, class Tag> +void test_deprecated(const charT&, const Tag&) +{ + // do nothing +} + +void test_deprecated(const char&, const test_regex_search_tag&); +void test_deprecated(const wchar_t&, const test_regex_search_tag&); +void test_deprecated(const char&, const test_invalid_regex_tag&); +void test_deprecated(const wchar_t&, const test_invalid_regex_tag&); + + +#endif + diff --git a/src/boost/libs/regex/test/regress/test_emacs.cpp b/src/boost/libs/regex/test/regress/test_emacs.cpp new file mode 100644 index 00000000..c91478c1 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_emacs.cpp @@ -0,0 +1,166 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_emacs2(); + +void test_emacs() +{ + using namespace boost::regex_constants; + // now try operator + : + TEST_REGEX_SEARCH("ab+", emacs, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab+", emacs, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab+", emacs, "sssabbbbbbsss", match_default, make_array(3, 10, -2, -2)); + TEST_REGEX_SEARCH("ab+c+", emacs, "abbb", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab+c+", emacs, "accc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab+c+", emacs, "abbcc", match_default, make_array(0, 5, -2, -2)); + TEST_INVALID_REGEX("\\<+", emacs); + TEST_INVALID_REGEX("\\>+", emacs); + TEST_REGEX_SEARCH("\n+", emacs, "\n\n", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\+", emacs, "+", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\+", emacs, "++", match_default, make_array(0, 1, -2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\++", emacs, "++", match_default, make_array(0, 2, -2, -2)); + + // now try operator ? + TEST_REGEX_SEARCH("a?", emacs, "b", match_default, make_array(0, 0, -2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("ab?", emacs, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("ab?", emacs, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab?", emacs, "sssabbbbbbsss", match_default, make_array(3, 5, -2, -2)); + TEST_REGEX_SEARCH("ab?c?", emacs, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("ab?c?", emacs, "abbb", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab?c?", emacs, "accc", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab?c?", emacs, "abcc", match_default, make_array(0, 3, -2, -2)); + TEST_INVALID_REGEX("\\<?", emacs); + TEST_INVALID_REGEX("\\>?", emacs); + TEST_REGEX_SEARCH("\n?", emacs, "\n\n", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("\\?", emacs, "?", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\?", emacs, "?", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\??", emacs, "??", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + + TEST_REGEX_SEARCH("a*?", emacs, "aa", match_default, make_array(0, 0, -2, 0, 1, -2, 1, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("^a*?$", emacs, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^.*?$", emacs, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^\\(a\\)*?$", emacs, "aa", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("^[ab]*?$", emacs, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a??", emacs, "aa", match_default, make_array(0, 0, -2, 0, 1, -2, 1, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("a+?", emacs, "aa", match_default, make_array(0, 1, -2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\{1,3\\}?", emacs, "aaa", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("\\w+?w", emacs, "...ccccccwcccccw", match_default, make_array(3, 10, -2, 10, 16, -2, -2)); + TEST_REGEX_SEARCH("\\W+\\w+?w", emacs, "...ccccccwcccccw", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH("abc\\|\\w+?", emacs, "abd", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\|\\w+?", emacs, "abcd", match_default, make_array(0, 3, -2, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("<\\ss*tag[^>]*>\\(.*?\\)<\\ss*/tag\\ss*>", emacs, " <tag>here is some text</tag> <tag></tag>", match_default, make_array(1, 29, 6, 23, -2, 30, 41, 35, 35, -2, -2)); + TEST_REGEX_SEARCH("<\\ss*tag[^>]*>\\(.*?\\)<\\ss*/tag\\ss*>", emacs, " < tag attr=\"something\">here is some text< /tag > <tag></tag>", match_default, make_array(1, 49, 24, 41, -2, 50, 61, 55, 55, -2, -2)); + TEST_INVALID_REGEX("a\\{1,3\\}\\{1\\}", emacs); + TEST_INVALID_REGEX("a**", emacs); + TEST_INVALID_REGEX("a++", emacs); + + TEST_REGEX_SEARCH("\\<abcd", emacs, " abcd", match_default, make_array(2, 6, -2, -2)); + TEST_REGEX_SEARCH("\\<ab", emacs, "cab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<ab", emacs, "\nab", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\<tag", emacs, "::tag", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\<abcd", emacs, "abcd", match_default|match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<abcd", emacs, " abcd", match_default|match_not_bow, make_array(2, 6, -2, -2)); + TEST_REGEX_SEARCH("\\<", emacs, "ab ", match_default|match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH(".\\<.", emacs, "ab", match_default|match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH(".\\<.", emacs, " b", match_default|match_not_bow, make_array(0, 2, -2, -2)); + // word end: + TEST_REGEX_SEARCH("abc\\>", emacs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\>", emacs, "abcd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\>", emacs, "abc\n", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\>", emacs, "abc::", match_default, make_array(0,3, -2, -2)); + TEST_REGEX_SEARCH("abc\\(?:\\>..\\|$\\)", emacs, "abc::", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("\\>", emacs, " ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH(".\\>.", emacs, " ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\>", emacs, "abc", match_default|match_not_eow, make_array(-2, -2)); + // word boundary: + TEST_REGEX_SEARCH("\\babcd", emacs, " abcd", match_default, make_array(2, 6, -2, -2)); + TEST_REGEX_SEARCH("\\bab", emacs, "cab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\bab", emacs, "\nab", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\btag", emacs, "::tag", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("abc\\b", emacs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\b", emacs, "abcd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\b", emacs, "abc\n", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\b", emacs, "abc::", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\babcd", emacs, "abcd", match_default|match_not_bow, make_array(-2, -2)); + // within word: + TEST_REGEX_SEARCH("\\B", emacs, "ab", match_default, make_array(1, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\Bb", emacs, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\B", emacs, "ab", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\B", emacs, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a\\B", emacs, "a ", match_default, make_array(-2, -2)); + // buffer operators: + TEST_REGEX_SEARCH("\\`abc", emacs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\`abc", emacs, "\nabc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\`abc", emacs, " abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\'", emacs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\'", emacs, "abc\n", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\'", emacs, "abc ", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("a\\|b", emacs, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\|b", emacs, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\|b\\|c", emacs, "c", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\|\\(b\\)\\|.", emacs, "b", match_default, make_array(0, 1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\|b\\|.", emacs, "a", match_default, make_array(0, 1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\(b\\|c\\)", emacs, "ab", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\(b\\|c\\)", emacs, "ac", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\(b\\|c\\)", emacs, "ad", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\(a\\|b\\|c\\)", emacs, "c", match_default, make_array(0, 1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\|\\(b\\)\\|.\\)", emacs, "b", match_default, make_array(0, 1, 0, 1, 0, 1, -2, -2)); + TEST_INVALID_REGEX("\\|c", emacs); + TEST_INVALID_REGEX("c\\|", emacs); + TEST_INVALID_REGEX("\\(\\|\\)", emacs); + TEST_INVALID_REGEX("\\(a\\|\\)", emacs); + TEST_INVALID_REGEX("\\(\\|a\\)", emacs); + + TEST_REGEX_SEARCH("\\(?:abc\\)+", emacs, "xxabcabcxx", match_default, make_array(2, 8, -2, -2)); + TEST_REGEX_SEARCH("\\(?:a+\\)\\(b+\\)", emacs, "xaaabbbx", match_default, make_array(1, 7, 4, 7, -2, -2)); + TEST_REGEX_SEARCH("\\(a+\\)\\(?:b+\\)", emacs, "xaaabbba", match_default, make_array(1, 7, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\(?:\\(a+\\)b+\\)", emacs, "xaaabbba", match_default, make_array(1, 7, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\(?:a+\\(b+\\)\\)", emacs, "xaaabbba", match_default, make_array(1, 7, 4, 7, -2, -2)); + TEST_REGEX_SEARCH("a+\\(?#b+\\)b+", emacs, "xaaabbba", match_default, make_array(1, 7, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\(?:b\\|$\\)", emacs, "ab", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\(a\\)\\(?:b\\|$\\)", emacs, "a", match_default, make_array(0, 1, 0, 1, -2, -2)); + test_emacs2(); +} + +void test_emacs2() +{ + using namespace boost::regex_constants; + + + TEST_REGEX_SEARCH("\\ss+", emacs, "a b", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\Ss+", emacs, " ab ", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\sw+", emacs, " ab ", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\Sw+", emacs, "a b", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\s_+", emacs, " $&*+-_<> ", match_default, make_array(1, 9, -2, -2)); + TEST_REGEX_SEARCH("\\S_+", emacs, "$&*+-_<>b", match_default, make_array(8, 9, -2, -2)); + TEST_REGEX_SEARCH("\\s.+", emacs, " .,;!? ", match_default, make_array(1, 6, -2, -2)); + TEST_REGEX_SEARCH("\\S.+", emacs, ".,;!?b", match_default, make_array(5, 6, -2, -2)); + TEST_REGEX_SEARCH("\\s(+", emacs, "([{ ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\S(+", emacs, "([{ ", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\s)+", emacs, ")]} ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\S)+", emacs, ")]} ", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\s\"+", emacs, "\"'` ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\S\"+", emacs, "\"'` ", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\s'+", emacs, "',# ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\S'+", emacs, "',# ", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\s<+", emacs, "; ", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\S<+", emacs, "; ", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\s>+", emacs, "\n\f ", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\S>+", emacs, "\n\f ", match_default, make_array(2, 3, -2, -2)); +} + diff --git a/src/boost/libs/regex/test/regress/test_escapes.cpp b/src/boost/libs/regex/test/regress/test_escapes.cpp new file mode 100644 index 00000000..c9bc951b --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_escapes.cpp @@ -0,0 +1,216 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127 4428) +#endif + +void test_character_escapes() +{ + using namespace boost::regex_constants; + // characters by code + TEST_REGEX_SEARCH("\\0101", perl, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\00", perl, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\0", perl, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\0172", perl, "z", match_default, make_array(0, 1, -2, -2)); + // extra escape sequences: + TEST_REGEX_SEARCH("\\a", perl, "\a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\f", perl, "\f", 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("\\r", perl, "\r", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\v", perl, "\v", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\t", perl, "\t", match_default, make_array(0, 1, -2, -2)); + + // updated tests for version 2: + TEST_REGEX_SEARCH("\\x41", perl, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\xff", perl, "\xff", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\xFF", perl, "\xff", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\c@", perl, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\cA", perl, "\x1", match_default, make_array(0, 1, -2, -2)); + //TEST_REGEX_SEARCH("\\cz", perl, "\x3A", match_default, make_array(0, 1, -2, -2)); + //TEST_INVALID_REGEX("\\c=", boost::regex::extended); + //TEST_INVALID_REGEX("\\c?", boost::regex::extended); + TEST_REGEX_SEARCH("=:", perl, "=:", match_default, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("\\e", perl, "\x1B", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\x1b", 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("\\", perl); + TEST_INVALID_REGEX("\\c", perl); + TEST_INVALID_REGEX("\\x}", perl); + TEST_INVALID_REGEX("\\x", perl); + TEST_INVALID_REGEX("\\x{yy", perl); + TEST_INVALID_REGEX("\\x{1b", perl); + // \Q...\E sequences: + TEST_INVALID_REGEX("\\Qabc\\", perl); + TEST_REGEX_SEARCH("\\Qabc\\E", perl, "abcd", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\Qabc\\Ed", perl, "abcde", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("\\Q+*?\\\\E", perl, "+*?\\", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a\\Q+*?\\\\Eb", perl, "a+*?\\b", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\C+", perl, "abcde", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("\\X+", perl, "abcde", match_default, make_array(0, 5, -2, -2)); +#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("\\~", boost::regex::extended, "~", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\j", boost::regex::extended, "j", match_default, make_array(0, 1, -2, -2)); +} + +void test_assertion_escapes() +{ + using namespace boost::regex_constants; + // word start: + TEST_REGEX_SEARCH("\\<abcd", perl, " abcd", match_default, make_array(2, 6, -2, -2)); + TEST_REGEX_SEARCH("\\<ab", perl, "cab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<ab", perl, "\nab", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\<tag", perl, "::tag", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\<abcd", perl, "abcd", match_default|match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<abcd", perl, " abcd", match_default|match_not_bow, make_array(2, 6, -2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "ab ", match_default|match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH(".\\<.", perl, "ab", match_default|match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH(".\\<.", perl, " b", match_default|match_not_bow, make_array(0, 2, -2, -2)); + // word end: + TEST_REGEX_SEARCH("abc\\>", perl, "abc", match_default, make_array(0, 3, -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::", match_default, make_array(0,3, -2, -2)); + TEST_REGEX_SEARCH("abc(?:\\>..|$)", perl, "abc::", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("\\>", perl, " ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH(".\\>.", perl, " ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\>", perl, "abc", match_default|match_not_eow, make_array(-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)); + TEST_REGEX_SEARCH("\\bab", perl, "\nab", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\btag", perl, "::tag", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("abc\\b", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\b", perl, "abcd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\b", perl, "abc\n", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\b", perl, "abc::", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\babcd", perl, "abcd", match_default|match_not_bow, make_array(-2, -2)); + // within word: + TEST_REGEX_SEARCH("\\B", perl, "ab", match_default, make_array(1, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\Bb", perl, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\B", perl, "ab", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a\\B", perl, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a\\B", perl, "a ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\By\\b", perl, "xy", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\by\\B", perl, "yz", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\B\\*\\B", perl, " * ", match_default, make_array(1, 2, -2, -2)); + // buffer operators: + TEST_REGEX_SEARCH("\\`abc", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\`abc", perl, "\nabc", 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)); + 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)); + TEST_REGEX_SEARCH("[[:<:]]ab", perl, "cab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[[:<:]]ab", perl, "\nab", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("[[:<:]]tag", perl, "::tag", match_default, make_array(2, 5, -2, -2)); + // word end + TEST_REGEX_SEARCH("abc[[:>:]]", perl, "abc", match_default, make_array(0, 3, -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::", match_default, make_array(0, 3, -2, -2)); + + TEST_REGEX_SEARCH("\\Aabc", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\Aabc", perl, "aabc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\z", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\z", perl, "abcd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\Z", perl, "abc\n\n", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc\\Z", perl, "abc\n\n", match_default|match_not_eob, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc\\Z", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\Gabc", perl, "abc", match_default, make_array(0, 3, -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\\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)); + + // Buffer reset \K: + TEST_REGEX_SEARCH("(foo)\\Kbar", perl, "foobar", match_default, make_array(3, 6, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(foo)(\\Kbar|baz)", perl, "foobar", match_default, make_array(3, 6, 0, 3, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(foo)(\\Kbar|baz)", perl, "foobaz", match_default, make_array(0, 6, 0, 3, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(foo\\Kbar)baz", perl, "foobarbaz", match_default, make_array(3, 9, 0, 6, -2, -2)); + + // Line ending \R: + TEST_REGEX_SEARCH("\\R", perl, "foo\nbar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\R", perl, "foo\rbar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\R", perl, "foo\r\nbar", match_default, make_array(3, 5, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl, "abc\r\nbar", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl, "abc\012bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl, "abc\013bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl, "abc\013bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl, "abc\205bar", match_default, make_array(0, 4, -2, -2)); + // see if \u works: + const wchar_t* w = L"\u2028"; + if(*w == 0x2028u) + { + TEST_REGEX_SEARCH_W(L"\\R", perl, L"foo\u2028bar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\R", perl, L"foo\u2029bar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"(?x) abc \\R", perl, L"abc\u2028bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"(?x) abc \\R", perl, L"abc\u2029bar", match_default, make_array(0, 4, -2, -2)); + } + // Bug report: https://github.com/boostorg/regex/issues/40 + TEST_REGEX_SEARCH("\\b", perl, "", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b", perl, "", match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b", perl, "", match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b", perl, "", match_not_bow | match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b", perl, "-", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b", perl, "-", match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b", perl, "-", match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b", perl, "-", match_not_bow | match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "", match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "", match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "", match_not_bow | match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "-", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "-", match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "-", match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\<", perl, "-", match_not_bow | match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "", match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "", match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "", match_not_bow | match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "-", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "-", match_not_bow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "-", match_not_eow, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\>", perl, "-", match_not_bow | match_not_eow, make_array(-2, -2)); + // Bug report https://github.com/boostorg/regex/issues/57 + // Line ending \R: + TEST_REGEX_SEARCH("\\R", perl | no_escape_in_lists, "foo\nbar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\R", perl | no_escape_in_lists, "foo\rbar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH("\\R", perl | no_escape_in_lists, "foo\r\nbar", match_default, make_array(3, 5, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl | no_escape_in_lists, "abc\r\nbar", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl | no_escape_in_lists, "abc\012bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl | no_escape_in_lists, "abc\013bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl | no_escape_in_lists, "abc\013bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?x) abc \\R", perl | no_escape_in_lists, "abc\205bar", match_default, make_array(0, 4, -2, -2)); + // see if \u works: + if(*w == 0x2028u) + { + TEST_REGEX_SEARCH_W(L"\\R", perl | no_escape_in_lists, L"foo\u2028bar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\R", perl | no_escape_in_lists, L"foo\u2029bar", match_default, make_array(3, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"(?x) abc \\R", perl | no_escape_in_lists, L"abc\u2028bar", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"(?x) abc \\R", perl | no_escape_in_lists, L"abc\u2029bar", match_default, make_array(0, 4, -2, -2)); + } +} + diff --git a/src/boost/libs/regex/test/regress/test_grep.cpp b/src/boost/libs/regex/test/regress/test_grep.cpp new file mode 100644 index 00000000..501ee87e --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_grep.cpp @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_grep() +{ + // + // now test grep, + // basically check all our restart types - line, word, etc + // checking each one for null and non-null matches. + // + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("a", perl|nosubs, " a a a aa", match_default, make_array(1, 2, -2, 3, 4, -2, 5, 6, -2, 7, 8, -2, 8, 9, -2, -2)); + TEST_REGEX_SEARCH("a+b+", perl|nosubs, "aabaabbb ab", match_default, make_array(0, 3, -2, 3, 8, -2, 9, 11, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl|nosubs, "adabbdacd", match_default, make_array(0, 2, -2, 2, 6, -2, 6, 9, -2, -2)); + TEST_REGEX_SEARCH("a", perl|nosubs, "\na\na\na\naa", match_default, make_array(1, 2, -2, 3, 4, -2, 5, 6, -2, 7, 8, -2, 8, 9, -2, -2)); + TEST_REGEX_SEARCH("^", perl|nosubs, " \n\n \n\n\n", match_default, make_array(0, 0, -2, 4, 4, -2, 5, 5, -2, 8, 8, -2, 9, 9, -2, 10, 10, -2, -2)); + TEST_REGEX_SEARCH("^ab", perl|nosubs, "ab \nab ab\n", match_default, make_array(0, 2, -2, 5, 7, -2, -2)); + TEST_REGEX_SEARCH("^[^\\n]*\n", perl|nosubs, " \n \n\n \n", match_default, make_array(0, 4, -2, 4, 7, -2, 7, 8, -2, 8, 11, -2, -2)); + TEST_REGEX_SEARCH("\\<abc", perl|nosubs, "abcabc abc\n\nabc", match_default, make_array(0, 3, -2, 7, 10, -2, 12, 15, -2, -2)); + TEST_REGEX_SEARCH("\\<", perl|nosubs, " ab a aaa ", match_default, make_array(2, 2, -2, 5, 5, -2, 7, 7, -2, -2)); + TEST_REGEX_SEARCH("\\<\\w+\\W+", perl|nosubs, " aa aa a ", match_default, make_array(1, 5, -2, 5, 9, -2, 9, 11, -2, -2)); + + TEST_REGEX_SEARCH("\\Aabc", perl|nosubs, "abc abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\G\\w+\\W+", perl|nosubs, "abc abc a cbbb ", match_default, make_array(0, 5, -2, 5, 9, -2, 9, 11, -2, 11, 18, -2, -2)); + TEST_REGEX_SEARCH("\\Ga+b+", perl|nosubs, "aaababb abb", match_default, make_array(0, 4, -2, 4, 7, -2, -2)); + TEST_REGEX_SEARCH("abc", perl|nosubs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc", perl|nosubs, " abc abcabc", match_default, make_array(1, 4, -2, 5, 8, -2, 8, 11, -2, -2)); + TEST_REGEX_SEARCH("\\n\\n", perl|nosubs, " \n\n\n \n \n\n\n\n ", match_default, make_array(1, 3, -2, 18, 20, -2, 20, 22, -2, -2)); + TEST_REGEX_SEARCH("$", perl|nosubs, " \n\n \n\n\n", match_default, make_array(3, 3, -2, 4, 4, -2, 7, 7, -2, 8, 8, -2, 9, 9, -2, 10, 10, -2, -2)); + TEST_REGEX_SEARCH("\\b", perl|nosubs, " abb a abbb ", match_default, make_array(2, 2, -2, 5, 5, -2, 6, 6, -2, 7, 7, -2, 8, 8, -2, 12, 12, -2, -2)); + TEST_REGEX_SEARCH("A", perl|icase|nosubs, " a a a aa", match_default, make_array(1, 2, -2, 3, 4, -2, 5, 6, -2, 7, 8, -2, 8, 9, -2, -2)); + TEST_REGEX_SEARCH("A+B+", perl|icase|nosubs, "aabaabbb ab", match_default, make_array(0, 3, -2, 3, 8, -2, 9, 11, -2, -2)); + TEST_REGEX_SEARCH("A(B*|c|e)D", perl|icase|nosubs, "adabbdacd", match_default, make_array(0, 2, -2, 2, 6, -2, 6, 9, -2, -2)); + TEST_REGEX_SEARCH("A", perl|icase|nosubs, "\na\na\na\naa", match_default, make_array(1, 2, -2, 3, 4, -2, 5, 6, -2, 7, 8, -2, 8, 9, -2, -2)); + TEST_REGEX_SEARCH("^aB", perl|icase|nosubs, "Ab \nab Ab\n", match_default, make_array(0, 2, -2, 5, 7, -2, -2)); + TEST_REGEX_SEARCH("\\<abc", perl|icase|nosubs, "Abcabc aBc\n\nabc", match_default, make_array(0, 3, -2, 7, 10, -2, 12, 15, -2, -2)); + TEST_REGEX_SEARCH("ABC", perl|icase|nosubs, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("abc", perl|icase|nosubs, " ABC ABCABC ", match_default, make_array(1, 4, -2, 5, 8, -2, 8, 11, -2, -2)); + TEST_REGEX_SEARCH("a|\\Ab", perl, "b ab", match_default, make_array(0, 1, -2, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a|^b", perl, "b ab\nb", match_default, make_array(0, 1, -2, 2, 3, -2, 5, 6, -2, -2)); + TEST_REGEX_SEARCH("a|\\<b", perl, "b ab\nb", match_default, make_array(0, 1, -2, 2, 3, -2, 5, 6, -2, -2)); + + TEST_REGEX_SEARCH("\\Aabc", perl, "abcabc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("^abc", perl, "abcabc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\<abc", perl, "abcabc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\babc", perl, "abcabc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?<=\\Aabc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?<=^abc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?<=\\<abc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?<=\\babc)?abc", perl, "abcabc", match_default, make_array(0, 3, -2, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?<=^).{2}|(?<=^.{3}).{2}", perl, "123456789", match_default, make_array(0, 2, -2, 3, 5, -2, -2)); +} + diff --git a/src/boost/libs/regex/test/regress/test_icu.cpp b/src/boost/libs/regex/test/regress/test_icu.cpp new file mode 100644 index 00000000..1ef9fa96 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_icu.cpp @@ -0,0 +1,703 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_icu.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Test code for Unicode regexes with ICU support. + */ + +// +// We can only build this if we have ICU support: +// +#include <boost/regex/config.hpp> +#if defined(BOOST_HAS_ICU) && !defined(BOOST_NO_STD_WSTRING) + +#include <boost/regex/icu.hpp> +#include "test.hpp" + +namespace unnecessary_fix{ +// +// Some outrageously broken std lib's don't have a conforming +// back_insert_iterator, which means we can't use the std version +// as an argument to regex_replace, sigh... use our own: +// +template <class Seq> +class back_insert_iterator +{ +private: + Seq* container; +public: + typedef const typename Seq::value_type value_type; + typedef Seq container_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + typedef std::output_iterator_tag iterator_category; + + explicit back_insert_iterator(Seq& x) : container(&x) {} + back_insert_iterator& operator=(const value_type& val) + { + container->push_back(val); + return *this; + } + back_insert_iterator& operator*() { return *this; } + back_insert_iterator& operator++() { return *this; } + back_insert_iterator operator++(int) { return *this; } +}; + +template <class Seq> +inline back_insert_iterator<Seq> back_inserter(Seq& x) +{ + return back_insert_iterator<Seq>(x); +} + +} + +// +// compare two match_results struct's for equality, +// converting the iterator as needed: +// +template <class MR1, class MR2> +void compare_result(const MR1& w1, const MR2& w2, boost::mpl::int_<2> const*) +{ + typedef typename MR2::value_type MR2_value_type; + typedef typename MR2_value_type::const_iterator MR2_iterator_type; + typedef boost::u16_to_u32_iterator<MR2_iterator_type> iterator_type; + //typedef typename MR1::size_type size_type; + if(w1.size() != w2.size()) + { + BOOST_REGEX_TEST_ERROR("Size mismatch in match_results class", UChar32); + } + for(int i = 0; i < (int)w1.size(); ++i) + { + if(w1[i].matched) + { + if(w2[i].matched == 0) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } + if((w1.position(i) != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2.prefix().first), iterator_type(w2[i].first))) || (w1.length(i) != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2[i].first), iterator_type(w2[i].second)))) + { + BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32); + } + } + else if(w2[i].matched) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } + } + // + // We don't have a way to access a list of named sub-expressions since we only store + // hashes, but "abc" and "N" are common names used in our tests, so check those: + // + if (w1["abc"].matched) + { + if (w2["abc"].matched == 0) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } + if ((w1.position("abc") != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2.prefix().first), iterator_type(w2["abc"].first))) || (w1.length("abc") != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2["abc"].first), iterator_type(w2["abc"].second)))) + { + BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32); + } + } + else if (w2["abc"].matched) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } + if (w1["N"].matched) + { + if (w2["N"].matched == 0) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } + if ((w1.position("N") != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2.prefix().first), iterator_type(w2["N"].first))) || (w1.length("N") != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2["N"].first), iterator_type(w2["N"].second)))) + { + BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32); + } + } + else if (w2["N"].matched) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } +} +template <class MR1, class MR2> +void compare_result(const MR1& w1, const MR2& w2, boost::mpl::int_<1> const*) +{ + typedef typename MR2::value_type MR2_value_type; + typedef typename MR2_value_type::const_iterator MR2_iterator_type; + typedef boost::u8_to_u32_iterator<MR2_iterator_type> iterator_type; + //typedef typename MR1::size_type size_type; + if(w1.size() != w2.size()) + { + BOOST_REGEX_TEST_ERROR("Size mismatch in match_results class", UChar32); + } + for(int i = 0; i < (int)w1.size(); ++i) + { + if(w1[i].matched) + { + if(w2[i].matched == 0) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } + if((w1.position(i) != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2.prefix().first), iterator_type(w2[i].first))) || (w1.length(i) != boost::BOOST_REGEX_DETAIL_NS::distance(iterator_type(w2[i].first), iterator_type(w2[i].second)))) + { + BOOST_REGEX_TEST_ERROR("Iterator mismatch in match_results class", UChar32); + } + } + else if(w2[i].matched) + { + BOOST_REGEX_TEST_ERROR("Matched mismatch in match_results class", UChar32); + } + } +} + +void test_icu_grep(const boost::u32regex& r, const std::vector< ::UChar32>& search_text) +{ + typedef std::vector< ::UChar32>::const_iterator const_iterator; + typedef boost::u32regex_iterator<const_iterator> test_iterator; + boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options(); + const int* answer_table = test_info<wchar_t>::answer_table(); + test_iterator start(search_text.begin(), search_text.end(), r, opts), end; + test_iterator copy(start); + const_iterator last_end = search_text.begin(); + while(start != end) + { + if(start != copy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t); + } + if(!(start == copy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t); + } + test_result(*start, search_text.begin(), answer_table); + // test $` and $' : + if(start->prefix().first != last_end) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for start of $`", wchar_t); + } + if(start->prefix().second != (*start)[0].first) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for end of $`", wchar_t); + } + if(start->prefix().matched != (start->prefix().first != start->prefix().second)) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $`", wchar_t); + } + if(start->suffix().first != (*start)[0].second) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for start of $'", wchar_t); + } + if(start->suffix().second != search_text.end()) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for end of $'", wchar_t); + } + if(start->suffix().matched != (start->suffix().first != start->suffix().second)) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $'", wchar_t); + } + last_end = (*start)[0].second; + ++start; + ++copy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t); + } +} + +void test_icu(const wchar_t&, const test_regex_search_tag& ) +{ + boost::u32regex r; + if(*test_locale::c_str()) + { + U_NAMESPACE_QUALIFIER Locale l(test_locale::c_str()); + if(l.isBogus()) + return; + r.imbue(l); + } + + std::vector< ::UChar32> expression; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression.assign(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end()); +#else + std::copy(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end(), std::back_inserter(expression)); +#endif + boost::regex_constants::syntax_option_type syntax_options = test_info<UChar32>::syntax_options(); +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { +#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) + r.assign(expression.begin(), expression.end(), syntax_options); +#else + if(expression.size()) + r.assign(&*expression.begin(), expression.size(), syntax_options); + else + r.assign(static_cast<UChar32 const*>(0), expression.size(), syntax_options); +#endif + if(r.status()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), UChar32); + } + std::vector< ::UChar32> search_text; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + search_text.assign(test_info<wchar_t>::search_text().begin(), test_info<wchar_t>::search_text().end()); +#else + std::copy(test_info<wchar_t>::search_text().begin(), test_info<wchar_t>::search_text().end(), std::back_inserter(search_text)); +#endif + boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options(); + const int* answer_table = test_info<wchar_t>::answer_table(); + boost::match_results<std::vector< ::UChar32>::const_iterator> what; + if(boost::u32regex_search( + const_cast<std::vector< ::UChar32>const&>(search_text).begin(), + const_cast<std::vector< ::UChar32>const&>(search_text).end(), + what, + r, + opts)) + { + test_result(what, const_cast<std::vector< ::UChar32>const&>(search_text).begin(), answer_table); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32); + } + + if(0 == *test_locale::c_str()) + { + // + // Now try UTF-16 construction: + // + typedef boost::u32_to_u16_iterator<std::vector<UChar32>::const_iterator> u16_conv; + std::vector<UChar> expression16, text16; + boost::match_results<std::vector<UChar>::const_iterator> what16; + boost::match_results<const UChar*> what16c; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression16.assign(u16_conv(expression.begin()), u16_conv(expression.end())); + text16.assign(u16_conv(search_text.begin()), u16_conv(search_text.end())); +#else + expression16.clear(); + std::copy(u16_conv(expression.begin()), u16_conv(expression.end()), std::back_inserter(expression16)); + text16.clear(); + std::copy(u16_conv(search_text.begin()), u16_conv(search_text.end()), std::back_inserter(text16)); +#endif + r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options); + if(boost::u32regex_search(const_cast<const std::vector<UChar>&>(text16).begin(), const_cast<const std::vector<UChar>&>(text16).end(), what16, r, opts)) + { + compare_result(what, what16, static_cast<boost::mpl::int_<2> const*>(0)); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32); + } + if(std::find(expression16.begin(), expression16.end(), 0) == expression16.end()) + { + expression16.push_back(0); + r = boost::make_u32regex(&*expression16.begin(), syntax_options); + if(std::find(text16.begin(), text16.end(), 0) == text16.end()) + { + text16.push_back(0); + if(boost::u32regex_search((const UChar*)&*text16.begin(), what16c, r, opts)) + { + compare_result(what, what16c, static_cast<boost::mpl::int_<2> const*>(0)); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32); + } + } + } + // + // Now try UTF-8 construction: + // + typedef boost::u32_to_u8_iterator<std::vector<UChar32>::const_iterator, unsigned char> u8_conv; + std::vector<unsigned char> expression8, text8; + boost::match_results<std::vector<unsigned char>::const_iterator> what8; + boost::match_results<const unsigned char*> what8c; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression8.assign(u8_conv(expression.begin()), u8_conv(expression.end())); + text8.assign(u8_conv(search_text.begin()), u8_conv(search_text.end())); +#else + expression8.clear(); + std::copy(u8_conv(expression.begin()), u8_conv(expression.end()), std::back_inserter(expression8)); + text8.clear(); + std::copy(u8_conv(search_text.begin()), u8_conv(search_text.end()), std::back_inserter(text8)); +#endif + r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options); + if(boost::u32regex_search(const_cast<const std::vector<unsigned char>&>(text8).begin(), const_cast<const std::vector<unsigned char>&>(text8).end(), what8, r, opts)) + { + compare_result(what, what8, static_cast<boost::mpl::int_<1> const*>(0)); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32); + } + if(std::find(expression8.begin(), expression8.end(), 0) == expression8.end()) + { + expression8.push_back(0); + r = boost::make_u32regex(&*expression8.begin(), syntax_options); + if(std::find(text8.begin(), text8.end(), 0) == text8.end()) + { + text8.push_back(0); + if(boost::u32regex_search((const unsigned char*)&*text8.begin(), what8c, r, opts)) + { + compare_result(what, what8c, static_cast<boost::mpl::int_<1> const*>(0)); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", UChar32); + } + } + } + } + // + // finally try a grep: + // + test_icu_grep(r, search_text); + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression& e) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), UChar32); + } + catch(const std::runtime_error& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e.what(), UChar32); + } + catch(const std::exception& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e.what(), UChar32); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", UChar32); + } +#endif +} + +void test_icu(const wchar_t&, const test_invalid_regex_tag&) +{ + //typedef boost::u16_to_u32_iterator<std::wstring::const_iterator, ::UChar32> conv_iterator; + std::vector< ::UChar32> expression; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression.assign(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end()); +#else + std::copy(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end(), std::back_inserter(expression)); +#endif + boost::regex_constants::syntax_option_type syntax_options = test_info<wchar_t>::syntax_options(); + boost::u32regex r; + if(*test_locale::c_str()) + { + U_NAMESPACE_QUALIFIER Locale l(test_locale::c_str()); + if(l.isBogus()) + return; + r.imbue(l); + } + // + // try it with exceptions disabled first: + // +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { +#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) + if(0 == r.assign(expression.begin(), expression.end(), syntax_options | boost::regex_constants::no_except).status()) +#else + if(expression.size()) + r.assign(&*expression.begin(), expression.size(), syntax_options | boost::regex_constants::no_except); + else + r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options | boost::regex_constants::no_except); + if(0 == r.status()) +#endif + { + BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t); + } + } +#ifndef BOOST_NO_EXCEPTIONS + catch(...) + { + BOOST_REGEX_TEST_ERROR("Unexpected exception thrown.", wchar_t); + } +#endif + // + // now try again with exceptions: + // + bool have_catch = false; +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { +#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) + r.assign(expression.begin(), expression.end(), syntax_options); +#else + if(expression.size()) + r.assign(&*expression.begin(), expression.size(), syntax_options); + else + r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options); +#endif +#ifdef BOOST_NO_EXCEPTIONS + if(r.status()) + have_catch = true; +#endif + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression&) + { + have_catch = true; + } + catch(const std::runtime_error& e) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << e.what(), wchar_t); + } + catch(const std::exception& e) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << e.what(), wchar_t); + } + catch(...) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", wchar_t); + } +#endif + if(!have_catch) + { + // oops expected exception was not thrown: + BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", wchar_t); + } + + if(0 == *test_locale::c_str()) + { + // + // Now try UTF-16 construction: + // + typedef boost::u32_to_u16_iterator<std::vector<UChar32>::const_iterator> u16_conv; + std::vector<UChar> expression16; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression16.assign(u16_conv(expression.begin()), u16_conv(expression.end())); +#else + std::copy(u16_conv(expression.begin()), u16_conv(expression.end()), std::back_inserter(expression16)); +#endif + if(0 == boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options | boost::regex_constants::no_except).status()) + { + BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t); + } + if(std::find(expression16.begin(), expression16.end(), 0) == expression16.end()) + { + expression16.push_back(0); + if(0 == boost::make_u32regex(&*expression16.begin(), syntax_options | boost::regex_constants::no_except).status()) + { + BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t); + } + } + // + // Now try UTF-8 construction: + // + typedef boost::u32_to_u8_iterator<std::vector<UChar32>::const_iterator> u8_conv; + std::vector<unsigned char> expression8; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression8.assign(u8_conv(expression.begin()), u8_conv(expression.end())); +#else + std::copy(u8_conv(expression.begin()), u8_conv(expression.end()), std::back_inserter(expression8)); +#endif + if(0 == boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options | boost::regex_constants::no_except).status()) + { + BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t); + } + if(std::find(expression8.begin(), expression8.end(), 0) == expression8.end()) + { + expression8.push_back(0); + if(0 == boost::make_u32regex(&*expression8.begin(), syntax_options | boost::regex_constants::no_except).status()) + { + BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", wchar_t); + } + } + } +} + +void test_icu(const wchar_t&, const test_regex_replace_tag&) +{ + std::vector< ::UChar32> expression; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression.assign(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end()); +#else + std::copy(test_info<wchar_t>::expression().begin(), test_info<wchar_t>::expression().end(), std::back_inserter(expression)); +#endif + boost::regex_constants::syntax_option_type syntax_options = test_info<UChar32>::syntax_options(); + boost::u32regex r; +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { +#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__) + r.assign(expression.begin(), expression.end(), syntax_options); +#else + if(expression.size()) + r.assign(&*expression.begin(), expression.size(), syntax_options); + else + r.assign(static_cast<UChar32 const*>(0), static_cast<boost::u32regex::size_type>(0), syntax_options); +#endif + if(r.status()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), UChar32); + } + typedef std::vector<UChar32> string_type; + string_type search_text; + boost::regex_constants::match_flag_type opts = test_info<UChar32>::match_options(); + string_type format_string; + string_type result_string; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + search_text.assign(test_info<UChar32>::search_text().begin(), test_info<UChar32>::search_text().end()); + format_string.assign(test_info<UChar32>::format_string().begin(), test_info<UChar32>::format_string().end()); + format_string.push_back(0); + result_string.assign(test_info<UChar32>::result_string().begin(), test_info<UChar32>::result_string().end()); +#else + std::copy(test_info<UChar32>::search_text().begin(), test_info<UChar32>::search_text().end(), std::back_inserter(search_text)); + std::copy(test_info<UChar32>::format_string().begin(), test_info<UChar32>::format_string().end(), std::back_inserter(format_string)); + format_string.push_back(0); + std::copy(test_info<UChar32>::result_string().begin(), test_info<UChar32>::result_string().end(), std::back_inserter(result_string)); +#endif + string_type result; + + boost::u32regex_replace(unnecessary_fix::back_inserter(result), search_text.begin(), search_text.end(), r, &*format_string.begin(), opts); + if(result != result_string) + { + BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", UChar32); + } + // + // Mixed mode character encoding: + // + if(0 == *test_locale::c_str()) + { + // + // Now try UTF-16 construction: + // + typedef boost::u32_to_u16_iterator<std::vector<UChar32>::const_iterator> u16_conv; + std::vector<UChar> expression16, text16, format16, result16, found16; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression16.assign(u16_conv(expression.begin()), u16_conv(expression.end())); + text16.assign(u16_conv(search_text.begin()), u16_conv(search_text.end())); + format16.assign(u16_conv(format_string.begin()), u16_conv(format_string.end())); + result16.assign(u16_conv(result_string.begin()), u16_conv(result_string.end())); +#else + std::copy(u16_conv(expression.begin()), u16_conv(expression.end()), std::back_inserter(expression16)); + std::copy(u16_conv(search_text.begin()), u16_conv(search_text.end()), std::back_inserter(text16)); + std::copy(u16_conv(format_string.begin()), u16_conv(format_string.end()), std::back_inserter(format16)); + std::copy(u16_conv(result_string.begin()), u16_conv(result_string.end()), std::back_inserter(result16)); +#endif + r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options); + boost::u32regex_replace(unnecessary_fix::back_inserter(found16), text16.begin(), text16.end(), r, &*format16.begin(), opts); + if(result16 != found16) + { + BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-16 string returned incorrect result", UChar32); + } + // + // Now with UnicodeString: + // + U_NAMESPACE_QUALIFIER UnicodeString expression16u, text16u, format16u, result16u, found16u; + if(expression16.size()) + expression16u.setTo(&*expression16.begin(), expression16.size()); + if(text16.size()) + text16u.setTo(&*text16.begin(), text16.size()); + format16u.setTo(&*format16.begin(), format16.size()-1); + if(result16.size()) + result16u.setTo(&*result16.begin(), result16.size()); + r = boost::make_u32regex(expression16.begin(), expression16.end(), syntax_options); + found16u = boost::u32regex_replace(text16u, r, format16u, opts); + if(result16u != found16u) + { + BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-16 string returned incorrect result", UChar32); + } + + // + // Now try UTF-8 construction: + // + typedef boost::u32_to_u8_iterator<std::vector<UChar32>::const_iterator, unsigned char> u8_conv; + std::vector<char> expression8, text8, format8, result8, found8; +#ifndef BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS + expression8.assign(u8_conv(expression.begin()), u8_conv(expression.end())); + text8.assign(u8_conv(search_text.begin()), u8_conv(search_text.end())); + format8.assign(u8_conv(format_string.begin()), u8_conv(format_string.end())); + result8.assign(u8_conv(result_string.begin()), u8_conv(result_string.end())); +#else + std::copy(u8_conv(expression.begin()), u8_conv(expression.end()), std::back_inserter(expression8)); + std::copy(u8_conv(search_text.begin()), u8_conv(search_text.end()), std::back_inserter(text8)); + std::copy(u8_conv(format_string.begin()), u8_conv(format_string.end()), std::back_inserter(format8)); + std::copy(u8_conv(result_string.begin()), u8_conv(result_string.end()), std::back_inserter(result8)); +#endif + r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options); + boost::u32regex_replace(unnecessary_fix::back_inserter(found8), text8.begin(), text8.end(), r, &*format8.begin(), opts); + if(result8 != found8) + { + BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-8 string returned incorrect result", UChar32); + } + // + // Now with std::string and UTF-8: + // + std::string expression8s, text8s, format8s, result8s, found8s; + if(expression8.size()) + expression8s.assign(&*expression8.begin(), expression8.size()); + if(text8.size()) + text8s.assign(&*text8.begin(), text8.size()); + format8s.assign(&*format8.begin(), format8.size()-1); + if(result8.size()) + result8s.assign(&*result8.begin(), result8.size()); + r = boost::make_u32regex(expression8.begin(), expression8.end(), syntax_options); + found8s = boost::u32regex_replace(text8s, r, format8s, opts); + if(result8s != found8s) + { + BOOST_REGEX_TEST_ERROR("u32regex_replace with UTF-8 string returned incorrect result", UChar32); + } + } + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression& e) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), UChar32); + } + catch(const std::runtime_error& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e.what(), UChar32); + } + catch(const std::exception& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e.what(), UChar32); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", UChar32); + } +#endif +} + +#else + +#include "test.hpp" + +void test_icu(const wchar_t&, const test_regex_search_tag&){} +void test_icu(const wchar_t&, const test_invalid_regex_tag&){} +void test_icu(const wchar_t&, const test_regex_replace_tag&){} + +#endif + diff --git a/src/boost/libs/regex/test/regress/test_icu.hpp b/src/boost/libs/regex/test/regress/test_icu.hpp new file mode 100644 index 00000000..cd90e984 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_icu.hpp @@ -0,0 +1,33 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_icu.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: MFC/ATL test handlers. + */ + +#ifndef TEST_ICU_HPP +#define TEST_ICU_HPP + +template <class charT, class Tag> +void test_icu(const charT&, const Tag&) +{ + // do nothing +} + +void test_icu(const wchar_t&, const test_regex_search_tag&); +void test_icu(const wchar_t&, const test_invalid_regex_tag&); +void test_icu(const wchar_t&, const test_regex_replace_tag&); + + +#endif diff --git a/src/boost/libs/regex/test/regress/test_locale.cpp b/src/boost/libs/regex/test/regress/test_locale.cpp new file mode 100644 index 00000000..54cd56ab --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_locale.cpp @@ -0,0 +1,220 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" +#include <clocale> +#if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32) +#include <boost/scoped_array.hpp> +#include <windows.h> +#endif +#include <iostream> +#include <iomanip> + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std{ using ::setlocale; } +#endif + +test_locale::test_locale(const char* c_name, boost::uint32_t lcid) +{ +#ifndef UNDER_CE + // store the name: + m_old_name = m_name; + m_name = c_name; + // back up C locale and then set it's new name: + const char* pl = std::setlocale(LC_ALL, 0); + m_old_c_locale = pl ? pl : ""; + m_old_c_state = s_c_locale; + if(std::setlocale(LC_ALL, c_name)) + { + s_c_locale = test_with_locale; + std::cout << "Testing the global C locale: " << c_name << std::endl; + } + else + { + s_c_locale = no_test; + std::cout << "The global C locale: " << c_name << " is not available and will not be tested." << std::endl; + } +#else + s_c_locale = no_test; +#endif + // Disabled for VC15.7 (and later?) as the C runtime asserts if you pass an invalid + // locale name to std::locale, rather than throwing the expected exception. +#if !defined(BOOST_NO_STD_LOCALE) && !defined(BOOST_NO_EXCEPTIONS) && !BOOST_WORKAROUND(BOOST_MSVC, > 1913) + // back up the C++ locale and create the new one: + m_old_cpp_locale = s_cpp_locale_inst; + m_old_cpp_state = s_cpp_locale; + try{ + s_cpp_locale_inst = std::locale(c_name); + s_cpp_locale = test_with_locale; + std::cout << "Testing the C++ locale: " << c_name << std::endl; + } + catch(std::runtime_error const &) + { + s_cpp_locale = no_test; + std::cout << "The C++ locale: " << c_name << " is not available and will not be tested." << std::endl; + } +#else + m_old_cpp_locale = s_cpp_locale_inst; + m_old_cpp_state = s_cpp_locale; + s_cpp_locale = no_test; +#endif + + // back up win locale and create the new one: + m_old_win_locale = s_win_locale_inst; + m_old_win_state = s_win_locale; + s_win_locale_inst = lcid; +#if defined(BOOST_WINDOWS) && !defined(BOOST_DISABLE_WIN32) + // + // Start by geting the printable name of the locale. + // We use this for debugging purposes only: + // +#ifndef BOOST_NO_ANSI_APIS + boost::scoped_array<char> p; + int r = ::GetLocaleInfoA( + lcid, // locale identifier + LOCALE_SCOUNTRY, // information type + 0, // information buffer + 0 // size of buffer + ); + p.reset(new char[r+1]); + r = ::GetLocaleInfoA( + lcid, // locale identifier + LOCALE_SCOUNTRY, // information type + p.get(), // information buffer + r+1 // size of buffer + ); +#else + WCHAR code_page_string[7]; + int r = ::GetLocaleInfoW( + lcid, + LOCALE_IDEFAULTANSICODEPAGE, + code_page_string, + 7); + BOOST_ASSERT(r != 0); + + UINT code_page = static_cast<UINT>(_wtol(code_page_string)); + + boost::scoped_array<wchar_t> wp; + r = ::GetLocaleInfoW( + lcid, // locale identifier + LOCALE_SCOUNTRY, // information type + 0, // information buffer + 0 // size of buffer + ); + wp.reset(new wchar_t[r+1]); + r = ::GetLocaleInfoW( + lcid, // locale identifier + LOCALE_SCOUNTRY, // information type + wp.get(), // information buffer + r+1 // size of buffer + ); + + int name_size = (r+1) * 2; + boost::scoped_array<char> p(new char[name_size]); + int conv_r = ::WideCharToMultiByte( + code_page, + 0, + wp.get(), r, + p.get(), name_size, + NULL, NULL + ); + BOOST_ASSERT(conv_r != 0); +#endif + // + // now see if locale is installed and behave accordingly: + // + if(::IsValidLocale(lcid, LCID_INSTALLED)) + { + s_win_locale = test_with_locale; + std::cout << "Testing the Win32 locale: \"" << p.get() << "\" (0x" << std::hex << lcid << ")" << std::endl; + } + else + { + s_win_locale = no_test; + std::cout << "The Win32 locale: \"" << p.get() << "\" (0x" << std::hex << lcid << ") is not available and will not be tested." << std::endl; + } +#else + s_win_locale = no_test; +#endif +} + +test_locale::~test_locale() +{ + // restore to previous state: +#ifndef UNDER_CE + std::setlocale(LC_ALL, m_old_c_locale.c_str()); + s_c_locale = m_old_c_state; +#endif +#ifndef BOOST_NO_STD_LOCALE + s_cpp_locale_inst = m_old_cpp_locale; +#endif + s_cpp_locale = m_old_cpp_state; + s_win_locale_inst = m_old_win_locale; + s_win_locale = m_old_win_state; + m_name = m_old_name; +} + +int test_locale::s_c_locale = test_no_locale; +int test_locale::s_cpp_locale = test_no_locale; +int test_locale::s_win_locale = test_no_locale; +#ifndef BOOST_NO_STD_LOCALE +std::locale test_locale::s_cpp_locale_inst; +#endif +boost::uint32_t test_locale::s_win_locale_inst = 0; +std::string test_locale::m_name; + + +void test_en_locale(const char* name, boost::uint32_t lcid) +{ + using namespace boost::regex_constants; + errors_as_warnings w; + test_locale l(name, lcid); + TEST_REGEX_SEARCH_L("[[:lower:]]+", perl, "\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xf7", match_default, make_array(1, 32, -2, -2)); + TEST_REGEX_SEARCH_L("[[:upper:]]+", perl, "\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf", match_default, make_array(1, 31, -2, -2)); +// TEST_REGEX_SEARCH_L("[[:punct:]]+", perl, "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0", match_default, make_array(0, 31, -2, -2)); + TEST_REGEX_SEARCH_L("[[:print:]]+", perl, "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe", match_default, make_array(0, 93, -2, -2)); + TEST_REGEX_SEARCH_L("[[:graph:]]+", perl, "\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe", match_default, make_array(0, 93, -2, -2)); + TEST_REGEX_SEARCH_L("[[:word:]]+", perl, "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe", match_default, make_array(0, 61, -2, -2)); + // collation sensitive ranges: +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x600) + // these tests are disabled for Borland C++: a bug in std::collate<wchar_t> + // causes these tests to crash (pointer overrun in std::collate<wchar_t>::do_transform). + TEST_REGEX_SEARCH_L("[a-z]+", perl|::boost::regex_constants::collate, "\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc", match_default, make_array(0, 28, -2, -2)); + TEST_REGEX_SEARCH_L("[a-z]+", perl|::boost::regex_constants::collate, "\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc", match_default, make_array(1, 28, -2, -2)); + if (lcid != 0x09) + { + // and equivalence classes, these fail for locale "en" but pass for "en_UK" and "en_US": + TEST_REGEX_SEARCH_L("[[=a=]]+", perl, "aA\xe0\xe1\xe2\xe3\xe4\xe5\xc0\xc1\xc2\xc3\xc4\xc5", match_default, make_array(0, 14, -2, -2)); + } + // case mapping: + TEST_REGEX_SEARCH_L("[A-Z]+", perl|icase|::boost::regex_constants::collate, "\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc", match_default, make_array(0, 28, -2, -2)); + TEST_REGEX_SEARCH_L("[a-z]+", perl|icase|::boost::regex_constants::collate, "\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc", match_default, make_array(1, 28, -2, -2)); + TEST_REGEX_SEARCH_L("\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd8\xd9\xda\xdb\xdc\xdd", perl|icase, "\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf8\xf9\xfa\xfb\xfc\xfd\xfe", match_default, make_array(1, 30, -2, -2)); +#endif +} + +void test_en_locale() +{ + // VC6 seems to have problems with std::setlocale, I've never + // gotten to the bottem of this as the program runs fine under the + // debugger, but hangs when run from bjam: +#if !BOOST_WORKAROUND(BOOST_MSVC, <1300) && !(defined(__ICL) && defined(_MSC_VER) && (_MSC_VER == 1200)) + test_en_locale("en_US", 0x09 | 0x01 << 10); + test_en_locale("en_UK", 0x09 | 0x02 << 10); + test_en_locale("en", 0x09); +#endif +} + + diff --git a/src/boost/libs/regex/test/regress/test_locale.hpp b/src/boost/libs/regex/test/regress/test_locale.hpp new file mode 100644 index 00000000..dfc72d78 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_locale.hpp @@ -0,0 +1,90 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_locale.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Helper classes for testing locale-specific expressions. + */ + + +#ifndef BOOST_REGEX_REGRESS_TEST_LOCALE_HPP +#define BOOST_REGEX_REGRESS_TEST_LOCALE_HPP +// +// defines class test_locale that handles the locale used for testing: +// +class test_locale +{ +public: + enum{ + no_test, + test_no_locale, + test_with_locale + }; + + test_locale(const char* c_name, boost::uint32_t lcid); + ~test_locale(); + + static int c_locale_state() + { + return s_c_locale; + } + static int cpp_locale_state() + { + return s_cpp_locale; + } + static int win_locale_state() + { + return s_win_locale; + } + static const char* c_str() + { + return m_name.c_str(); + } +#ifndef BOOST_NO_STD_LOCALE + static std::locale cpp_locale() + { + return s_cpp_locale_inst; + } +#endif + static boost::uint32_t win_locale() + { + return s_win_locale_inst; + } + +private: + // the actions to take for each locale type: + static int s_c_locale; + static int s_cpp_locale; + static int s_win_locale; + // current locales: +#ifndef BOOST_NO_STD_LOCALE + static std::locale s_cpp_locale_inst; +#endif + static boost::uint32_t s_win_locale_inst; + static std::string m_name; + + // backed up versions of the previous locales and their action state: + std::string m_old_c_locale; + std::string m_old_name; + int m_old_c_state; +#ifndef BOOST_NO_STD_LOCALE + std::locale m_old_cpp_locale; +#endif + int m_old_cpp_state; + boost::uint32_t m_old_win_locale; + int m_old_win_state; + +}; + +#endif + diff --git a/src/boost/libs/regex/test/regress/test_mfc.cpp b/src/boost/libs/regex/test/regress/test_mfc.cpp new file mode 100644 index 00000000..0d855cef --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_mfc.cpp @@ -0,0 +1,551 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_mfc.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Test code for MFC/ATL strings with Boost.Regex. + */ + +// +// We can only build this if we have ATL support: +// +#include <boost/config.hpp> + +#ifdef TEST_MFC + +#include <boost/regex/mfc.hpp> +#include "test.hpp" +#include "atlstr.h" + +#pragma warning(disable:4267) + +void test_mfc(const char&, const test_regex_search_tag&) +{ + const std::string& ss = test_info<char>::search_text(); + const std::string& ss2 = test_info<char>::expression(); + CAtlStringA s(ss.c_str(), ss.size()); + CAtlStringA s2(ss2.c_str(), ss2.size()); + boost::regex_constants::match_flag_type opts = test_info<char>::match_options(); + const int* answer_table = test_info<char>::answer_table(); + boost::regex r = boost::make_regex(s2, test_info<char>::syntax_options()); + boost::cmatch what; + if(boost::regex_search( + s, + what, + r, + opts)) + { + test_result(what, s.GetString(), answer_table); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", char); + } + // + // regex_match tests: + // + if(answer_table[0] < 0) + { + if(boost::regex_match(s, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", char); + } + } + else + { + if((answer_table[0] > 0) && boost::regex_match(s, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", char); + } + else if((answer_table[0] == 0) && (answer_table[1] == static_cast<int>(ss.size()))) + { + if(boost::regex_match( + s, + what, + r, + opts)) + { + test_result(what, s.GetString(), answer_table); + if(!boost::regex_match(s, r, opts)) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", char); + } + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", char); + } + } + } + // + // test regex_iterator: + // + boost::cregex_iterator start(boost::make_regex_iterator(s, r, opts)), end; + boost::cregex_iterator copy(start); + while(start != end) + { + if(start != copy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", char); + } + if(!(start == copy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", char); + } + test_result(*start, s.GetString(), answer_table); + ++start; + ++copy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", char); + } + // + // test regex_token_iterator: + // + typedef boost::regex_token_iterator<const char*> token_iterator; + answer_table = test_info<char>::answer_table(); + // + // we start by testing sub-expression 0: + // + token_iterator tstart(boost::make_regex_token_iterator(s, r, 0, opts)), tend; + token_iterator tcopy(tstart); + while(tstart != tend) + { + if(tstart != tcopy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", char); + } + if(!(tstart == tcopy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", char); + } + test_sub_match(*tstart, s.GetString(), answer_table, 0); + ++tstart; + ++tcopy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", char); + } + // + // and now field spitting: + // + token_iterator tstart2(boost::make_regex_token_iterator(s, r, -1, opts)), tend2; + token_iterator tcopy2(tstart2); + int last_end2 = 0; + answer_table = test_info<char>::answer_table(); + while(tstart2 != tend2) + { + if(tstart2 != tcopy2) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", char); + } + if(!(tstart2 == tcopy2)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", char); + } +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first) != last_end2) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of start of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first) + << ", expected: " + << last_end2 + << ".", char); + } + int expected_end = static_cast<int>(answer_table[0] < 0 ? s.GetLength() : answer_table[0]); + if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second) != expected_end) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of end2 of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second) + << ", expected: " + << expected_end + << ".", char); + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + last_end2 = answer_table[1]; + ++tstart2; + ++tcopy2; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", char); + } + +} + +void test_mfc(const wchar_t&, const test_regex_search_tag&) +{ + const std::wstring& ss = test_info<wchar_t>::search_text(); + const std::wstring& ss2 = test_info<wchar_t>::expression(); + CAtlStringW s(ss.c_str(), ss.size()); + CAtlStringW s2(ss2.c_str(), ss2.size()); + boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options(); + const int* answer_table = test_info<wchar_t>::answer_table(); + boost::wregex r = boost::make_regex(s2, test_info<wchar_t>::syntax_options()); + boost::wcmatch what; + if(boost::regex_search( + s, + what, + r, + opts)) + { + test_result(what, s.GetString(), answer_table); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t); + } + // + // regex_match tests: + // + if(answer_table[0] < 0) + { + if(boost::regex_match(s, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", wchar_t); + } + } + else + { + if((answer_table[0] > 0) && boost::regex_match(s, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", wchar_t); + } + else if((answer_table[0] == 0) && (answer_table[1] == static_cast<int>(ss.size()))) + { + if(boost::regex_match( + s, + what, + r, + opts)) + { + test_result(what, s.GetString(), answer_table); + if(!boost::regex_match(s, r, opts)) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t); + } + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t); + } + } + } + // + // test regex_iterator: + // + boost::wcregex_iterator start(boost::make_regex_iterator(s, r, opts)), end; + boost::wcregex_iterator copy(start); + while(start != end) + { + if(start != copy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t); + } + if(!(start == copy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t); + } + test_result(*start, s.GetString(), answer_table); + ++start; + ++copy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t); + } + // + // test regex_token_iterator: + // + typedef boost::regex_token_iterator<const wchar_t*> token_iterator; + answer_table = test_info<wchar_t>::answer_table(); + // + // we start by testing sub-expression 0: + // + token_iterator tstart(boost::make_regex_token_iterator(s, r, 0, opts)), tend; + token_iterator tcopy(tstart); + while(tstart != tend) + { + if(tstart != tcopy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t); + } + if(!(tstart == tcopy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t); + } + test_sub_match(*tstart, s.GetString(), answer_table, 0); + ++tstart; + ++tcopy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t); + } + // + // and now field spitting: + // + token_iterator tstart2(boost::make_regex_token_iterator(s, r, -1, opts)), tend2; + token_iterator tcopy2(tstart2); + int last_end2 = 0; + answer_table = test_info<wchar_t>::answer_table(); + while(tstart2 != tend2) + { + if(tstart2 != tcopy2) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", wchar_t); + } + if(!(tstart2 == tcopy2)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", wchar_t); + } +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first) != last_end2) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of start of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->first) + << ", expected: " + << last_end2 + << ".", wchar_t); + } + int expected_end = static_cast<int>(answer_table[0] < 0 ? s.GetLength() : answer_table[0]); + if(boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second) != expected_end) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of end2 of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(s.GetString(), tstart2->second) + << ", expected: " + << expected_end + << ".", wchar_t); + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + last_end2 = answer_table[1]; + ++tstart2; + ++tcopy2; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", wchar_t); + } + +} + +void test_mfc(const char&, const test_invalid_regex_tag&) +{ + std::string ss = test_info<char>::expression(); + CAtlStringA s(ss.c_str(), ss.size()); + bool have_catch = false; + try{ + boost::regex e = boost::make_regex(s, test_info<char>::syntax_options()); + if(e.error_code()) + have_catch = true; + } + catch(const boost::bad_expression&) + { + have_catch = true; + } + catch(const std::runtime_error& r) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << r.what(), char); + } + catch(const std::exception& r) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << r.what(), char); + } + catch(...) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", char); + } + if(!have_catch) + { + // oops expected exception was not thrown: + BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", char); + } + +} + +void test_mfc(const wchar_t&, const test_invalid_regex_tag&) +{ + std::wstring ss = test_info<wchar_t>::expression(); + CAtlStringW s(ss.c_str(), ss.size()); + bool have_catch = false; + try{ + boost::wregex e = boost::make_regex(s, test_info<wchar_t>::syntax_options()); + if(e.error_code()) + have_catch = true; + } + catch(const boost::bad_expression&) + { + have_catch = true; + } + catch(const std::runtime_error& r) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << r.what(), wchar_t); + } + catch(const std::exception& r) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << r.what(), wchar_t); + } + catch(...) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", wchar_t); + } + if(!have_catch) + { + // oops expected exception was not thrown: + BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", wchar_t); + } +} + +void test_mfc(const char&, const test_regex_replace_tag&) +{ + const CStringA expression(test_info<char>::expression().c_str(), test_info<char>::expression().size()); + boost::regex_constants::syntax_option_type syntax_options = test_info<char>::syntax_options(); + try{ + boost::regex r = boost::make_regex(expression, syntax_options); + if(r.status()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), char); + } + const CStringA search_text(test_info<char>::search_text().c_str(), test_info<char>::search_text().size()); + boost::regex_constants::match_flag_type opts = test_info<char>::match_options(); + const CStringA format_string(test_info<char>::format_string().c_str(), test_info<char>::format_string().size()); + const CStringA result_string(test_info<char>::result_string().c_str(), test_info<char>::result_string().size()); + + CStringA result = boost::regex_replace(search_text, r, format_string, opts); + if(result != result_string) + { + BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", char); + } + } + catch(const boost::bad_expression& e) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), char); + } + catch(const std::runtime_error& r) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << r.what(), char); + } + catch(const std::exception& r) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << r.what(), char); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", char); + } +} + +void test_mfc(const wchar_t&, const test_regex_replace_tag&) +{ + const CStringW expression(test_info<wchar_t>::expression().c_str(), test_info<wchar_t>::expression().size()); + boost::regex_constants::syntax_option_type syntax_options = test_info<wchar_t>::syntax_options(); + try{ + boost::wregex r = boost::make_regex(expression, syntax_options); + if(r.status()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), wchar_t); + } + const CStringW search_text(test_info<wchar_t>::search_text().c_str(), test_info<wchar_t>::search_text().size()); + boost::regex_constants::match_flag_type opts = test_info<wchar_t>::match_options(); + const CStringW format_string(test_info<wchar_t>::format_string().c_str(), test_info<wchar_t>::format_string().size()); + const CStringW result_string(test_info<wchar_t>::result_string().c_str(), test_info<wchar_t>::result_string().size()); + + CStringW result = boost::regex_replace(search_text, r, format_string, opts); + if(result != result_string) + { + BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", wchar_t); + } + } + catch(const boost::bad_expression& e) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), wchar_t); + } + catch(const std::runtime_error& r) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << r.what(), wchar_t); + } + catch(const std::exception& r) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << r.what(), wchar_t); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", wchar_t); + } +} + +#else + +#include "test.hpp" + +void test_mfc(const char&, const test_regex_search_tag&){} +void test_mfc(const wchar_t&, const test_regex_search_tag&){} +void test_mfc(const char&, const test_invalid_regex_tag&){} +void test_mfc(const wchar_t&, const test_invalid_regex_tag&){} +void test_mfc(const char&, const test_regex_replace_tag&){} +void test_mfc(const wchar_t&, const test_regex_replace_tag&){} + + +#endif diff --git a/src/boost/libs/regex/test/regress/test_mfc.hpp b/src/boost/libs/regex/test/regress/test_mfc.hpp new file mode 100644 index 00000000..befee1c7 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_mfc.hpp @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_mfc.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: MFC/ATL test handlers. + */ + +#ifndef TEST_MFC_HPP +#define TEST_MFC_HPP + +template <class charT, class Tag> +void test_mfc(const charT&, const Tag&) +{ + // do nothing +} + +void test_mfc(const char&, const test_regex_search_tag&); +void test_mfc(const wchar_t&, const test_regex_search_tag&); +void test_mfc(const char&, const test_invalid_regex_tag&); +void test_mfc(const wchar_t&, const test_invalid_regex_tag&); +void test_mfc(const char&, const test_regex_replace_tag&); +void test_mfc(const wchar_t&, const test_regex_replace_tag&); + + +#endif diff --git a/src/boost/libs/regex/test/regress/test_non_greedy_repeats.cpp b/src/boost/libs/regex/test/regress/test_non_greedy_repeats.cpp new file mode 100644 index 00000000..3196f5ac --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_non_greedy_repeats.cpp @@ -0,0 +1,45 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_non_greedy_repeats() +{ + // + // non-greedy repeats added 21/04/00 + // + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("a*?", perl, "aa", match_default, make_array(0, 0, -2, 0, 1, -2, 1, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("^a*?$", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^.*?$", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^(a)*?$", perl, "aa", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("^[ab]*?$", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a??", perl, "aa", match_default, make_array(0, 0, -2, 0, 1, -2, 1, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("a+?", perl, "aa", match_default, make_array(0, 1, -2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a{1,3}?", perl, "aaa", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("\\w+?w", perl, "...ccccccwcccccw", match_default, make_array(3, 10, -2, 10, 16, -2, -2)); + TEST_REGEX_SEARCH("\\W+\\w+?w", perl, "...ccccccwcccccw", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH("abc|\\w+?", perl, "abd", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("abc|\\w+?", perl, "abcd", match_default, make_array(0, 3, -2, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("<\\s*tag[^>]*>(.*?)<\\s*/tag\\s*>", perl, " <tag>here is some text</tag> <tag></tag>", match_default, make_array(1, 29, 6, 23, -2, 30, 41, 35, 35, -2, -2)); + TEST_REGEX_SEARCH("<\\s*tag[^>]*>(.*?)<\\s*/tag\\s*>", perl, " < tag attr=\"something\">here is some text< /tag > <tag></tag>", match_default, make_array(1, 49, 24, 41, -2, 50, 61, 55, 55, -2, -2)); + TEST_REGEX_SEARCH("xx-{0,2}?(?:[+-][0-9])??\\z", perl, "xx--", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("xx.{0,2}?(?:[+-][0-9])??\\z", perl, "xx--", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("xx.{0,2}?(?:[+-][0-9])??\\z", perl, "xx--", match_default|match_not_dot_newline, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("xx[/-]{0,2}?(?:[+-][0-9])??\\z", perl, "xx--", match_default, make_array(0, 4, -2, -2)); + TEST_INVALID_REGEX("a{1,3}{1}", perl); + TEST_INVALID_REGEX("a**", perl); +} + diff --git a/src/boost/libs/regex/test/regress/test_not_regex.hpp b/src/boost/libs/regex/test/regress/test_not_regex.hpp new file mode 100644 index 00000000..24c22ff3 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_not_regex.hpp @@ -0,0 +1,127 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_not_regex.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Declares tests for invalid regexes. + */ + + +#ifndef BOOST_REGEX_REGRESS_TEST_NOT_REGEX_HPP +#define BOOST_REGEX_REGRESS_TEST_NOT_REGEX_HPP +#include "info.hpp" +// +// this file implements a test for a regular expression that should not compile: +// +struct test_invalid_regex_tag{}; + +template<class charT, class traits> +void test_empty(boost::basic_regex<charT, traits>& r) +{ + if(!r.empty()) + { + BOOST_REGEX_TEST_ERROR("Invalid value returned from basic_regex<>::empty().", charT); + } + if(r.size()) + { + BOOST_REGEX_TEST_ERROR("Invalid value returned from basic_regex<>::size().", charT); + } + if(r.str().size()) + { + BOOST_REGEX_TEST_ERROR("Invalid value returned from basic_regex<>::str().", charT); + } + if(r.begin() != r.end()) + { + BOOST_REGEX_TEST_ERROR("Invalid value returned from basic_regex<>::begin().", charT); + } + if(r.status() == 0) + { + BOOST_REGEX_TEST_ERROR("Invalid value returned from basic_regex<>::status().", charT); + } + if(r.begin() != r.end()) + { + BOOST_REGEX_TEST_ERROR("Invalid value returned from basic_regex<>::begin().", charT); + } +} + +template<class charT, class traits> +void test(boost::basic_regex<charT, traits>& r, const test_invalid_regex_tag&) +{ + const std::basic_string<charT>& expression = test_info<charT>::expression(); + boost::regex_constants::syntax_option_type syntax_options = test_info<charT>::syntax_options(); + // + // try it with exceptions disabled first: + // +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { + if(0 == r.assign(expression, syntax_options | boost::regex_constants::no_except).status()) + { + BOOST_REGEX_TEST_ERROR("Expression compiled when it should not have done so.", charT); + } + test_empty(r); + } +#ifndef BOOST_NO_EXCEPTIONS + catch(...) + { + BOOST_REGEX_TEST_ERROR("Unexpected exception thrown.", charT); + } +#endif + // + // now try again with exceptions: + // + bool have_catch = false; +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { + r.assign(expression, syntax_options); +#ifdef BOOST_NO_EXCEPTIONS + if(r.status()) + have_catch = true; +#endif + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression&) + { + have_catch = true; + test_empty(r); + } + catch(const std::runtime_error& e) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::runtime_error instead: " << e.what(), charT); + } + catch(const std::exception& e) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << e.what(), charT); + } + catch(...) + { + have_catch = true; + BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", charT); + } +#endif + if(!have_catch) + { + // oops expected exception was not thrown: + BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", charT); + } + +} + + + +#endif diff --git a/src/boost/libs/regex/test/regress/test_operators.cpp b/src/boost/libs/regex/test/regress/test_operators.cpp new file mode 100644 index 00000000..2f4a017b --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_operators.cpp @@ -0,0 +1,178 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" +#include <iostream> +#include <iomanip> + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300)\ + && !BOOST_WORKAROUND(__HP_aCC, BOOST_TESTED_AT(55500))\ + && !(defined(__GNUC__) && (__GNUC__ < 3) && !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION))) + +template <class T1, class T2> +void test_less(const T1& t1, const T2& t2) +{ + if(!(t1 < t2)) + { + BOOST_REGEX_TEST_ERROR("Failed < comparison", char); + } + if(!(t1 <= t2)) + { + BOOST_REGEX_TEST_ERROR("Failed <= comparison", char); + } + if(!(t1 != t2)) + { + BOOST_REGEX_TEST_ERROR("Failed != comparison", char); + } + if(t1 == t2) + { + BOOST_REGEX_TEST_ERROR("Failed == comparison", char); + } + if(t1 >= t2) + { + BOOST_REGEX_TEST_ERROR("Failed >= comparison", char); + } + if(t1 > t2) + { + BOOST_REGEX_TEST_ERROR("Failed > comparison", char); + } +} + +template <class T1, class T2> +void test_greater(const T1& t1, const T2& t2) +{ + if(t1 < t2) + { + BOOST_REGEX_TEST_ERROR("Failed < comparison", char); + } + if(t1 <= t2) + { + BOOST_REGEX_TEST_ERROR("Failed <= comparison", char); + } + if(!(t1 != t2)) + { + BOOST_REGEX_TEST_ERROR("Failed != comparison", char); + } + if(t1 == t2) + { + BOOST_REGEX_TEST_ERROR("Failed == comparison", char); + } + if(!(t1 >= t2)) + { + BOOST_REGEX_TEST_ERROR("Failed >= comparison", char); + } + if(!(t1 > t2)) + { + BOOST_REGEX_TEST_ERROR("Failed > comparison", char); + } +} + +template <class T1, class T2> +void test_equal(const T1& t1, const T2& t2) +{ + if(t1 < t2) + { + BOOST_REGEX_TEST_ERROR("Failed < comparison", char); + } + if(!(t1 <= t2)) + { + BOOST_REGEX_TEST_ERROR("Failed <= comparison", char); + } + if(t1 != t2) + { + BOOST_REGEX_TEST_ERROR("Failed != comparison", char); + } + if(!(t1 == t2)) + { + BOOST_REGEX_TEST_ERROR("Failed == comparison", char); + } + if(!(t1 >= t2)) + { + BOOST_REGEX_TEST_ERROR("Failed >= comparison", char); + } + if(t1 > t2) + { + BOOST_REGEX_TEST_ERROR("Failed > comparison", char); + } +} + +template <class T1, class T2, class T3> +void test_plus(const T1& t1, const T2& t2, const T3& t3) +{ + if(t1 + t2 != t3) + { + BOOST_REGEX_TEST_ERROR("Failed addition", char); + } + if(t3 != t1 + t2) + { + BOOST_REGEX_TEST_ERROR("Failed addition", char); + } +} + +void test_operators() +{ + test_info<char>::set_typename("sub_match operators"); + + std::string s1("a"); + std::string s2("b"); + boost::sub_match<std::string::const_iterator> sub1, sub2; + sub1.first = s1.begin(); + sub1.second = s1.end(); + sub1.matched = true; + sub2.first = s2.begin(); + sub2.second = s2.end(); + sub2.matched = true; + + test_less(sub1, sub2); + test_less(sub1, s2.c_str()); + test_less(s1.c_str(), sub2); + test_less(sub1, *s2.c_str()); + test_less(*s1.c_str(), sub2); + test_less(sub1, s2); + test_less(s1, sub2); + test_greater(sub2, sub1); + test_greater(sub2, s1.c_str()); + test_greater(s2.c_str(), sub1); + test_greater(sub2, *s1.c_str()); + test_greater(*s2.c_str(), sub1); + test_greater(sub2, s1); + test_greater(s2, sub1); + test_equal(sub1, sub1); + test_equal(sub1, s1.c_str()); + test_equal(s1.c_str(), sub1); + test_equal(sub1, *s1.c_str()); + test_equal(*s1.c_str(), sub1); + test_equal(sub1, s1); + test_equal(s1, sub1); + test_plus(sub2, sub1, "ba"); + test_plus(sub2, s1.c_str(), "ba"); + test_plus(s2.c_str(), sub1, "ba"); + test_plus(sub2, *s1.c_str(), "ba"); + test_plus(*s2.c_str(), sub1, "ba"); + test_plus(sub2, s1, "ba"); + test_plus(s2, sub1, "ba"); +} + +#else + +#include <iostream> + +void test_operators() +{ + std::cout << + "\n<note>\n" + "This compiler version does not support the sub_match comparison operators\n" + "tests for these operators are not carried out\n" + "</note>\n"; +} + +#endif + diff --git a/src/boost/libs/regex/test/regress/test_overloads.cpp b/src/boost/libs/regex/test/regress/test_overloads.cpp new file mode 100644 index 00000000..847cd498 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_overloads.cpp @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#define BOOST_REGEX_TEST(x)\ + if(!(x)){ BOOST_REGEX_TEST_ERROR("Error in: " BOOST_STRINGIZE(x), char); } + +void test_overloads() +{ + test_info<char>::set_typename("sub_match operators"); + + // test all the available overloads with *one* simple + // expression, doing all these tests with all the test + // cases would just take to long... + + boost::regex e("abc"); + std::string s("abc"); + const std::string& cs = s; + boost::smatch sm; + boost::cmatch cm; + // regex_match: + BOOST_REGEX_TEST(boost::regex_match(cs.begin(), cs.end(), sm, e)) + BOOST_REGEX_TEST(boost::regex_match(cs.begin(), cs.end(), sm, e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_match(cs.begin(), cs.end(), e)) + BOOST_REGEX_TEST(boost::regex_match(cs.begin(), cs.end(), e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_match(s.c_str(), cm, e)) + BOOST_REGEX_TEST(boost::regex_match(s.c_str(), cm, e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_match(s.c_str(), e)) + BOOST_REGEX_TEST(boost::regex_match(s.c_str(), e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_match(s, sm, e)) + BOOST_REGEX_TEST(boost::regex_match(s, sm, e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_match(s, e)) + BOOST_REGEX_TEST(boost::regex_match(s, e, boost::regex_constants::match_default)) + // regex_search: + BOOST_REGEX_TEST(boost::regex_search(cs.begin(), cs.end(), sm, e)) + BOOST_REGEX_TEST(boost::regex_search(cs.begin(), cs.end(), sm, e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_search(cs.begin(), cs.end(), e)) + BOOST_REGEX_TEST(boost::regex_search(cs.begin(), cs.end(), e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_search(s.c_str(), cm, e)) + BOOST_REGEX_TEST(boost::regex_search(s.c_str(), cm, e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_search(s.c_str(), e)) + BOOST_REGEX_TEST(boost::regex_search(s.c_str(), e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_search(s, sm, e)) + BOOST_REGEX_TEST(boost::regex_search(s, sm, e, boost::regex_constants::match_default)) + BOOST_REGEX_TEST(boost::regex_search(s, e)) + BOOST_REGEX_TEST(boost::regex_search(s, e, boost::regex_constants::match_default)) +} diff --git a/src/boost/libs/regex/test/regress/test_partial_match.hpp b/src/boost/libs/regex/test/regress/test_partial_match.hpp new file mode 100644 index 00000000..19e45866 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_partial_match.hpp @@ -0,0 +1,389 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_regex_search.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Declares tests for regex search and iteration. + */ + +#ifndef BOOST_REGEX_REGRESS_REGEX_PARTIAL_MATCH_HPP +#define BOOST_REGEX_REGRESS_REGEX_PARTIAL_MATCH_HPP +#include "info.hpp" +// +// this file implements a test for a regular expression that should compile, +// followed by a search for that expression: +// +struct test_regex_search_tag{}; + +template <class BidirectionalIterator> +void test_sub_match(const boost::sub_match<BidirectionalIterator>& sub, BidirectionalIterator base, const int* answer_table, int i) +{ +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + typedef typename boost::sub_match<BidirectionalIterator>::value_type charT; + if((sub.matched == 0) + && + !((i == 0) + && (test_info<charT>::match_options() & boost::match_partial)) ) + { + if(answer_table[2*i] >= 0) + { + BOOST_REGEX_TEST_ERROR( + "Sub-expression " << i + << " was not matched when it should have been.", charT); + } + } + else + { + if(boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.first) != answer_table[2*i]) + { + BOOST_REGEX_TEST_ERROR( + "Error in start location of sub-expression " + << i << ", found " << boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.first) + << ", expected " << answer_table[2*i] << ".", charT); + } + if(boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.second) != answer_table[1+ 2*i]) + { + BOOST_REGEX_TEST_ERROR( + "Error in end location of sub-expression " + << i << ", found " << boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.second) + << ", expected " << answer_table[1 + 2*i] << ".", charT); + } + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +} + +template <class BidirectionalIterator, class Allocator> +void test_result(const boost::match_results<BidirectionalIterator, Allocator>& what, BidirectionalIterator base, const int* answer_table) +{ + for(unsigned i = 0; i < what.size(); ++i) + { + test_sub_match(what[i], base, answer_table, i); + } +} + +template<class charT, class traits> +void test_simple_search(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + boost::match_results<const_iterator> what; + if(boost::regex_search( + search_text.begin(), + search_text.end(), + what, + r, + opts)) + { + test_result(what, search_text.begin(), answer_table); + // setting match_any should have no effect on the result returned: + if(!boost::regex_search( + search_text.begin(), + search_text.end(), + r, + opts|boost::regex_constants::match_any)) + { + BOOST_REGEX_TEST_ERROR("Expected match was not found when using the match_any flag.", charT); + } + } + else + { + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } + // setting match_any should have no effect on the result returned: + else if(boost::regex_search( + search_text.begin(), + search_text.end(), + r, + opts|boost::regex_constants::match_any)) + { + BOOST_REGEX_TEST_ERROR("Unexpected match was found when using the match_any flag.", charT); + } + } +} + +template<class charT, class traits> +void test_regex_iterator(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + typedef boost::regex_iterator<const_iterator, charT, traits> test_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + test_iterator start(search_text.begin(), search_text.end(), r, opts), end; + test_iterator copy(start); + const_iterator last_end = search_text.begin(); + while(start != end) + { + if(start != copy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", charT); + } + if(!(start == copy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", charT); + } + test_result(*start, search_text.begin(), answer_table); + // test $` and $' : + if(start->prefix().first != last_end) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for start of $`", charT); + } + if(start->prefix().second != (*start)[0].first) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for end of $`", charT); + } + if(start->prefix().matched != (start->prefix().first != start->prefix().second)) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $`", charT); + } + if(start->suffix().first != (*start)[0].second) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for start of $'", charT); + } + if(start->suffix().second != search_text.end()) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for end of $'", charT); + } + if(start->suffix().matched != (start->suffix().first != start->suffix().second)) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $'", charT); + } + last_end = (*start)[0].second; + ++start; + ++copy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } +} + +template<class charT, class traits> +void test_regex_token_iterator(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + typedef boost::regex_token_iterator<const_iterator, charT, traits> test_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + // + // we start by testing sub-expression 0: + // + test_iterator start(search_text.begin(), search_text.end(), r, 0, opts), end; + test_iterator copy(start); + while(start != end) + { + if(start != copy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", charT); + } + if(!(start == copy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", charT); + } + test_sub_match(*start, search_text.begin(), answer_table, 0); + ++start; + ++copy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } + // + // and now field spitting: + // + test_iterator start2(search_text.begin(), search_text.end(), r, -1, opts), end2; + test_iterator copy2(start2); + int last_end2 = 0; + answer_table = test_info<charT>::answer_table(); + while(start2 != end2) + { + if(start2 != copy2) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", charT); + } + if(!(start2 == copy2)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", charT); + } +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if(boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->first) != last_end2) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of start of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->first) + << ", expected: " + << last_end2 + << ".", charT); + } + int expected_end = static_cast<int>(answer_table[0] < 0 ? search_text.size() : answer_table[0]); + if(boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->second) != expected_end) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of end2 of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->second) + << ", expected: " + << expected_end + << ".", charT); + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + last_end2 = answer_table[1]; + ++start2; + ++copy2; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } +} + +template <class charT, class traits> +struct grep_test_predicate +{ + typedef typename std::basic_string<charT>::const_iterator test_iter; + + grep_test_predicate(test_iter b, const int* a) + : m_base(b), m_table(a) + {} + bool operator()(const boost::match_results<test_iter>& what) + { + test_result(what, m_base, m_table); + // move on the answer table to next set of answers; + if(*m_table != -2) + while(*m_table++ != -2){} + return true; + } +private: + test_iter m_base; + const int* m_table; +}; + +template<class charT, class traits> +void test_regex_grep(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + grep_test_predicate<charT, traits> pred(search_text.begin(), answer_table); + boost::regex_grep(pred, search_text.begin(), search_text.end(), r, opts); +} + +template<class charT, class traits> +void test_regex_match(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + boost::match_results<const_iterator> what; + if(answer_table[0] < 0) + { + if(boost::regex_match(search_text, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", charT); + } + } + else + { + if((answer_table[0] > 0) && boost::regex_match(search_text, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", charT); + } + else if((answer_table[0] == 0) && (answer_table[1] == static_cast<int>(search_text.size()))) + { + if(boost::regex_match( + search_text.begin(), + search_text.end(), + what, + r, + opts)) + { + test_result(what, search_text.begin(), answer_table); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } + } + } +} + +template<class charT, class traits> +void test(boost::basic_regex<charT, traits>& r, const test_regex_search_tag&) +{ + const std::basic_string<charT>& expression = test_info<charT>::expression(); + boost::regex_constants::syntax_option_type syntax_options = test_info<charT>::syntax_options(); + try{ + r.assign(expression, syntax_options); + if(r.status()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), charT); + } + test_simple_search(r); + test_regex_iterator(r); + test_regex_token_iterator(r); + test_regex_grep(r); + test_regex_match(r); + } + catch(const boost::bad_expression& e) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), charT); + } + catch(const std::runtime_error& r) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << r.what(), charT); + } + catch(const std::exception& r) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << r.what(), charT); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", charT); + } + +} + + + +#endif + diff --git a/src/boost/libs/regex/test/regress/test_perl_ex.cpp b/src/boost/libs/regex/test/regress/test_perl_ex.cpp new file mode 100644 index 00000000..6a53256d --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_perl_ex.cpp @@ -0,0 +1,1019 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_options3(); + +void test_independent_subs() +{ + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("(?>^abc)", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?>^abc)", perl, "def\nabc", match_default, make_array(4, 7, -2, -2)); + TEST_REGEX_SEARCH("(?>^abc)", perl, "defabc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?>.*/)foo", perl, "/this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?>.*/)foo", perl, "/this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo", match_default, make_array(0, 67, -2, -2)); + TEST_REGEX_SEARCH("(?>(\\.\\d\\d[1-9]?))\\d+", perl, "1.230003938", match_default, make_array(1, 11, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("(?>(\\.\\d\\d[1-9]?))\\d+", perl, "1.875000282", match_default, make_array(1, 11, 1, 5, -2, -2)); + TEST_REGEX_SEARCH("(?>(\\.\\d\\d[1-9]?))\\d+", perl, "1.235", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^((?>\\w+)|(?>\\s+))*$", perl, "now is the time for all good men to come to the aid of the party", match_default, make_array(0, 64, 59, 64, -2, -2)); + TEST_REGEX_SEARCH("^((?>\\w+)|(?>\\s+))*$", perl, "this is not a line with only words and spaces!", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?>\\d+))(\\w)", perl, "12345a", match_default, make_array(0, 6, 0, 5, 5, 6, -2, -2)); + TEST_REGEX_SEARCH("((?>\\d+))(\\w)", perl, "12345+", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?>\\d+))(\\d)", perl, "12345", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?>a+)b", perl, "aaab", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("((?>a+)b)", perl, "aaab", match_default, make_array(0, 4, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?>(a+))b", perl, "aaab", match_default, make_array(0, 4, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?>b)+", perl, "aaabbbccc", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?>a+|b+|c+)*c", perl, "aaabbbbccccd", match_default, make_array(0, 8, -2, 8, 9, -2, 9, 10, -2, 10, 11, -2, -2)); + TEST_REGEX_SEARCH("((?>[^()]+)|\\([^()]*\\))+", perl, "((abc(ade)ufh()()x", match_default, make_array(2, 18, 17, 18, -2, -2)); + TEST_REGEX_SEARCH("\\(((?>[^()]+)|\\([^()]+\\))+\\)", perl, "(abc)", match_default, make_array(0, 5, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\(((?>[^()]+)|\\([^()]+\\))+\\)", perl, "(abc(def)xyz)", match_default, make_array(0, 13, 9, 12, -2, -2)); + TEST_REGEX_SEARCH("\\(((?>[^()]+)|\\([^()]+\\))+\\)", perl, "((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?>a*)*", perl, "a", match_default, make_array(0, 1, -2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("(?>a*)*", perl, "aa", match_default, make_array(0, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("(?>a*)*", perl, "aaaa", match_default, make_array(0, 4, -2, 4, 4, -2, -2)); + TEST_REGEX_SEARCH("(?>a*)*", perl, "a", match_default, make_array(0, 1, -2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("(?>a*)*", perl, "aaabcde", match_default, make_array(0, 3, -2, 3, 3, -2, 4, 4, -2, 5, 5, -2, 6, 6, -2, 7, 7, -2, -2)); + TEST_REGEX_SEARCH("((?>a*))*", perl, "aaaaa", match_default, make_array(0, 5, 5, 5, -2, 5, 5, 5, 5, -2, -2)); + TEST_REGEX_SEARCH("((?>a*))*", perl, "aabbaa", match_default, make_array(0, 2, 2, 2, -2, 2, 2, 2, 2, -2, 3, 3, 3, 3, -2, 4, 6, 6, 6, -2, 6, 6, 6, 6, -2, -2)); + TEST_REGEX_SEARCH("((?>a*?))*", perl, "aaaaa", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 2, 2, 2, 2, -2, 3, 3, 3, 3, -2, 4, 4, 4, 4, -2, 5, 5, 5, 5, -2, -2)); + TEST_REGEX_SEARCH("((?>a*?))*", perl, "aabbaa", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 2, 2, 2, 2, -2, 3, 3, 3, 3, -2, 4, 4, 4, 4, -2, 5, 5, 5, 5, -2, 6, 6, 6, 6, -2, -2)); + TEST_REGEX_SEARCH("word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword", perl, "word cat dog elephant mussel cow horse canary baboon snake shark otherword", match_default, make_array(0, 74, -2, -2)); + TEST_REGEX_SEARCH("word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword", perl, "word cat dog elephant mussel cow horse canary baboon snake shark", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("word (?>[a-zA-Z0-9]+ ){0,30}otherword", perl, "word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("word (?>[a-zA-Z0-9]+ ){0,30}otherword", perl, "word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I really really hope otherword", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?>Z)+|A)+", perl, "ZABCDEFG", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_INVALID_REGEX("((?>)+|A)+", perl); +} + +void test_conditionals() +{ + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("(?:(a)|b)(?(1)A|B)", perl, "aA", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?:(a)|b)(?(1)A|B)", perl, "bB", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("(?:(a)|b)(?(1)A|B)", perl, "aB", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:(a)|b)(?(1)A|B)", perl, "bA", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(a)?(?(1)A)B", perl, "aAB", match_default, make_array(0, 3, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)?(?(1)A)B", perl, "B", match_default, make_array(0, 1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(a)?(?(1)|A)B", perl, "aB", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(a)?(?(1)|A)B", perl, "AB", match_default, make_array(0, 2, -1, -1, -2, -2)); + + TEST_REGEX_SEARCH("^(a)?(?(1)a|b)+$", perl, "aa", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^(a)?(?(1)a|b)+$", perl, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("^(a)?(?(1)a|b)+$", perl, "bb", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^(a)?(?(1)a|b)+$", perl, "ab", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("^(?(?=abc)\\w{3}:|\\d\\d)$", perl, "abc:", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^(?(?=abc)\\w{3}:|\\d\\d)$", perl, "12", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^(?(?=abc)\\w{3}:|\\d\\d)$", perl, "123", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?(?=abc)\\w{3}:|\\d\\d)$", perl, "xyz", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("^(?(?!abc)\\d\\d|\\w{3}:)$", perl, "abc:", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^(?(?!abc)\\d\\d|\\w{3}:)$", perl, "12", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("^(?(?!abc)\\d\\d|\\w{3}:)$", perl, "123", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?(?!abc)\\d\\d|\\w{3}:)$", perl, "xyz", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?(?<=foo)bar|cat)", perl, "foobar", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?(?<=foo)bar|cat)", perl, "cat", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?(?<=foo)bar|cat)", perl, "fcat", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("(?(?<=foo)bar|cat)", perl, "focat", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("(?(?<=foo)bar|cat)", perl, "foocat", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?(?<!foo)cat|bar)", perl, "foobar", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?(?<!foo)cat|bar)", perl, "cat", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?(?<!foo)cat|bar)", perl, "fcat", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("(?(?<!foo)cat|bar)", perl, "focat", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("(?(?<!foo)cat|bar)", perl, "foocat", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(\\()?[^()]+(?(1)\\))", perl, "abcd", match_default, make_array(0, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(\\()?[^()]+(?(1)\\))", perl, "(abcd)", match_default, make_array(0, 6, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(\\()?[^()]+(?(1)\\))", perl, "the quick (abcd) fox", match_default, make_array(0, 10, -1, -1, -2, 10, 16, 10, 11, -2, 16, 20, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(\\()?[^()]+(?(1)\\))", perl, "(abcd", match_default, make_array(1, 5, -1, -1, -2, -2)); + + TEST_REGEX_SEARCH("^(?(2)a|(1)(2))+$", perl, "12", match_default, make_array(0, 2, 0, 1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("^(?(2)a|(1)(2))+$", perl, "12a", match_default, make_array(0, 3, 0, 1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("^(?(2)a|(1)(2))+$", perl, "12aa", match_default, make_array(0, 4, 0, 1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("^(?(2)a|(1)(2))+$", perl, "1234", match_default, make_array(-2, -2)); + + 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)(?(?<a", perl); + + TEST_INVALID_REGEX("(?(?!#?)+)", perl); + TEST_INVALID_REGEX("(?(?=:-){0})", perl); + TEST_INVALID_REGEX("(?(123){1})", perl); + TEST_INVALID_REGEX("(?(?<=A)*)", perl); + TEST_INVALID_REGEX("(?(?<=A)+)", perl); + + TEST_INVALID_REGEX("(?<!*|^)", perl); + TEST_INVALID_REGEX("(?<!*|A)", perl); + TEST_INVALID_REGEX("(?<=?|A)", perl); + TEST_INVALID_REGEX("(?<=*|\\B)", perl); + TEST_INVALID_REGEX("(?<!a|bc)de", perl); + TEST_INVALID_REGEX("(?<=a|bc)de", perl); + + // Bug reports: + TEST_REGEX_SEARCH("\\b(?:(?:(one)|(two)|(three))(?:,|\\b)){3,}(?(1)|(?!))(?(2)|(?!))(?(3)|(?!))", perl, "one,two,two, one", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b(?:(?:(one)|(two)|(three))(?:,|\\b)){3,}(?(1)|(?!))(?(2)|(?!))(?(3)|(?!))", perl, "one,three,two", match_default, make_array(0, 13, 0, 3, 10, 13, 4, 9, -2, -2)); + TEST_REGEX_SEARCH("\\b(?:(?:(one)|(two)|(three))(?:,|\\b)){3,}(?(1)|(?!))(?(2)|(?!))(?(3)|(?!))", perl, "one,two,two,one,three,four", match_default, make_array(0, 22, 12, 15, 8, 11, 16, 21, -2, -2)); +} + +void test_options() +{ + // test the (?imsx) construct: + using namespace boost::regex_constants; + TEST_INVALID_REGEX("(?imsx", perl); + TEST_INVALID_REGEX("(?g", 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|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|no_mod_m, "abc\nabc", match_default, make_array(0, 3, -2, 4, 7, -2, -2)); + + TEST_REGEX_SEARCH(" ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)", perl|mod_x, "ab c", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH(" ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)", perl|mod_x, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH(" ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)", perl|mod_x, "ab cde", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)", perl, "ab c", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?x) ^ a (?# begins with a) b\\sc (?# then b c) $ (?# then end)", perl, "ab cde", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ a\\ b[c ]d $", perl|mod_x, "a bcd", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("^ a\\ b[c ]d $", perl|mod_x, "a b d", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("^ a\\ b[c ]d $", perl|mod_x, "abcd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^ a\\ b[c ]d $", perl|mod_x, "ab d", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("^1234(?# test newlines\n inside)", perl|mod_x, "1234", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^1234 #comment in boost::regex::extended re\n", perl|mod_x, "1234", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("#rhubarb\n abcd", perl|mod_x, "abcd", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^1234 #comment in boost::regex::extended re\r\n", perl|mod_x, "1234", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("#rhubarb\r\n abcd", perl|mod_x, "abcd", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^abcd#rhubarb", perl|mod_x, "abcd", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("^abcd#rhubarb", perl, "abcd#rhubarb", match_default, make_array(0, 12, -2, -2)); + TEST_REGEX_SEARCH("^a b\n\n c", perl|mod_x, "abc", match_default, make_array(0, 3, -2, -2)); + + TEST_REGEX_SEARCH("(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ", perl|mod_x, "12-sep-98", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ", perl|mod_x, "12-09-98", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("(?(?=[^a-z]+[a-z]) \\d{2}-[a-z]{3}-\\d{2} | \\d{2}-\\d{2}-\\d{2} ) ", perl|mod_x, "sep-12-98", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^a (?#xxx) (?#yyy) {3}c", perl|mod_x, "aaac", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab", perl|mod_x, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH(" abc\\Q abc\\Eabc", perl|mod_x, "abc abcabc", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH(" abc\\Q abc\\Eabc", perl|mod_x, "abcabcabc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("abc#comment\n \\Q#not comment\n literal\\E", perl|mod_x, "abc#not comment\n literal", match_default, make_array(0, 27, -2, -2)); + TEST_REGEX_SEARCH("abc#comment\n \\Q#not comment\n literal", perl|mod_x, "abc#not comment\n literal", match_default, make_array(0, 27, -2, -2)); + TEST_REGEX_SEARCH("abc#comment\n \\Q#not comment\n literal\\E #more comment\n ", perl|mod_x, "abc#not comment\n literal", match_default, make_array(0, 27, -2, -2)); + TEST_REGEX_SEARCH("abc#comment\n \\Q#not comment\n literal\\E #more comment", perl|mod_x, "abc#not comment\n literal", match_default, make_array(0, 27, -2, -2)); + + TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "a bcd e", match_default, make_array(0, 7, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "a b cd e", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "abcd e", 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, "abcdef", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("a(?x: b c )d", perl, "XabcdY", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("a(?x: b c )d", perl, "Xa b c d Y", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?x)x y z | a b c)", perl, "XabcY", match_default, make_array(1, 4, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("((?x)x y z | a b c)", perl, "AxyzB", match_default, make_array(1, 4, 1, 4, -2, -2)); + + TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "a bcd e", match_default, make_array(0, 7, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "a b cd e", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(a (?x)b c)d e", perl, "abcd e", 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, "abcdef", match_default, make_array(-2, -2)); + + TEST_INVALID_REGEX("a++(?#abc)+", perl); + TEST_INVALID_REGEX("a++(?#abc)?", perl); + TEST_INVALID_REGEX("a++(?#abc)*", perl); + TEST_INVALID_REGEX("a++(?#abc){2}", perl); + TEST_INVALID_REGEX("a++(?#abc)(?#more)+", perl); + TEST_REGEX_SEARCH("(?x) ab (?#first comment) (?#more) +", perl, "abbbb", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab(?#first comment)(?#more)+", perl, "abbbb", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("(?x) ab (?#first comment) (?#more) (c)", perl, "abc", match_default, make_array(0, 3, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("ab(?#first comment)(?#more)(c)", perl, "abc", match_default, make_array(0, 3, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("(?x) ab (?#first comment) (?#more) (?:c)", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("ab(?#first comment)(?#more)(?:c)", perl, "abc", match_default, make_array(0, 3, -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(-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)); + 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)); + TEST_REGEX_SEARCH("(a(?i)b)c", perl, "AbC", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "hog", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "dog", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "Hog", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?i)[dh]og", perl, "Dog", match_default, make_array(0, 3, -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)); + 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)); + 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)); + + TEST_REGEX_SEARCH("a(?i:b)c", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(?i:b)c", perl, "aBc", match_default, make_array(0, 3, -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)); + 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(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a(?i:b)*c", perl, "aBBc", match_default, make_array(0, 4, -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, "aBBC", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "J", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "j", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "h", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?i:j)|h", perl, "H", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("a(?=b(?i)c)\\w\\wd", perl, "abcd", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a(?=b(?i)c)\\w\\wd", perl, "abCd", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a(?=b(?i)c)\\w\\wd", perl, "aBCd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(?=b(?i)c)\\w\\wd", perl, "abcD", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "more than million", match_default, make_array(0, 17, -2, -2)); + TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "more than MILLION", match_default, make_array(0, 17, -2, -2)); + TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "more \n than Million", match_default, make_array(0, 19, -2, -2)); + TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "MORE THAN MILLION", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase|no_mod_s|no_mod_m, "more \n than \n million", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "more than million", match_default, make_array(0, 17, -2, -2)); + TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "more than MILLION", match_default, make_array(0, 17, -2, -2)); + TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "more \n than Million", match_default, make_array(0, 19, -2, -2)); + TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "MORE THAN MILLION", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase|no_mod_s|no_mod_m, "more \n than \n million", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?>a(?i)b+)+c", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?>a(?i)b+)+c", perl, "aBbc", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?>a(?i)b+)+c", perl, "aBBc", match_default, make_array(0, 4, -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, "abAb", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?>a(?i)b+)+c", perl, "abbC", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?=a(?i)b)\\w\\wc", perl, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?=a(?i)b)\\w\\wc", perl, "aBc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?=a(?i)b)\\w\\wc", perl, "Ab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?=a(?i)b)\\w\\wc", perl, "abC", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?=a(?i)b)\\w\\wc", perl, "aBC", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "abxxc", match_default, make_array(2, 5, 2, 4, -2, -2)); + TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "aBxxc", match_default, make_array(2, 5, 2, 4, -2, -2)); + TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "Abxxc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "ABxxc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?<=a(?i)b)(\\w\\w)c", perl, "abxxC", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?<=^.{4})(?:bar|cat)", perl, "fooocat", match_default, make_array(4, 7, -2, -2)); + TEST_REGEX_SEARCH("(?<=^.{4})(?:bar|cat)", perl, "foocat", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?<=^a{4})(?:bar|cat)", perl, "aaaacat", match_default, make_array(4, 7, -2, -2)); + TEST_REGEX_SEARCH("(?<=^a{4})(?:bar|cat)", perl, "aaacat", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?<=^[[:alpha:]]{4})(?:bar|cat)", perl, "aaaacat", match_default, make_array(4, 7, -2, -2)); + TEST_REGEX_SEARCH("(?<=^[[:alpha:]]{4})(?:bar|cat)", perl, "aaacat", match_default, make_array(-2, -2)); + + //TEST_REGEX_SEARCH("(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "abxyZZ", match_default, make_array(4, 6, -2, -2)); + //TEST_REGEX_SEARCH("(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "abXyZZ", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "ZZZ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "zZZ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "bZZ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "BZZ", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "ZZ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "abXYZZ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "zzz", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:ab(?i)x(?-i)y|(?i)z|b)ZZ", perl, "bzz", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("((?-i)[[:lower:]])[[:lower:]]", perl|icase, "ab", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("((?-i)[[:lower:]])[[:lower:]]", perl|icase, "aB", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("((?-i)[[:lower:]])[[:lower:]]", perl|icase, "Ab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?-i)[[:lower:]])[[:lower:]]", perl|icase, "AB", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("a(?-i)b", perl|icase, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a(?-i)b", perl|icase, "Ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a(?-i)b", perl|icase, "aB", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(?-i)b", perl|icase, "AB", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?:(?-i)a)b", perl|icase, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("((?-i)a)b", perl|icase, "ab", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?:(?-i)a)b", perl|icase, "aB", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("((?-i)a)b", perl|icase, "aB", match_default, make_array(0, 2, 0, 1, -2, -2)); + + TEST_REGEX_SEARCH("(?:(?-i)a)b", perl|icase, "Ab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:(?-i)a)b", perl|icase, "aB", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("((?-i)a)b", perl|icase, "aB", match_default, make_array(0, 2, 0, 1, -2, -2)); + + TEST_REGEX_SEARCH("(?:(?-i)a)b", perl|icase, "Ab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:(?-i)a)b", perl|icase, "AB", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?-i:a)b", perl|icase, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("((?-i:a))b", perl|icase, "ab", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?-i:a)b", perl|icase, "aB", match_default, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("((?-i:a))b", perl|icase, "aB", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?-i:a)b", perl|icase, "AB", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?-i:a)b", perl|icase, "Ab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?-i:a)b", perl|icase, "aB", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("((?-i:a))b", perl|icase, "aB", match_default, make_array(0, 2, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?-i:a)b", perl|icase, "Ab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?-i:a)b", perl|icase, "AB", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?-i:a.))b", perl|icase, "AB", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?-i:a.))b", perl|icase, "A\nB", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((?s-i:a.))b", perl|icase, "a\nB", match_default, make_array(0, 3, 0, 2, -2, -2)); + + TEST_REGEX_SEARCH(".", perl, "\n", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl, "\n", match_default|match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", perl|mod_s, "\n", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl|mod_s, "\n", match_default|match_not_dot_newline, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(".", perl|no_mod_s, "\n", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH(".", perl|no_mod_s, "\n", match_default|match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?s).", perl, "\n", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?s).", perl, "\n", match_default|match_not_dot_newline, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?-s).", perl, "\n", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?-s).", perl, "\n", match_default|match_not_dot_newline, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?-xism)d", perl, "d", match_default, make_array(0, 1, -2, -2)); + test_options3(); +} + +void test_options3() +{ + using namespace boost::regex_constants; + + TEST_REGEX_SEARCH(".+", perl, " \n ", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH(".+", perl, " \n ", match_default|match_not_dot_newline, make_array(0, 2, -2, 3, 5, -2, -2)); + TEST_REGEX_SEARCH(".+", perl|mod_s, " \n ", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH(".+", perl|mod_s, " \n ", match_default|match_not_dot_newline, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH(".+", perl|no_mod_s, " \n ", match_default, make_array(0, 2, -2, 3, 5, -2, -2)); + TEST_REGEX_SEARCH(".+", perl|no_mod_s, " \n ", match_default|match_not_dot_newline, make_array(0, 2, -2, 3, 5, -2, -2)); + TEST_REGEX_SEARCH("(?s).+", perl, " \n ", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("(?s).+", perl, " \n ", match_default|match_not_dot_newline, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("(?-s).+", perl, " \n ", match_default, make_array(0, 2, -2, 3, 5, -2, -2)); + TEST_REGEX_SEARCH("(?-s).+", perl, " \n ", match_default|match_not_dot_newline, make_array(0, 2, -2, 3, 5, -2, -2)); + + const char* big_expression = +" (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* # optional leading comment\n" +"(?: (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"|\n" +"\" (?: # opening quote...\n" +"[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n" +"| # or\n" +"\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n" +")* \" # closing quote\n" +") # initial word\n" +"(?: (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* \\. (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"|\n" +"\" (?: # opening quote...\n" +"[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n" +"| # or\n" +"\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n" +")* \" # closing quote\n" +") )* # further okay, if led by a period\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* @ (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # initial subdomain\n" +"(?: #\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* \\. # if led by a period...\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # ...further okay\n" +")*\n" +"# address\n" +"| # or\n" +"(?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"|\n" +"\" (?: # opening quote...\n" +"[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n" +"| # or\n" +"\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n" +")* \" # closing quote\n" +") # one word, optionally followed by....\n" +"(?:\n" +"[^()<>@,;:\".\\\\\\[\\]\\x80-\\xff\\000-\\010\\012-\\037] | # atom and space parts, or...\n" +"\\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) | # comments, or...\n" +"\" (?: # opening quote...\n" +"[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n" +"| # or\n" +"\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n" +")* \" # closing quote\n" +"# quoted strings\n" +")*\n" +"< (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* # leading <\n" +"(?: @ (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # initial subdomain\n" +"(?: #\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* \\. # if led by a period...\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # ...further okay\n" +")*\n" +"(?: (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* , (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* @ (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # initial subdomain\n" +"(?: #\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* \\. # if led by a period...\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # ...further okay\n" +")*\n" +")* # further okay, if led by comma\n" +": # closing colon\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* )? # optional route\n" +"(?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"|\n" +"\" (?: # opening quote...\n" +"[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n" +"| # or\n" +"\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n" +")* \" # closing quote\n" +") # initial word\n" +"(?: (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* \\. (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"|\n" +"\" (?: # opening quote...\n" +"[^\\\\\\x80-\\xff\\n\\015\"] # Anything except backslash and quote\n" +"| # or\n" +"\\\\ [^\\x80-\\xff] # Escaped something (something != CR)\n" +")* \" # closing quote\n" +") )* # further okay, if led by a period\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* @ (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # initial subdomain\n" +"(?: #\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* \\. # if led by a period...\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* (?:\n" +"[^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]+ # some number of atom characters...\n" +"(?![^(\\040)<>@,;:\".\\\\\\[\\]\\000-\\037\\x80-\\xff]) # ..not followed by something that could be part of an atom\n" +"| \\[ # [\n" +"(?: [^\\\\\\x80-\\xff\\n\\015\\[\\]] | \\\\ [^\\x80-\\xff] )* # stuff\n" +"\\] # ]\n" +") # ...further okay\n" +")*\n" +"# address spec\n" +"(?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* > # trailing >\n" +"# name and address\n" +") (?: [\\040\\t] | \\(\n" +"(?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] | \\( (?: [^\\\\\\x80-\\xff\\n\\015()] | \\\\ [^\\x80-\\xff] )* \\) )*\n" +"\\) )* # optional trailing comment\n" +"\n"; + + do{ + test_info<char>::set_info(__FILE__, __LINE__, + big_expression, + perl|mod_x, "Alan Other <user@dom.ain>", match_default, + make_array(0, 25, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#if !defined(BOOST_NO_WREGEX) && !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + do{ + std::string st(big_expression); + test_info<wchar_t>::set_info(__FILE__, __LINE__, + std::wstring(st.begin(), st.end()), + perl|mod_x, L"Alan Other <user@dom.ain>", match_default, + make_array(0, 25, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#endif + do{ + test_info<char>::set_info(__FILE__, __LINE__, + big_expression, + perl|mod_x, "<user@dom.ain>", match_default, + 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) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + do{ + std::string st(big_expression); + test_info<wchar_t>::set_info(__FILE__, __LINE__, + std::wstring(st.begin(), st.end()), + perl|mod_x, L"<user@dom.ain>", match_default, + make_array(1, 13, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#endif + do{ + test_info<char>::set_info(__FILE__, __LINE__, + big_expression, + perl|mod_x, "\"A. Other\" <user.1234@dom.ain> (a comment)", match_default, + 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) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + do{ + std::string st(big_expression); + test_info<wchar_t>::set_info(__FILE__, __LINE__, + std::wstring(st.begin(), st.end()), + perl|mod_x, L"\"A. Other\" <user.1234@dom.ain> (a comment)", match_default, + make_array(0, 42, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#endif + do{ + test_info<char>::set_info(__FILE__, __LINE__, + big_expression, + perl|mod_x, "A. Other <user.1234@dom.ain> (a comment)", match_default, + 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) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + do{ + std::string st(big_expression); + test_info<wchar_t>::set_info(__FILE__, __LINE__, + std::wstring(st.begin(), st.end()), + perl|mod_x, L"A. Other <user.1234@dom.ain> (a comment)", match_default, + make_array(2, 40, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#endif + do{ + test_info<char>::set_info(__FILE__, __LINE__, + big_expression, + perl|mod_x, "\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay", match_default, + 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) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + do{ + std::string st(big_expression); + test_info<wchar_t>::set_info(__FILE__, __LINE__, + std::wstring(st.begin(), st.end()), + perl|mod_x, L"\"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"@x400-re.lay", match_default, + make_array(0, 61, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#endif + do{ + test_info<char>::set_info(__FILE__, __LINE__, + big_expression, + perl|mod_x, "A missing angle <user@some.where", match_default, + 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) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + do{ + std::string st(big_expression); + test_info<wchar_t>::set_info(__FILE__, __LINE__, + std::wstring(st.begin(), st.end()), + perl|mod_x, L"A missing angle <user@some.where", match_default, + make_array(17, 32, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#endif +} + +void test_mark_resets() +{ + using namespace boost::regex_constants; + + TEST_REGEX_SEARCH("(?|(abc)|(xyz))", perl, "abc", match_default, make_array(0, 3, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))", perl, "xyz", match_default, make_array(0, 3, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(x)(?|(abc)|(xyz))(x)", perl, "xabcx", match_default, make_array(0, 5, 0, 1, 1, 4, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("(x)(?|(abc)|(xyz))(x)", perl, "xxyzx", match_default, make_array(0, 5, 0, 1, 1, 4, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("(x)(?|(abc)(pqr)|(xyz))(x)", perl, "xabcpqrx", match_default, make_array(0, 8, 0, 1, 1, 4, 4, 7, 7, 8, -2, -2)); + TEST_REGEX_SEARCH("(x)(?|(abc)(pqr)|(xyz))(x)", perl, "xxyzx", match_default, make_array(0, 5, 0, 1, 1, 4, -1, -1, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))\\1", perl, "abcabc", match_default, make_array(0, 6, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))\\1", perl, "xyzxyz", match_default, make_array(0, 6, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))\\1", perl, "abcxyz", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))\\1", perl, "xyzabc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))(?1)", perl, "abcabc", match_default, make_array(0, 6, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))(?1)", perl, "xyzabc", match_default, make_array(0, 6, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))(?1)", perl, "xyzxyz", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^X(?5)(a)(?|(b)|(q))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_INVALID_REGEX("^X(?5)(a)(?|(b)|(q))(c)(d)Y", perl); + TEST_REGEX_SEARCH("^X(?&N)(a)(?|(b)|(q))(c)(d)(?<N>Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_REGEX_SEARCH("^X(?7)(a)(?|(b)|(q)(r)(s))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, -1, -1, -1, -1, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_REGEX_SEARCH("^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, -1, -1, -1, -1, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_REGEX_SEARCH("^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, -1, -1, -1, -1, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(?:((?:xyz)))|(123))", perl, "abc", match_default, make_array(0, 3, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(?:)((?:)xyz)|(123))", perl, "xyz", match_default, make_array(0, 3, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|((?:(x)|(y)|(z)))|(123))", perl, "y", match_default, make_array(0, 1, 0, 1, -1, -1, 0, 1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|((?|(x)|(y)|(z)))|(123))", perl, "y", match_default, make_array(0, 1, 0, 1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|((?|(x)|(y)|(z)))|(123))", perl, "abc", match_default, make_array(0, 3, 0, 3, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|((?|(x)|(y)|(z)))|(123))", perl, "123", match_default, make_array(0, 3, 0, 3, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|((x)|(y)|(z))|(123))", perl, "z", match_default, make_array(0, 1, 0, 1, -1, -1, -1, -1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|((x)|(y)|(z))|(123))", perl, "abc", match_default, make_array(0, 3, 0, 3, -1, -1, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|((x)|(y)|(z))|(123))", perl, "123", match_default, make_array(0, 3, 0, 3, -1, -1, -1, -1, -1, -1, -2, -2)); +} + +void test_recursion() +{ + using namespace boost::regex_constants; + + TEST_INVALID_REGEX("(a(?2)b)", perl); + TEST_INVALID_REGEX("(a(?1b))", perl); + TEST_REGEX_SEARCH("(a(?1)b)", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(a(?1)+b)", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^([^()]|\\((?1)*\\))*$", perl, "abc", match_default, make_array(0, 3, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("^([^()]|\\((?1)*\\))*$", perl, "a(b)c", match_default, make_array(0, 5, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("^([^()]|\\((?1)*\\))*$", perl, "a(b(c))d", match_default, make_array(0, 8, 7, 8, -2, -2)); + TEST_REGEX_SEARCH("^([^()]|\\((?1)*\\))*$", perl, "a(b(c)d", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^>abc>([^()]|\\((?1)*\\))*<xyz<$", perl, ">abc>123<xyz<", match_default, make_array(0, 13, 7, 8, -2, -2)); + TEST_REGEX_SEARCH("^>abc>([^()]|\\((?1)*\\))*<xyz<$", perl, ">abc>1(2)3<xyz<", match_default, make_array(0, 15, 9, 10, -2, -2)); + TEST_REGEX_SEARCH("^>abc>([^()]|\\((?1)*\\))*<xyz<$", perl, ">abc>(1(2)3)<xyz<", match_default, make_array(0, 17, 5, 12, -2, -2)); + //TEST_REGEX_SEARCH("^\\W*(?:((.)\\W*(?1)\\W*\\2|)|((.)\\W*(?3)\\W*\\4|\\W*.\\W*))\\W*$", perl|icase, "1221", match_default, make_array(0, 4, 0, 4, 0, 1, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("^\\W*(?:((.)\\W*(?1)\\W*\\2|)|((.)\\W*(?3)\\W*\\4|\\W*.\\W*))\\W*$", perl|icase, "Satan, oscillate my metallic sonatas!", match_default, make_array(0, 37, -1, -1, -1, -1, 0, 36, 0, 1, -2, -2)); + //TEST_REGEX_SEARCH("^\\W*(?:((.)\\W*(?1)\\W*\\2|)|((.)\\W*(?3)\\W*\\4|\\W*.\\W*))\\W*$", perl|icase, "A man, a plan, a canal: Panama!", match_default, make_array(0, 31, -1, -1, -1, -1, 0, 30, 0, 1, -2, -2)); + //TEST_REGEX_SEARCH("^\\W*(?:((.)\\W*(?1)\\W*\\2|)|((.)\\W*(?3)\\W*\\4|\\W*.\\W*))\\W*$", perl|icase, "Able was I ere I saw Elba.", match_default, make_array(0, 26, -1, -1, -1, -1, 0, 25, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^\\W*(?:((.)\\W*(?1)\\W*\\2|)|((.)\\W*(?3)\\W*\\4|\\W*.\\W*))\\W*$", perl|icase, "The quick brown fox", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$", perl|icase, "12", match_default, make_array(0, 2, 0, 2, -1, -1, -2, -2)); + //TEST_REGEX_SEARCH("^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$", perl|icase, "(((2+2)*-3)-7)", match_default, make_array(0, 14, 0, 14, 11, 12, -2, -2)); + TEST_REGEX_SEARCH("^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$", perl|icase, "-12", match_default, make_array(0, 3, 0, 3, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("^(\\d+|\\((?1)([+*-])(?1)\\)|-(?1))$", perl|icase, "((2+2)*-3)-7)", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(x(y|(?1){2})z)", perl|icase, "xyz", match_default, make_array(0, 3, 0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("^(x(y|(?1){2})z)", perl|icase, "xxyzxyzz", match_default, make_array(0, 8, 0, 8, 1, 7, -2, -2)); + TEST_REGEX_SEARCH("^(x(y|(?1){2})z)", perl|icase, "xxyzz", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(x(y|(?1){2})z)", perl|icase, "xxyzxyzxyzz", match_default, make_array(-2, -2)); + TEST_INVALID_REGEX("(?1)", perl); + TEST_INVALID_REGEX("((?2)(abc)", perl); + TEST_REGEX_SEARCH("^(a|b|c)=(?1)+", perl|icase, "a=a", match_default, make_array(0, 3, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^(a|b|c)=(?1)+", perl|icase, "a=b", match_default, make_array(0, 3, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^(a|b|c)=(?1)+", perl|icase, "a=bc", match_default, make_array(0, 4, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^(a|b|c)=((?1))+", perl|icase, "a=a", match_default, make_array(0, 3, 0, 1, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("^(a|b|c)=((?1))+", perl|icase, "a=b", match_default, make_array(0, 3, 0, 1, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("^(a|b|c)=((?1))+", perl|icase, "a=bc", match_default, make_array(0, 4, 0, 1, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("^(?1)(abc)", perl|icase, "abcabc", match_default, make_array(0, 6, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?1)X(?<abc>P)", perl|icase, "abcPXP123", match_default, make_array(3, 6, 5, 6, -2, -2)); + TEST_REGEX_SEARCH("(abc)(?i:(?1))", perl|icase, "defabcabcxyz", match_default, make_array(3, 9, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(abc)(?i:(?1))", perl, "DEFabcABCXYZ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(abc)(?i:(?1)abc)", perl, "DEFabcABCABCXYZ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(abc)(?:(?i)(?1))", perl, "defabcabcxyz", match_default, make_array(3, 9, 3, 6, -2, -2)); + TEST_REGEX_SEARCH("(abc)(?:(?i)(?1))", perl, "DEFabcABCXYZ", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))(?1)", perl, "abcabc", match_default, make_array(0, 6, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))(?1)", perl, "xyzabc", match_default, make_array(0, 6, 0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?|(abc)|(xyz))(?1)", perl, "xyzxyz", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?1)[]a()b](abc)", perl, "abcbabc", match_default, make_array(0, 7, 4, 7, -2, -2)); + TEST_REGEX_SEARCH("(?1)[]a()b](abc)", perl, "abcXabc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?1)[^]a()b](abc)", perl, "abcXabc", match_default, make_array(0, 7, 4, 7, -2, -2)); + TEST_REGEX_SEARCH("(?1)[^]a()b](abc)", perl, "abcbabc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?2)[]a()b](abc)(xyz)", perl, "xyzbabcxyz", match_default, make_array(0, 10, 4, 7, 7, 10, -2, -2)); + TEST_REGEX_SEARCH("^X(?5)(a)(?|(b)|(q))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_INVALID_REGEX("^X(?5)(a)(?|(b)|(q))(c)(d)Y", perl); + TEST_REGEX_SEARCH("^X(?7)(a)(?|(b)|(q)(r)(s))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, -1, -1, -1, -1, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_REGEX_SEARCH("^X(?7)(a)(?|(b|(r)(s))|(q))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, -1, -1, -1, -1, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_REGEX_SEARCH("^X(?7)(a)(?|(b|(?|(r)|(t))(s))|(q))(c)(d)(Y)", perl, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, -1, -1, -1, -1, 4, 5, 5, 6, 6, 7, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{100}*(\\d+|\"(?1)\")", perl, L"1234", match_default, make_array(0, 4, 0, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{100}*(\\d+|\"(?1)\")", perl, L"\"1234\"", match_default, make_array(0, 6, 0, 6, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{100}*(\\d+|\"(?1)\")", perl, L"\x100" L"1234", match_default, make_array(0, 5, 1, 5, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{100}*(\\d+|\"(?1)\")", perl, L"\"\x100" L"1234\"", match_default, make_array(1, 6, 2, 6, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{100}*(\\d+|\"(?1)\")", perl, L"\x100\x100" L"12ab", match_default, make_array(0, 4, 2, 4, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{100}*(\\d+|\"(?1)\")", perl, L"\x100\x100" L"\"12\"", match_default, make_array(0, 6, 2, 6, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{100}*(\\d+|\"(?1)\")", perl, L"\x100\x100" L"abcd", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(ab|c)(?-1)", perl, "abc", match_default, make_array(0, 3, 0, 2, -2, -2)); + TEST_REGEX_SEARCH("xy(?+1)(abc)", perl, "xyabcabc", match_default, make_array(0, 8, 5, 8, -2, -2)); + TEST_REGEX_SEARCH("xy(?+1)(abc)", perl, "xyabc", match_default, make_array(-2, -2)); + TEST_INVALID_REGEX("x(?-0)y", perl); + TEST_INVALID_REGEX("x(?-1)y", perl); + TEST_INVALID_REGEX("x(?+0)y", perl); + TEST_INVALID_REGEX("x(?+1)y", perl); + TEST_REGEX_SEARCH("^(?+1)(?<a>x|y){0}z", perl, "xzxx", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("^(?+1)(?<a>x|y){0}z", perl, "yzyy", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("^(?+1)(?<a>x|y){0}z", perl, "xxz", match_default, make_array(-2, -2)); + + // Now recurse to sub-expression zero: + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "(abcd)", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "(abcd)xyz", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "xyz(abcd)", match_default, make_array(3, 9, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "(ab(xy)cd)pqr", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "(ab(xycd)pqr", match_default, make_array(3, 9, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "() abc ()", match_default, make_array(0, 2, -2, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "12(abcde(fsh)xyz(foo(bar))lmno)89", match_default, make_array(2, 31, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "abcd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "abcd)", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?0))*\\)", perl, "(abcd", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("\\( ( (?>[^()]+) | (?0) )* \\) ", perl|mod_x, "(ab(xy)cd)pqr", match_default, make_array(0, 10, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (?>[^()]+) | (?0) )* \\) ", perl|mod_x, "1(abcd)(x(y)z)pqr", match_default, make_array(1, 7, 2, 6, -2, 7, 14, 12, 13, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?0) ) \\) ", perl|mod_x, "(abcd)", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?0) ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(3, 7, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?0) ) \\) ", perl|mod_x, "(a(b(c)d)e)", match_default, make_array(4, 7, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?0) ) \\) ", perl|mod_x, "((ab))", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?0) ) \\) ", perl|mod_x, "()", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?0) )? \\) ", perl|mod_x, "()", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?0) )? \\) ", perl|mod_x, "12(abcde(fsh)xyz(foo(bar))lmno)89", match_default, make_array(8, 13, -2, 20, 25, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (?>[^()]+) | (?0) )* \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()]+) | (?0) )* ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 1, 9, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( (123)? ( ( (?>[^()]+) | (?0) )* ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, -1, -1, 1, 9, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( (123)? ( ( (?>[^()]+) | (?0) )* ) \\) ", perl|mod_x, "(123ab(xy)cd)", match_default, make_array(0, 13, 1, 4, 4, 12, 10, 12, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (123)? ( (?>[^()]+) | (?0) )* ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 1, 9, -1, -1, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (123)? ( (?>[^()]+) | (?0) )* ) \\) ", perl|mod_x, "(123ab(xy)cd)", match_default, make_array(0, 13, 1, 12, 1, 4, 10, 12, -2, -2)); + TEST_REGEX_SEARCH("\\( (((((((((( ( (?>[^()]+) | (?0) )* )))))))))) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?0) )* ) \\) ", perl|mod_x, "(abcd(xyz<p>qrs)123)", match_default, make_array(0, 20, 1, 19, 16, 19, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()]+) | ((?0)) )* ) \\) ", perl|mod_x, "(ab(cd)ef)", match_default, make_array(0, 10, 1, 9, 7, 9, 3, 7, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()]+) | ((?0)) )* ) \\) ", perl|mod_x, "(ab(cd(ef)gh)ij)", match_default, make_array(0, 16, 1, 15, 13, 15, 3, 13, -2, -2)); + // Again with (?R): + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "(abcd)", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "(abcd)xyz", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "xyz(abcd)", match_default, make_array(3, 9, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "(ab(xy)cd)pqr", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "(ab(xycd)pqr", match_default, make_array(3, 9, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "() abc ()", match_default, make_array(0, 2, -2, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "12(abcde(fsh)xyz(foo(bar))lmno)89", match_default, make_array(2, 31, -2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "abcd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "abcd)", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\((?:(?>[^()]+)|(?R))*\\)", perl, "(abcd", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("\\( ( (?>[^()]+) | (?R) )* \\) ", perl|mod_x, "(ab(xy)cd)pqr", match_default, make_array(0, 10, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (?>[^()]+) | (?R) )* \\) ", perl|mod_x, "1(abcd)(x(y)z)pqr", match_default, make_array(1, 7, 2, 6, -2, 7, 14, 12, 13, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?R) ) \\) ", perl|mod_x, "(abcd)", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?R) ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(3, 7, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?R) ) \\) ", perl|mod_x, "(a(b(c)d)e)", match_default, make_array(4, 7, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?R) ) \\) ", perl|mod_x, "((ab))", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?R) ) \\) ", perl|mod_x, "()", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?R) )? \\) ", perl|mod_x, "()", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\( (?: (?>[^()]+) | (?R) )? \\) ", perl|mod_x, "12(abcde(fsh)xyz(foo(bar))lmno)89", match_default, make_array(8, 13, -2, 20, 25, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (?>[^()]+) | (?R) )* \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()]+) | (?R) )* ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 1, 9, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( (123)? ( ( (?>[^()]+) | (?R) )* ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, -1, -1, 1, 9, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( (123)? ( ( (?>[^()]+) | (?R) )* ) \\) ", perl|mod_x, "(123ab(xy)cd)", match_default, make_array(0, 13, 1, 4, 4, 12, 10, 12, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (123)? ( (?>[^()]+) | (?R) )* ) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 1, 9, -1, -1, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( (123)? ( (?>[^()]+) | (?R) )* ) \\) ", perl|mod_x, "(123ab(xy)cd)", match_default, make_array(0, 13, 1, 12, 1, 4, 10, 12, -2, -2)); + TEST_REGEX_SEARCH("\\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \\) ", perl|mod_x, "(ab(xy)cd)", match_default, make_array(0, 10, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 7, 9, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \\) ", perl|mod_x, "(abcd(xyz<p>qrs)123)", match_default, make_array(0, 20, 1, 19, 16, 19, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()]+) | ((?R)) )* ) \\) ", perl|mod_x, "(ab(cd)ef)", match_default, make_array(0, 10, 1, 9, 7, 9, 3, 7, -2, -2)); + TEST_REGEX_SEARCH("\\( ( ( (?>[^()]+) | ((?R)) )* ) \\) ", perl|mod_x, "(ab(cd(ef)gh)ij)", match_default, make_array(0, 16, 1, 15, 13, 15, 3, 13, -2, -2)); + // And some extra cases: + TEST_REGEX_SEARCH("x(ab|(bc|(de|(?R))))", perl|mod_x, "xab", match_default, make_array(0, 3, 1, 3, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("x(ab|(bc|(de|(?R))))", perl|mod_x, "xbc", match_default, make_array(0, 3, 1, 3, 1, 3, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("x(ab|(bc|(de|(?R))))", perl|mod_x, "xde", match_default, make_array(0, 3, 1, 3, 1, 3, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("x(ab|(bc|(de|(?R))))", perl|mod_x, "xxab", match_default, make_array(0, 4, 1, 4, 1, 4, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("x(ab|(bc|(de|(?R))))", perl|mod_x, "xxxab", match_default, make_array(0, 5, 1, 5, 1, 5, 1, 5, -2, -2)); + TEST_REGEX_SEARCH("x(ab|(bc|(de|(?R))))", perl|mod_x, "xyab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[^()]*(?:\\((?R)\\)[^()]*)*", perl|mod_x, "(this(and)that)", match_default, make_array(0, 15, -2, 15, 15, -2, -2)); + TEST_REGEX_SEARCH("[^()]*(?:\\((?R)\\)[^()]*)*", perl|mod_x, "(this(and)that)stuff", match_default, make_array(0, 20, -2, 20, 20, -2, -2)); + TEST_REGEX_SEARCH("[^()]*(?:\\((?>(?R))\\)[^()]*)*", perl|mod_x, "(this(and)that)", match_default, make_array(0, 15, -2, 15, 15, -2, -2)); + + // More complex cases involving (?(R): + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<>", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abcd>", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc <123> hij>", match_default, make_array(0, 15, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc <def> hij>", match_default, make_array(5, 10, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc<>def>", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc<>", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("((abc (?(R) (?(R1)1) (?(R2)2) X | (?1) (?2) (?R) ))) ", perl|mod_x, "abcabc1Xabc2XabcXabcabc", match_default, make_array(0, 17, 0, 17, 0, 17, -2, -2)); + + // Recursion to named sub-expressions: + //TEST_REGEX_SEARCH("^\\W*(?:(?<one>(?<two>.)\\W*(?&one)\\W*\\k<two>|)|(?<three>(?<four>.)\\W*(?&three)\\W*\\k'four'|\\W*.\\W*))\\W*$", perl|mod_x|icase, "Satan, oscillate my metallic sonatas!", match_default, make_array(0, 37, -1, -1, -1, -1, 0, 36, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?'abc'a|b)(?<doe>d|e)(?&abc){2}", perl|mod_x, "bdaa", match_default, make_array(0, 4, 0, 1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?'abc'a|b)(?<doe>d|e)(?&abc){2}", perl|mod_x, "bdab", match_default, make_array(0, 4, 0, 1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?'abc'a|b)(?<doe>d|e)(?&abc){2}", perl|mod_x, "bddd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?&abc)X(?<abc>P)", perl|mod_x, "abcPXP123", match_default, make_array(3, 6, 5, 6, -2, -2)); + TEST_REGEX_SEARCH("(?:a(?&abc)b)*(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_REGEX_SEARCH("(?:a(?&abc)b){1,5}(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_REGEX_SEARCH("(?:a(?&abc)b){2,5}(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_REGEX_SEARCH("(?:a(?&abc)b){2,}(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_INVALID_REGEX("(?<a>)(?&)", perl|mod_x); + TEST_INVALID_REGEX("(?<abc>)(?&a)", perl|mod_x); + TEST_INVALID_REGEX("(?<a>)(?&aaaaaaaaaaaaaaaaaaaaaaa)", perl|mod_x); + TEST_INVALID_REGEX("(?&N)[]a(?<N>)](?<M>abc)", perl|mod_x); + TEST_INVALID_REGEX("(?&N)[]a(?<N>)](abc)", perl|mod_x); + TEST_INVALID_REGEX("(?&N)[]a(?<N>)](abc)", perl|mod_x); + TEST_REGEX_SEARCH("^X(?&N)(a)(?|(b)|(q))(c)(d)(?<N>Y)", perl|mod_x, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, -2, -2)); + // And again with (?P> : + //TEST_REGEX_SEARCH("^\\W*(?:(?<one>(?<two>.)\\W*(?&one)\\W*\\k<two>|)|(?<three>(?<four>.)\\W*(?&three)\\W*\\k'four'|\\W*.\\W*))\\W*$", perl|mod_x|icase, "Satan, oscillate my metallic sonatas!", match_default, make_array(0, 37, -1, -1, -1, -1, 0, 36, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(?'abc'a|b)(?<doe>d|e)(?P>abc){2}", perl|mod_x, "bdaa", match_default, make_array(0, 4, 0, 1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?'abc'a|b)(?<doe>d|e)(?P>abc){2}", perl|mod_x, "bdab", match_default, make_array(0, 4, 0, 1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?'abc'a|b)(?<doe>d|e)(?P>abc){2}", perl|mod_x, "bddd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?P>abc)X(?<abc>P)", perl|mod_x, "abcPXP123", match_default, make_array(3, 6, 5, 6, -2, -2)); + TEST_REGEX_SEARCH("(?:a(?P>abc)b)*(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_REGEX_SEARCH("(?:a(?P>abc)b){1,5}(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_REGEX_SEARCH("(?:a(?P>abc)b){2,5}(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_REGEX_SEARCH("(?:a(?P>abc)b){2,}(?<abc>x)", perl|mod_x, "123axbaxbaxbx456", match_default, make_array(3, 13, 12, 13 , -2, -2)); + TEST_INVALID_REGEX("(?<a>)(?P>)", perl|mod_x); + TEST_INVALID_REGEX("(?<abc>)(?P>a)", perl|mod_x); + TEST_INVALID_REGEX("(?<a>)(?P>aaaaaaaaaaaaaaaaaaaaaaa)", perl|mod_x); + TEST_INVALID_REGEX("(?P>N)[]a(?<N>)](?<M>abc)", perl|mod_x); + TEST_INVALID_REGEX("(?P>N)[]a(?<N>)](abc)", perl|mod_x); + TEST_INVALID_REGEX("(?P>N)[]a(?<N>)](abc)", perl|mod_x); + TEST_REGEX_SEARCH("^X(?P>N)(a)(?|(b)|(q))(c)(d)(?<N>Y)", perl|mod_x, "XYabcdY", match_default, make_array(0, 7, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, -2, -2)); + // Now check (?(R&NAME) : + TEST_REGEX_SEARCH("(?<A> (?'B' abc (?(R) (?(R&A)1) (?(R&B)2) X | (?1) (?2) (?R) ))) ", perl|mod_x, "abcabc1Xabc2XabcXabcabc", match_default, make_array(0, 17, 0, 17, 0, 17, -2, -2)); + TEST_INVALID_REGEX("(?<A> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) ", perl|mod_x); + TEST_REGEX_SEARCH("(?<1> (?'B' abc (?(R) (?(R&1)1) (?(R&B)2) X | (?1) (?2) (?R) ))) ", perl|mod_x, "abcabc1Xabc2XabcXabcabc", match_default, make_array(0, 17, 0, 17, 0, 17, -2, -2)); + + // Now check for named conditionals: + TEST_REGEX_SEARCH("^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)", perl|mod_x, "abd", match_default, make_array(0, 3, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("^(?<ab>a)? (?(<ab>)b|c) (?('ab')d|e)", perl|mod_x, "ce", match_default, make_array(0, 2, -1, -1, -2, -2)); + + // Recursions in combination with (DEFINE): + TEST_REGEX_SEARCH("^(?(DEFINE) (?<A> a) (?<B> b) ) (?&A) (?&B) ", perl|mod_x, "abcd", match_default, make_array(0, 2, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(?<NAME>(?&NAME_PAT))\\s+(?<ADDR>(?&ADDRESS_PAT)) (?(DEFINE) (?<NAME_PAT>[a-z]+) (?<ADDRESS_PAT>\\d+))", perl|mod_x, "metcalfe 33", match_default, make_array(0, 11, 0, 8, 9, 11, -1, -1, -1, -1, -2, -2)); + TEST_INVALID_REGEX("^(?(DEFINE) abc | xyz ) ", perl|mod_x); + //TEST_INVALID_REGEX("(?(DEFINE) abc){3} xyz", perl|mod_x); + TEST_REGEX_SEARCH("(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}", perl|mod_x, "1.2.3.4", match_default, make_array(0, 7, -1, -1, 5, 7, -2, -2)); + TEST_REGEX_SEARCH("(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}", perl|mod_x, "131.111.10.206", match_default, make_array(0, 14, -1, -1, 10, 14, -2, -2)); + TEST_REGEX_SEARCH("(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}", perl|mod_x, "10.0.0.0", match_default, make_array(0, 8, -1, -1, 6, 8, -2, -2)); + TEST_REGEX_SEARCH("(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}", perl|mod_x, "10.6", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))\\b(?&byte)(\\.(?&byte)){3}", perl|mod_x, "455.3.4.5", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))", perl|mod_x, "1.2.3.4", match_default, make_array(0, 7, 5, 7, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))", perl|mod_x, "131.111.10.206", match_default, make_array(0, 14, 10, 14, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))", perl|mod_x, "10.0.0.0", match_default, make_array(0, 8, 6, 8, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))", perl|mod_x, "10.6", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\b(?&byte)(\\.(?&byte)){3}(?(DEFINE)(?<byte>2[0-4]\\d|25[0-5]|1\\d\\d|[1-9]?\\d))", perl|mod_x, "455.3.4.5", match_default, make_array(-2, -2)); + + // Bugs: + TEST_REGEX_SEARCH("namespace\\s+(\\w+)\\s+(\\{(?:[^{}]*(?:(?2)[^{}]*)*)?\\})", perl, "namespace one { namespace two { int foo(); } }", match_default, make_array(0, 46, 10, 13, 14, 46, -2, -2)); + TEST_REGEX_SEARCH("namespace\\s+(\\w+)\\s+(\\{(?:[^{}]*(?:(?2)[^{}]*)*)?\\})", perl, "namespace one { namespace two { int foo(){} } { {{{ } } } } {}}", match_default, make_array(0, 64, 10, 13, 14, 64, -2, -2)); + TEST_INVALID_REGEX("((?1)|a)", perl); + TEST_REGEX_SEARCH("a(?0)?", perl, "aaaaa", match_default, make_array(0, 5, -2, -2)); + + // Recursion to a named sub with a name that is used multiple times: + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+))\\.(?&A)", perl, "aaaa.aa", match_default, make_array(0, 7, 0, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+))\\.(?&A)", perl, "bbbb.aa", match_default, make_array(0, 7, -1, -1, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+))\\.(?&A)", perl, "bbbb.bb", match_default, make_array(-2, -2)); + // Back reference to a named sub with a name that is used multiple times: + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+))\\.\\k<A>", perl, "aaaa.aaaa", match_default, make_array(0, 9, 0, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+))\\.\\k<A>", perl, "bbbb.aaaa", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+))\\.\\k<A>", perl, "aaaa.bbbb", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+))\\.\\k<A>", perl, "bbbb.bbbb", match_default, make_array(0, 9, -1, -1, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("(?:(?<A>a+)|(?<A>b+)|c+)\\.\\k<A>", perl, "cccc.cccc", match_default, make_array(-2, -2)); +} + +void test_verbs() +{ + using namespace boost::regex_constants; + + TEST_INVALID_REGEX("a+(*", perl); + TEST_INVALID_REGEX("a+(*FX)", perl); + TEST_REGEX_SEARCH("a+(*FAIL)b", perl, "aaaab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AB", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "ACDE", match_default, make_array(0, 4, 0, 3, 1, 2, 3, 4, -2, -2)); + + TEST_REGEX_SEARCH("^a+(*FAIL)", perl, "aaaaaa", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a+b?c+(*FAIL)", perl, "aaabccc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a+b?(*COMMIT)c+(*FAIL)", perl, "aaabccc", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AB", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "ABX", match_default, make_array(0, 2, 0, 2, 1, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AADE", match_default, make_array(0, 4, 0, 3, 1, 2, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "ACDE", match_default, make_array(0, 4, 0, 3, 1, 2, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("(A(A|B(*ACCEPT)|C)D)(E)", perl, "AD", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "AAD", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "ACD", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "BAD", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "BCD", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "BAX", match_default, make_array(0, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "ACX", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:(?1)|B)(A(*ACCEPT)XX|C)D", perl, "ABC", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("^(?=a(*ACCEPT)b)", perl, "ac", match_default, make_array(0, 0, -2, -2)); + TEST_REGEX_SEARCH("A(*COMMIT)(B|D)", perl, "ACABX", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(*COMMIT)(A|P)(B|P)(C|P)", perl, "ABCDEFG", match_default, make_array(0, 3, 0, 1, 1, 2, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("(*COMMIT)(A|P)(B|P)(C|P)", perl, "DEFGABC", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("(\\w+)(?>b(*COMMIT))\\w{2}", perl, "abbb", match_default, make_array(0, 4, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(\\w+)b(*COMMIT)\\w{2}", perl, "abbb", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("a+b?(*PRUNE)c+(*FAIL)", perl, "aaabccc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a+b?(*SKIP)c+(*FAIL)", perl, "aaabcccaaabccc", match_default, make_array(-2, -2)); +// + TEST_REGEX_SEARCH("^(?=a(*SKIP)b|ac)", perl, "ac", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?=a(*PRUNE)b)", perl, "ab", match_default, make_array(0, 0, -2, -2)); + TEST_REGEX_SEARCH("^(?=a(*PRUNE)b)", perl, "ac", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("AA+(*PRUNE)(B|Z)|AC", perl, "AAAC", match_default, make_array(2, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("AA+(*SKIP)(B|Z)|AC", perl, "AAAC", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("AA+(*SKIP)(B|Z)|C", perl, "AAAC", match_default, make_array(3, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("AA+(*SKIP)(B|Z)|AC", perl, "AAAC", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("AA+(*SKIP)B|C", perl, "AAAC", match_default, make_array(3, 4, -2, -2)); + + TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "aaaxxxxxx", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "aaa++++++", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "bbbxxxxx", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "bbb+++++", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "cccxxxx", match_default, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "ccc++++", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?:aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "dddddddd", match_default, make_array(0, 3, -2, -2)); + + TEST_REGEX_SEARCH("^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "aaaxxxxxx", match_default, make_array(0, 9, 0, 9, -2, -2)); + TEST_REGEX_SEARCH("^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "aaa++++++", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "bbbxxxxx", match_default, make_array(0, 8, 0, 8, -2, -2)); + TEST_REGEX_SEARCH("^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "bbb+++++", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "cccxxxx", match_default, make_array(0, 7, 0, 7, -2, -2)); + TEST_REGEX_SEARCH("^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "ccc++++", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(aaa(*THEN)\\w{6}|bbb(*THEN)\\w{5}|ccc(*THEN)\\w{4}|\\w{3})", perl, "dddddddd", match_default, make_array(0, 3, 0, 3, -2, -2)); + + TEST_REGEX_SEARCH("(?:a+(*THEN)\\w{6}|x\\w{3})", perl, "aaaxxxxx", match_default, make_array(3, 7, -2, -2)); + TEST_REGEX_SEARCH("(?>(*COMMIT)(?>yes|no)(*THEN)(*F))?", perl, "yes", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?>(*COMMIT)(yes|no)(*THEN)(*F))?", perl, "yes", match_default, make_array(-2, -2)); +} diff --git a/src/boost/libs/regex/test/regress/test_regex_replace.hpp b/src/boost/libs/regex/test/regress/test_regex_replace.hpp new file mode 100644 index 00000000..cc029748 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_regex_replace.hpp @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_regex_replace.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Declares tests for regex search and replace. + */ + +#ifndef BOOST_REGEX_REGRESS_REGEX_REPLACE_HPP +#define BOOST_REGEX_REGRESS_REGEX_REPLACE_HPP +#include "info.hpp" + +template<class charT, class traits> +void test_regex_replace(boost::basic_regex<charT, traits>& r) +{ + typedef std::basic_string<charT> string_type; + const string_type& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const string_type& format_string = test_info<charT>::format_string(); + const string_type& result_string = test_info<charT>::result_string(); + + string_type result = boost::regex_replace(search_text, r, format_string, opts); + if(result != result_string) + { + BOOST_REGEX_TEST_ERROR("regex_replace generated an incorrect string result", charT); + } +} + + +struct test_regex_replace_tag{}; + +template<class charT, class traits> +void test(boost::basic_regex<charT, traits>& r, const test_regex_replace_tag&) +{ + const std::basic_string<charT>& expression = test_info<charT>::expression(); + boost::regex_constants::syntax_option_type syntax_options = test_info<charT>::syntax_options(); +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { + r.assign(expression, syntax_options); + if(r.status()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), charT); + } + test_regex_replace(r); + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression& e) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), charT); + } + catch(const std::runtime_error& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e.what(), charT); + } + catch(const std::exception& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e.what(), charT); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", charT); + } +#endif + +} + +#endif + diff --git a/src/boost/libs/regex/test/regress/test_regex_search.hpp b/src/boost/libs/regex/test/regress/test_regex_search.hpp new file mode 100644 index 00000000..16b1bf91 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_regex_search.hpp @@ -0,0 +1,554 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_regex_search.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Declares tests for regex search and iteration. + */ + +#ifndef BOOST_REGEX_REGRESS_REGEX_SEARCH_HPP +#define BOOST_REGEX_REGRESS_REGEX_SEARCH_HPP +#include "info.hpp" +#ifdef TEST_ROPE +#include <rope> +#endif +// +// this file implements a test for a regular expression that should compile, +// followed by a search for that expression: +// +struct test_regex_search_tag{}; + +template <class BidirectionalIterator> +void test_sub_match(const boost::sub_match<BidirectionalIterator>& sub, BidirectionalIterator base, const int* answer_table, int i, bool recurse = true) +{ +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if(recurse) + { + boost::sub_match<BidirectionalIterator> copy(sub); + test_sub_match(copy, base, answer_table, i, false); + } + typedef typename boost::sub_match<BidirectionalIterator>::value_type charT; + if((sub.matched == 0) + && + !((i == 0) + && (test_info<charT>::match_options() & boost::match_partial)) ) + { + if(answer_table[2*i] >= 0) + { + BOOST_REGEX_TEST_ERROR( + "Sub-expression " << i + << " was not matched when it should have been.", charT); + } + } + else + { + if(boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.first) != answer_table[2*i]) + { + BOOST_REGEX_TEST_ERROR( + "Error in start location of sub-expression " + << i << ", found " << boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.first) + << ", expected " << answer_table[2*i] << ".", charT); + } + if(boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.second) != answer_table[1+ 2*i]) + { + BOOST_REGEX_TEST_ERROR( + "Error in end location of sub-expression " + << i << ", found " << boost::BOOST_REGEX_DETAIL_NS::distance(base, sub.second) + << ", expected " << answer_table[1 + 2*i] << ".", charT); + } + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif +} + +template <class BidirectionalIterator, class Allocator> +void test_result(const boost::match_results<BidirectionalIterator, Allocator>& what, BidirectionalIterator base, const int* answer_table, bool recurse = true) +{ + if(recurse) + { + boost::match_results<BidirectionalIterator, Allocator> copy(what); + test_result(copy, base, answer_table, false); + boost::match_results<BidirectionalIterator, Allocator> s; + s.swap(copy); + test_result(s, base, answer_table, false); + boost::match_results<BidirectionalIterator, Allocator> s2; + s2 = what; + test_result(s2, base, answer_table, false); + } + for(unsigned i = 0; i < what.size(); ++i) + { + test_sub_match(what[i], base, answer_table, i); + } +} + +template<class charT, class traits> +void test_simple_search(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + boost::match_results<const_iterator> what; + if(boost::regex_search( + search_text.begin(), + search_text.end(), + what, + r, + opts)) + { + test_result(what, search_text.begin(), answer_table); + // setting match_any should have no effect on the result returned: + if(!boost::regex_search( + search_text.begin(), + search_text.end(), + r, + opts|boost::regex_constants::match_any)) + { + BOOST_REGEX_TEST_ERROR("Expected match was not found when using the match_any flag.", charT); + } + } + else + { + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } + // setting match_any should have no effect on the result returned: + else if(boost::regex_search( + search_text.begin(), + search_text.end(), + r, + opts|boost::regex_constants::match_any)) + { + BOOST_REGEX_TEST_ERROR("Unexpected match was found when using the match_any flag.", charT); + } + } +#ifdef TEST_ROPE + std::rope<charT> rsearch_text; + for(unsigned i = 0; i < search_text.size(); ++i) + { + std::rope<charT> c(search_text[i]); + if(++i != search_text.size()) + { + c.append(search_text[i]); + if(++i != search_text.size()) + { + c.append(search_text[i]); + } + } + rsearch_text.append(c); + } + boost::match_results<std::rope<charT>::const_iterator> rwhat; + if(boost::regex_search( + rsearch_text.begin(), + rsearch_text.end(), + rwhat, + r, + opts)) + { + test_result(rwhat, rsearch_text.begin(), answer_table); + } + else + { + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } + } +#endif +} + +template<class charT, class traits> +void test_regex_iterator(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + typedef boost::regex_iterator<const_iterator, charT, traits> test_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + test_iterator start(search_text.begin(), search_text.end(), r, opts), end; + test_iterator copy(start); + const_iterator last_end = search_text.begin(); + while(start != end) + { + if(start != copy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", charT); + } + if(!(start == copy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", charT); + } + test_result(*start, search_text.begin(), answer_table); + // test $` and $' : + if(start->prefix().first != last_end) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for start of $`", charT); + } + if(start->prefix().second != (*start)[0].first) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for end of $`", charT); + } + if(start->prefix().matched != (start->prefix().first != start->prefix().second)) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $`", charT); + } + if(start->suffix().first != (*start)[0].second) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for start of $'", charT); + } + if(start->suffix().second != search_text.end()) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for end of $'", charT); + } + if(start->suffix().matched != (start->suffix().first != start->suffix().second)) + { + BOOST_REGEX_TEST_ERROR("Incorrect position for matched member of $'", charT); + } + last_end = (*start)[0].second; + ++start; + ++copy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } +} + +template<class charT, class traits> +void test_regex_token_iterator(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + typedef boost::regex_token_iterator<const_iterator, charT, traits> test_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + // + // we start by testing sub-expression 0: + // + test_iterator start(search_text.begin(), search_text.end(), r, 0, opts), end; + test_iterator copy(start); + while(start != end) + { + if(start != copy) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", charT); + } + if(!(start == copy)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", charT); + } + test_sub_match(*start, search_text.begin(), answer_table, 0); + ++start; + ++copy; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } + // + // and now field spitting: + // + test_iterator start2(search_text.begin(), search_text.end(), r, -1, opts), end2; + test_iterator copy2(start2); + int last_end2 = 0; + answer_table = test_info<charT>::answer_table(); + while(start2 != end2) + { + if(start2 != copy2) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", charT); + } + if(!(start2 == copy2)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", charT); + } +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if(boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->first) != last_end2) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of start of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->first) + << ", expected: " + << last_end2 + << ".", charT); + } + int expected_end = static_cast<int>(answer_table[0] < 0 ? search_text.size() : answer_table[0]); + if(boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->second) != expected_end) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of end2 of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->second) + << ", expected: " + << expected_end + << ".", charT); + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + last_end2 = answer_table[1]; + ++start2; + ++copy2; + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // + // and now both field splitting and $0: + // + std::vector<int> subs; + subs.push_back(-1); + subs.push_back(0); + start2 = test_iterator(search_text.begin(), search_text.end(), r, subs, opts); + copy2 = start2; + last_end2 = 0; + answer_table = test_info<charT>::answer_table(); + while(start2 != end2) + { + if(start2 != copy2) + { + BOOST_REGEX_TEST_ERROR("Failed iterator != comparison.", charT); + } + if(!(start2 == copy2)) + { + BOOST_REGEX_TEST_ERROR("Failed iterator == comparison.", charT); + } +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4244) +#endif + if(boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->first) != last_end2) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of start of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->first) + << ", expected: " + << last_end2 + << ".", charT); + } + int expected_end = static_cast<int>(answer_table[0] < 0 ? search_text.size() : answer_table[0]); + if(boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->second) != expected_end) + { + BOOST_REGEX_TEST_ERROR( + "Error in location of end2 of field split, found: " + << boost::BOOST_REGEX_DETAIL_NS::distance(search_text.begin(), start2->second) + << ", expected: " + << expected_end + << ".", charT); + } +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + last_end2 = answer_table[1]; + ++start2; + ++copy2; + if((start2 == end2) && (answer_table[0] >= 0)) + { + BOOST_REGEX_TEST_ERROR( + "Expected $0 match not found", charT); + } + if(start2 != end2) + { + test_sub_match(*start2, search_text.begin(), answer_table, 0); + ++start2; + ++copy2; + } + // move on the answer table to next set of answers; + if(*answer_table != -2) + while(*answer_table++ != -2){} + } + if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } +#endif +} + +template <class charT, class traits> +struct grep_test_predicate +{ + typedef typename std::basic_string<charT>::const_iterator test_iter; + + grep_test_predicate(test_iter b, const int* a) + : m_base(b), m_table(a) + {} + bool operator()(const boost::match_results<test_iter>& what) + { + test_result(what, m_base, m_table); + // move on the answer table to next set of answers; + if(*m_table != -2) + while(*m_table++ != -2){} + return true; + } +private: + test_iter m_base; + const int* m_table; +}; + +template<class charT, class traits> +void test_regex_grep(boost::basic_regex<charT, traits>& r) +{ + //typedef typename std::basic_string<charT>::const_iterator const_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + grep_test_predicate<charT, traits> pred(search_text.begin(), answer_table); + boost::regex_grep(pred, search_text.begin(), search_text.end(), r, opts); +} + +template<class charT, class traits> +void test_regex_match(boost::basic_regex<charT, traits>& r) +{ + typedef typename std::basic_string<charT>::const_iterator const_iterator; + const std::basic_string<charT>& search_text = test_info<charT>::search_text(); + boost::regex_constants::match_flag_type opts = test_info<charT>::match_options(); + const int* answer_table = test_info<charT>::answer_table(); + boost::match_results<const_iterator> what; + if(answer_table[0] < 0) + { + if(boost::regex_match(search_text, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", charT); + } + } + else + { + if((answer_table[0] > 0) && boost::regex_match(search_text, r, opts)) + { + BOOST_REGEX_TEST_ERROR("boost::regex_match found a match when it should not have done so.", charT); + } + else if((answer_table[0] == 0) && (answer_table[1] == static_cast<int>(search_text.size()))) + { + if(boost::regex_match( + search_text.begin(), + search_text.end(), + what, + r, + opts)) + { + test_result(what, search_text.begin(), answer_table); + } + else if(answer_table[0] >= 0) + { + // we should have had a match but didn't: + BOOST_REGEX_TEST_ERROR("Expected match was not found.", charT); + } + } + } +} + +template<class charT, class traits> +void test(boost::basic_regex<charT, traits>& r, const test_regex_search_tag&) +{ + const std::basic_string<charT>& expression = test_info<charT>::expression(); + boost::regex_constants::syntax_option_type syntax_options = test_info<charT>::syntax_options(); +#ifndef BOOST_NO_EXCEPTIONS + try +#endif + { + r.assign(expression, syntax_options); + if(r.status()) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done, error code = " << r.status(), charT); + } + if(expression != std::basic_string<charT>(r.begin(), r.end())) + { + BOOST_REGEX_TEST_ERROR("Stored expression string was incorrect", charT); + } + test_simple_search(r); + test_regex_iterator(r); + test_regex_token_iterator(r); + test_regex_grep(r); + test_regex_match(r); + // + // Verify sub-expression locations: + // +#ifndef BOOST_NO_EXCEPTIONS + if((syntax_options & boost::regbase::save_subexpression_location) == 0) + { + bool have_except = false; + try + { + r.subexpression(1); + } + catch(const std::out_of_range&) + { + have_except = true; + } + if(!have_except) + { + BOOST_REGEX_TEST_ERROR("Expected std::out_of_range error was not found.", charT); + } + } +#endif + r.assign(expression, syntax_options | boost::regbase::save_subexpression_location); + for(std::size_t i = 0; i < r.mark_count(); ++i) + { + std::pair<const charT*, const charT*> p = r.subexpression(i); + if(*p.first != '(') + { + BOOST_REGEX_TEST_ERROR("Starting location of sub-expression " << i << " iterator was invalid.", charT); + } + if(*p.second != ')') + { + BOOST_REGEX_TEST_ERROR("Ending location of sub-expression " << i << " iterator was invalid.", charT); + } + } + } +#ifndef BOOST_NO_EXCEPTIONS + catch(const boost::bad_expression& e) + { + BOOST_REGEX_TEST_ERROR("Expression did not compile when it should have done: " << e.what(), charT); + } + catch(const std::runtime_error& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::runtime_error: " << e.what(), charT); + } + catch(const std::exception& e) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected std::exception: " << e.what(), charT); + } + catch(...) + { + BOOST_REGEX_TEST_ERROR("Received an unexpected exception of unknown type", charT); + } +#endif +} + + + +#endif diff --git a/src/boost/libs/regex/test/regress/test_replace.cpp b/src/boost/libs/regex/test/regress/test_replace.cpp new file mode 100644 index 00000000..635e6e30 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_replace.cpp @@ -0,0 +1,198 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_replace() +{ + using namespace boost::regex_constants; + // start by testing subs: + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$`", "..."); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$'", ",,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$&", "aaa"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$0", "aaa"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$1", ""); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$15", ""); + TEST_REGEX_REPLACE("(a+)b+", perl, "...aaabbb,,,", match_default|format_no_copy, "$1", "aaa"); + TEST_REGEX_REPLACE("[[:digit:]]*", perl, "123ab", match_default|format_no_copy, "<$0>", "<123><><><>"); + TEST_REGEX_REPLACE("[[:digit:]]*", perl, "123ab1", match_default|format_no_copy, "<$0>", "<123><><><1><>"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$`$", "...$"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "(?1x:y)", "(?1x:y)"); + // and now escapes: + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$x", "$x"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\a", "\a"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\f", "\f"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\n", "\n"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\r", "\r"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\t", "\t"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\v", "\v"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\", "\\"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\x21", "!"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\xz", "xz"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\x", "x"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\x{z}", "x{z}"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\x{12b", "x{12b"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\x{21}", "!"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\c@", "\0"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\c", "c"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\e", "\x1B"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\0101", "A"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default|format_no_copy, "\\u$1", "Aaa"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default|format_no_copy, "\\U$1", "AAA"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default|format_no_copy, "\\U$1\\E$1", "AAAaaa"); + TEST_REGEX_REPLACE("(A+)", perl, "...AAA,,,", match_default|format_no_copy, "\\l$1", "aAA"); + TEST_REGEX_REPLACE("(A+)", perl, "...AAA,,,", match_default|format_no_copy, "\\L$1", "aaa"); + TEST_REGEX_REPLACE("(A+)", perl, "...AAA,,,", match_default|format_no_copy, "\\L$1\\E$1", "aaaAAA"); + TEST_REGEX_REPLACE("\\w+", perl, "fee FOO FAR bAR", match_default|format_perl, "\\L\\u$0", "Fee Foo Far Bar"); + // sed format sequences: + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "\\0", "aabb"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "\\1", "aa"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "\\2", "bb"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "&", "aabb"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "$", "$"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "$1", "$1"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "()?:", "()?:"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "\\\\", "\\"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "\\&", "&"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_sed|format_no_copy, "\\l\\u\\L\\U\\E", "luLUE"); + + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "$0", "aabb"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "$1", "aa"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "$2", "bb"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "$&", "aabb"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "$$", "$"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "&", "&"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "\\0", "\0"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "()?:", "()?:"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,", match_default|format_perl|format_no_copy, "\\0101", "A"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "\\1", "aa"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, " ...aabb,,", match_default|format_perl|format_no_copy, "\\2", "bb"); + + // move to copying unmatched data: + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_all, "bbb", "...bbb,,,"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,", match_default|format_all, "$1", "...bb,,,"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "$1", "...bb,,,b*bbb?"); + 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:B", "...AB,,,AB*AB?"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?1A:B)C", "...ACBC,,,ACBC*ACBC?"); + 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}A)(?{2}B)", "...AB,,,AB*AB?"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?{1}A:B", "...AB,,,AB*AB?"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?{1}A:B)C", "...ACBC,,,ACBC*ACBC?"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?{1}:B", "...B,,,B*B?"); + TEST_REGEX_REPLACE("(?<one>a+)|(?<two>b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?{one}A)(?{two}B)", "...AB,,,AB*AB?"); + TEST_REGEX_REPLACE("(?<one>a+)|(?<two>b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?{one}A:B", "...AB,,,AB*AB?"); + TEST_REGEX_REPLACE("(?<one>a+)|(?<two>b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?{one}A:B)C", "...ACBC,,,ACBC*ACBC?"); + TEST_REGEX_REPLACE("(?<one>a+)|(?<two>b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?{one}:B", "...B,,,B*B?"); + + // move to copying unmatched data, but replace first occurance only: + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_all|format_first_only, "bbb", "...bbb,,,"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,", match_default|format_all|format_first_only, "$1", "...bb,,,"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all|format_first_only, "$1", "...bb,,,ab*abbb?"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all|format_first_only, "(?1A)(?2B)", "...Abb,,,ab*abbb?"); + 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"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?", "...??,,,??*???"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?a", "...?a?a,,,?a?a*?a?a?"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?1A:(?2B))abc", "...AabcBabc,,,AabcBabc*AabcBabc?"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,", match_default|format_all|format_no_copy, "(?2abc:def)", "def"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,", match_default|format_all|format_no_copy, "(?1abc:def)", "abc"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,", match_default|format_perl|format_no_copy, "(?1abc:def)", "(?1abc:def)"); + TEST_REGEX_REPLACE("a+(b+)", perl, "...", match_default|format_perl, "(?1abc:def)", "..."); + TEST_REGEX_REPLACE("a+(b+)", perl, "...", match_default|format_perl|format_no_copy, "(?1abc:def)", ""); + // probe bug reports and other special cases: + TEST_REGEX_REPLACE("([^\\d]+).*", normal|icase, "tesd 999 test", match_default|format_all, "($1)replace", "tesd replace"); + TEST_REGEX_REPLACE("(a)(b)", perl, "ab", match_default|format_all, "$1:$2", "a:b"); + TEST_REGEX_REPLACE("(a(c)?)|(b)", perl, "acab", match_default|format_all, "(?1(?2(C:):A):B:)", "C:AB:"); + TEST_REGEX_REPLACE("x", icase, "xx", match_default|format_all, "a", "aa"); + TEST_REGEX_REPLACE("x", basic|icase, "xx", match_default|format_all, "a", "aa"); + TEST_REGEX_REPLACE("x", boost::regex::extended|icase, "xx", match_default|format_all, "a", "aa"); + TEST_REGEX_REPLACE("x", emacs|icase, "xx", match_default|format_all, "a", "aa"); + TEST_REGEX_REPLACE("x", literal|icase, "xx", match_default|format_all, "a", "aa"); + // literals: + TEST_REGEX_REPLACE("(a(c)?)|(b)", perl, "acab", match_default|format_literal, "\\&$", "\\&$\\&$\\&$"); + // Bracketed sub expressions: + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default, "$", "...$,,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default, "${", "...${,,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default, "${2", "...${2,,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default, "${23", "...${23,,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default, "${d}", "...${d},,,"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default, "/${1}/", ".../aaa/,,,"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default, "/${10}/", "...//,,,"); + TEST_REGEX_REPLACE("((((((((((a+))))))))))", perl, "...aaa,,,", match_default, "/${10}/", ".../aaa/,,,"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default, "/${1}0/", ".../aaa0/,,,"); + + // New Perl style operators: + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$MATCH", "aaa"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${MATCH}", "aaa"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${^MATCH}", "aaa"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$MATC", "$MATC"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${MATCH", "${MATCH"); + + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$PREMATCH", "..."); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${PREMATCH}", "..."); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${^PREMATCH}", "..."); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$PREMATC", "$PREMATC"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${PREMATCH", "${PREMATCH"); + + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$POSTMATCH", ",,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${POSTMATCH}", ",,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${^POSTMATCH}", ",,,"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$POSTMATC", "$POSTMATC"); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "${POSTMATCH", "${POSTMATCH"); + + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$LAST_PAREN_MATCH", ""); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$LAST_PAREN_MATC", "$LAST_PAREN_MATC"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default|format_no_copy, "$LAST_PAREN_MATCH", "aaa"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, "...aaabb,,,", match_default|format_no_copy, "$LAST_PAREN_MATCH", "bb"); + + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$+", ""); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$+foo", "foo"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default|format_no_copy, "$+", "aaa"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, "...aaabb,,,", match_default|format_no_copy, "$+foo", "bbfoo"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, "...aaabb,,,", match_default|format_no_copy, "$+{", "bb{"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, "...aaabb,,,", match_default|format_no_copy, "$+{foo", "bb{foo"); + + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$LAST_SUBMATCH_RESULT", ""); + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$LAST_SUBMATCH_RESUL", "$LAST_SUBMATCH_RESUL"); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default|format_no_copy, "$LAST_SUBMATCH_RESULT", "aaa"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, "...aaabb,,,", match_default|format_no_copy, "$LAST_SUBMATCH_RESULT", "bb"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaa,,,", match_default|format_no_copy, "$LAST_SUBMATCH_RESULT", "aaa"); + + TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$^N", ""); + TEST_REGEX_REPLACE("(a+)", perl, "...aaa,,,", match_default|format_no_copy, "$^N", "aaa"); + TEST_REGEX_REPLACE("(a+)(b+)", perl, "...aaabb,,,", match_default|format_no_copy, "$^N", "bb"); + TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaa,,,", match_default|format_no_copy, "$^N", "aaa"); + + TEST_REGEX_REPLACE("(?<one>a+)(?<two>b+)", perl, " ...aabb,,", match_default|format_no_copy, "$&", "aabb"); + TEST_REGEX_REPLACE("(?<one>a+)(?<two>b+)", perl, " ...aabb,,", match_default|format_no_copy, "$1", "aa"); + TEST_REGEX_REPLACE("(?<one>a+)(?<two>b+)", perl, " ...aabb,,", match_default|format_no_copy, "$2", "bb"); + TEST_REGEX_REPLACE("(?<one>a+)(?<two>b+)", perl, " ...aabb,,", match_default|format_no_copy, "d$+{one}c", "daac"); + TEST_REGEX_REPLACE("(?<one>a+)(?<two>b+)", perl, " ...aabb,,", match_default|format_no_copy, "c$+{two}d", "cbbd"); + + TEST_REGEX_REPLACE("(?<one>a)(?<one>b)(c)", perl, " ...abc,,", match_default, "$1.$2.$3.$+{one}", " ...a.b.c.a,,"); + TEST_REGEX_REPLACE("(?:(?<one>a)|(?<one>b))", perl, " ...a,,", match_default, "$1.$2.$+{one}", " ...a..a,,"); + TEST_REGEX_REPLACE("(?:(?<one>a)|(?<one>b))", perl, " ...b,,", match_default, "$1.$2.$+{one}", " ....b.b,,"); + TEST_REGEX_REPLACE("(?:(?<one>a)(?<one>b))", perl, " ...ab,,", match_default, "$1.$2.$+{one}", " ...a.b.a,,"); + + // See https://svn.boost.org/trac/boost/ticket/589 + TEST_REGEX_REPLACE("(a*)", perl, "aabb", match_default, "{$1}", "{aa}{}b{}b{}"); + TEST_REGEX_REPLACE("(a*)", boost::regex::extended, "aabb", match_default, "{$1}", "{aa}{}b{}b{}"); + TEST_REGEX_REPLACE("(a*)", boost::regex::extended, "aabb", match_default|match_posix, "{$1}", "{aa}b{}b{}"); +} + diff --git a/src/boost/libs/regex/test/regress/test_sets.cpp b/src/boost/libs/regex/test/regress/test_sets.cpp new file mode 100644 index 00000000..3cd7a520 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_sets.cpp @@ -0,0 +1,406 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_sets() +{ + using namespace boost::regex_constants; + // now test the set operator [] + TEST_REGEX_SEARCH("[abc]", boost::regex::extended, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[abc]", boost::regex::extended, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[abc]", boost::regex::extended, "c", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[abc]", boost::regex::extended, "d", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[^bcd]", boost::regex::extended, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[^bcd]", boost::regex::extended, "b", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[^bcd]", boost::regex::extended, "d", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[^bcd]", boost::regex::extended, "e", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a[b]c", boost::regex::extended, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[ab]c", boost::regex::extended, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[a^b]*c", boost::regex::extended, "aba^c", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a[^ab]c", boost::regex::extended, "adc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[]b]c", boost::regex::extended, "a]c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[[b]c", boost::regex::extended, "a[c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[-b]c", boost::regex::extended, "a-c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[^]b]c", boost::regex::extended, "adc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[^-b]c", boost::regex::extended, "adc", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[b-]c", boost::regex::extended, "a-c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[a-z-]c", boost::regex::extended, "a-c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[a-z-]+c", boost::regex::extended, "aaz-c", match_default, make_array(0, 5, -2, -2)); + TEST_INVALID_REGEX("a[b", boost::regex::extended); + TEST_INVALID_REGEX("a[", boost::regex::extended); + TEST_INVALID_REGEX("a[]", boost::regex::extended); + + // now some ranges: + TEST_REGEX_SEARCH("[b-e]", boost::regex::extended, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[b-e]", boost::regex::extended, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[b-e]", boost::regex::extended, "e", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[b-e]", boost::regex::extended, "f", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[^b-e]", boost::regex::extended, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[^b-e]", boost::regex::extended, "b", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[^b-e]", boost::regex::extended, "e", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[^b-e]", boost::regex::extended, "f", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a[1-3]c", boost::regex::extended, "a2c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[-3]c", boost::regex::extended, "a-c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[-3]c", boost::regex::extended, "a3c", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a[^-3]c", boost::regex::extended, "a-c", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a[^-3]c", boost::regex::extended, "a3c", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a[^-3]c", boost::regex::extended, "axc", match_default, make_array(0, 3, -2, -2)); + TEST_INVALID_REGEX("a[3-1]c", boost::regex::extended & ~::boost::regex_constants::collate); + TEST_INVALID_REGEX("a[1-3-5]c", boost::regex::extended); + TEST_INVALID_REGEX("a[1-", boost::regex::extended); + TEST_INVALID_REGEX("a[\\9]", perl); + + // and some classes + TEST_REGEX_SEARCH("a[[:alpha:]]c", boost::regex::extended, "abc", match_default, make_array(0, 3, -2, -2)); + TEST_INVALID_REGEX("a[[:unknown:]]c", boost::regex::extended); + TEST_INVALID_REGEX("a[[", boost::regex::extended); + TEST_INVALID_REGEX("a[[:", boost::regex::extended); + TEST_INVALID_REGEX("a[[:a", boost::regex::extended); + TEST_INVALID_REGEX("a[[:alpha", boost::regex::extended); + TEST_INVALID_REGEX("a[[:alpha:", boost::regex::extended); + TEST_INVALID_REGEX("a[[:alpha:]", boost::regex::extended); + TEST_INVALID_REGEX("a[[:alpha:!", boost::regex::extended); + TEST_INVALID_REGEX("a[[:alpha,:]", boost::regex::extended); + TEST_INVALID_REGEX("a[[:]:]]b", boost::regex::extended); + TEST_INVALID_REGEX("a[[:-:]]b", boost::regex::extended); + TEST_INVALID_REGEX("a[[:alph:]]", boost::regex::extended); + TEST_INVALID_REGEX("a[[:alphabet:]]", boost::regex::extended); + TEST_REGEX_SEARCH("[[:alnum:]]+", boost::regex::extended, "-%@a0X_-", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("[[:alpha:]]+", boost::regex::extended, " -%@aX_0-", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("[[:blank:]]+", boost::regex::extended, "a \tb", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("[[:cntrl:]]+", boost::regex::extended, " a\n\tb", match_default, make_array(2, 4, -2, -2)); + TEST_REGEX_SEARCH("[[:digit:]]+", boost::regex::extended, "a019b", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("[[:graph:]]+", boost::regex::extended, " a%b ", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("[[:lower:]]+", boost::regex::extended, "AabC", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("[[:print:]]+", boost::regex::extended, "AabC", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("[[:punct:]]+", boost::regex::extended, " %-&\t", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("[[:space:]]+", boost::regex::extended, "a \n\t\rb", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("[[:upper:]]+", boost::regex::extended, "aBCd", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("[[:xdigit:]]+", boost::regex::extended, "p0f3Cx", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\d]+", perl, "a019b", match_default, make_array(1, 4, -2, -2)); + + // + // escapes are supported in character classes if we have either + // 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)); + TEST_REGEX_SEARCH("[[:class:]", basic|no_char_classes, "[", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:class:]", basic|no_char_classes, "c", match_default, make_array(0, 1, -2, -2)); + // + // test single character escapes: + // + TEST_REGEX_SEARCH("\\w", perl, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\w", perl, "Z", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\w", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\w", perl, "z", 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(-2, -2)); + TEST_REGEX_SEARCH("\\w", perl, "`", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\w", perl, "[", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\w", perl, "@", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\W", perl, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\W", perl, "z", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\W", perl, "A", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\W", perl, "Z", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\W", perl, "_", match_default, make_array(-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("[[:lower:]]", perl|icase, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:upper:]]", perl|icase, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:alpha:]]", perl|icase, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:alnum:]]", perl|icase, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:lower:]]", perl|icase, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:upper:]]", perl|icase, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:alpha:]]", perl|icase, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:alnum:]]", perl|icase, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:lower:][:upper:]]", perl, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:lower:][:upper:]]", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:lower:][:alpha:]]", perl, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[:lower:][:alpha:]]", perl, "a", match_default, make_array(0, 1, -2, -2)); +} + +void test_sets2b(); +void test_sets2c(); + +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)); + TEST_REGEX_SEARCH("[[.two.]]", perl, "2", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.three.]]", perl, "3", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.a.]]", perl, "bac", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH("[[.\xf0.]]", perl, "b\xf0x", 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_REGEX_SEARCH("[[.NUL.][.ae.]]", perl, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.NUL.]-a]", boost::regex::extended, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.NUL.]-a]", perl, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.NUL.]-a]", boost::regex::extended, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.NUL.]-a]", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.NUL.]-[.NUL.]a]", boost::regex::extended, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.NUL.]-[.NUL.]a]", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_INVALID_REGEX("[[..]]", perl); + TEST_INVALID_REGEX("[[.not-a-collating-element.]]", perl); + 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.]]", boost::regex::extended|icase, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.A.]]", boost::regex::extended|icase, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.A.]-b]+", boost::regex::extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("[A-[.b.]]+", boost::regex::extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("[[.a.]-B]+", boost::regex::extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("[a-[.B.]]+", boost::regex::extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("[\x61]", boost::regex::extended, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[\x61-c]+", boost::regex::extended, "abcd", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("[a-\x63]+", boost::regex::extended, "abcd", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("[[.a.]-c]+", boost::regex::extended, "abcd", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("[a-[.c.]]+", boost::regex::extended, "abcd", match_default, make_array(0, 3, -2, -2)); + TEST_INVALID_REGEX("[[:alpha:]-a]", boost::regex::extended); + TEST_INVALID_REGEX("[a-[:alpha:]]", boost::regex::extended); + TEST_REGEX_SEARCH("[[.ae.]]", basic, "ae", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("[[.ae.]]", basic, "aE", match_default, make_array(-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("[[.ae.]-b]", basic, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[[.ae.]-b]", basic, "b", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[.ae.]-b]", basic, "ae", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("[a-[.ae.]]", basic, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[a-[.ae.]]", basic, "b", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("[a-[.ae.]]", basic, "ae", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("[[.ae.]]", basic|icase, "AE", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("[[.ae.]]", basic|icase, "Ae", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("[[.AE.]]", basic|icase, "Ae", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("[[.Ae.]]", basic|icase, "aE", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("[[.AE.]-B]", basic|icase, "a", match_default, make_array(-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.]]", 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, "zzaA", match_default, make_array(2, 4, -2, -2)); + TEST_INVALID_REGEX("[d-[.ae.]]", perl); + // + // try some equivalence classes: + // + 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("[[=right-curly-bracket=]]", basic, "}", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[=NUL=]]", basic, "\x0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[[=NUL=]]", perl, "\x0", 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: + // + TEST_REGEX_SEARCH("\\l+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\l]+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_INVALID_REGEX("[\\l-a]", perl); + TEST_REGEX_SEARCH("[\\L]+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[[:^lower:]]+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\L+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\u+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\u]+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\U]+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[[:^upper:]]+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\U+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\d+", perl, "AB012AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\d]+", perl, "AB012AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\D]+", perl, "01abc01", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[[:^digit:]]+", perl, "01abc01", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\D+", perl, "01abc01", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\s+", perl, "AB AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\s]+", perl, "AB AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\S]+", perl, " abc ", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[[:^space:]]+", perl, " abc ", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\S+", perl, " abc ", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\s+", perl, "AB AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("[\\w]+", perl, "AB_ AB", match_default, make_array(0, 3, -2, 6, 8, -2, -2)); + TEST_REGEX_SEARCH("[\\W]+", perl, "AB_ AB", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("[[:^word:]]+", perl, "AB_ AB", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("\\W+", perl, "AB_ AB", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("\\h+", perl, "\v\f\r\n \t\n", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("\\V+", perl, "\v\f\r\n \t\n", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("\\H+", perl, " \t\v\f\r\n ", match_default, make_array(2, 6, -2, -2)); + TEST_REGEX_SEARCH("\\v+", perl, " \t\v\f\r\n ", match_default, make_array(2, 6, -2, -2)); + test_sets2c(); +} + +void test_sets2c() +{ + using namespace boost::regex_constants; + // and some Perl style properties: + TEST_REGEX_SEARCH("\\pl+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\Pl+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\pu+", perl, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\Pu+", perl, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\pd+", perl, "AB012AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\PD+", perl, "01abc01", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\ps+", perl, "AB AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\PS+", perl, " abc ", match_default, make_array(2, 5, -2, -2)); + + TEST_REGEX_SEARCH("\\p{alnum}+", perl, "-%@a0X_-", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("\\p{alpha}+", perl, " -%@aX_0-", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("\\p{blank}+", perl, "a \tb", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{cntrl}+", perl, " a\n\tb", match_default, make_array(2, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{digit}+", perl, "a019b", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{graph}+", perl, " a%b ", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{lower}+", perl, "AabC", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\p{print}+", perl, "AabC", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{punct}+", perl, " %-&\t", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{space}+", perl, "a \n\t\rb", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("\\p{upper}+", perl, "aBCd", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\p{xdigit}+", perl, "p0f3Cx", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("\\P{alnum}+", perl, "-%@a", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\P{alpha}+", perl, " -%@a", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("\\P{blank}+", perl, "a ", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{cntrl}+", perl, " a\n", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\P{digit}+", perl, "a0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{graph}+", perl, " a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{lower}+", perl, "Aa", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{print}+", perl, "Absc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\P{punct}+", perl, " %", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{space}+", perl, "a ", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{upper}+", perl, "aB", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{xdigit}+", perl, "pf", match_default, make_array(0, 1, -2, -2)); + + TEST_INVALID_REGEX("\\p{invalid class}", perl); + TEST_INVALID_REGEX("\\p{upper", perl); + TEST_INVALID_REGEX("\\p{", perl); + TEST_INVALID_REGEX("\\p", perl); + TEST_INVALID_REGEX("\\P{invalid class}", perl); + TEST_INVALID_REGEX("\\P{upper", perl); + TEST_INVALID_REGEX("\\P{", perl); + TEST_INVALID_REGEX("\\P", perl); + + // try named characters: + TEST_REGEX_SEARCH("\\N{zero}", perl, "0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{one}", perl, "1", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{two}", perl, "2", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{three}", perl, "3", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{a}", perl, "bac", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\N{\xf0}", perl, "b\xf0x", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\N{right-curly-bracket}", perl, "}", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{NUL}", perl, "\0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[\\N{zero}-\\N{nine}]+", perl, " 0123456789 ", match_default, make_array(1, 11, -2, -2)); + + TEST_INVALID_REGEX("\\N", perl); + TEST_INVALID_REGEX("\\N{", perl); + TEST_INVALID_REGEX("\\N{}", perl); + TEST_INVALID_REGEX("\\N{invalid-name}", perl); + TEST_INVALID_REGEX("\\N{zero", perl); + test_sets2b(); +} + +void test_sets2b() +{ + using namespace boost::regex_constants; + + // and repeat with POSIX-boost::regex::extended syntax: + TEST_REGEX_SEARCH("\\pl+", boost::regex::extended, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\Pl+", boost::regex::extended, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\pu+", boost::regex::extended, "abABCab", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\Pu+", boost::regex::extended, "ABabcAB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\pd+", boost::regex::extended, "AB012AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\PD+", boost::regex::extended, "01abc01", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\ps+", boost::regex::extended, "AB AB", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("\\PS+", boost::regex::extended, " abc ", match_default, make_array(2, 5, -2, -2)); + + TEST_REGEX_SEARCH("\\p{alnum}+", boost::regex::extended, "-%@a0X_-", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("\\p{alpha}+", boost::regex::extended, " -%@aX_0-", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("\\p{blank}+", boost::regex::extended, "a \tb", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{cntrl}+", boost::regex::extended, " a\n\tb", match_default, make_array(2, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{digit}+", boost::regex::extended, "a019b", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{graph}+", boost::regex::extended, " a%b ", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{lower}+", boost::regex::extended, "AabC", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\p{print}+", boost::regex::extended, "AabC", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{punct}+", boost::regex::extended, " %-&\t", match_default, make_array(1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\p{space}+", boost::regex::extended, "a \n\t\rb", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("\\p{upper}+", boost::regex::extended, "aBCd", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH("\\p{xdigit}+", boost::regex::extended, "p0f3Cx", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("\\P{alnum}+", boost::regex::extended, "-%@a", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("\\P{alpha}+", boost::regex::extended, " -%@a", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("\\P{blank}+", boost::regex::extended, "a ", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{cntrl}+", boost::regex::extended, " a\n", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\P{digit}+", boost::regex::extended, "a0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{graph}+", boost::regex::extended, " a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{lower}+", boost::regex::extended, "Aa", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{print}+", boost::regex::extended, "Absc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("\\P{punct}+", boost::regex::extended, " %", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{space}+", boost::regex::extended, "a ", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{upper}+", boost::regex::extended, "aB", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\P{xdigit}+", boost::regex::extended, "pf", match_default, make_array(0, 1, -2, -2)); + + TEST_INVALID_REGEX("\\p{invalid class}", boost::regex::extended); + TEST_INVALID_REGEX("\\p{upper", boost::regex::extended); + TEST_INVALID_REGEX("\\p{", boost::regex::extended); + TEST_INVALID_REGEX("\\p", boost::regex::extended); + TEST_INVALID_REGEX("\\P{invalid class}", boost::regex::extended); + TEST_INVALID_REGEX("\\P{upper", boost::regex::extended); + TEST_INVALID_REGEX("\\P{", boost::regex::extended); + TEST_INVALID_REGEX("\\P", boost::regex::extended); + + // try named characters: + TEST_REGEX_SEARCH("\\N{zero}", boost::regex::extended, "0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{one}", boost::regex::extended, "1", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{two}", boost::regex::extended, "2", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{three}", boost::regex::extended, "3", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{a}", boost::regex::extended, "bac", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\N{\xf0}", boost::regex::extended, "b\xf0x", match_default, make_array(1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\N{right-curly-bracket}", boost::regex::extended, "}", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\N{NUL}", boost::regex::extended, "\0", match_default, make_array(0, 1, -2, -2)); + + TEST_INVALID_REGEX("\\N", boost::regex::extended); + TEST_INVALID_REGEX("\\N{", boost::regex::extended); + TEST_INVALID_REGEX("\\N{}", boost::regex::extended); + TEST_INVALID_REGEX("\\N{invalid-name}", boost::regex::extended); + TEST_INVALID_REGEX("\\N{zero", boost::regex::extended); +} + diff --git a/src/boost/libs/regex/test/regress/test_simple_repeats.cpp b/src/boost/libs/regex/test/regress/test_simple_repeats.cpp new file mode 100644 index 00000000..1a73fde6 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_simple_repeats.cpp @@ -0,0 +1,500 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_simple_repeats2(); + +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); + TEST_REGEX_SEARCH("\n*", perl, "\n\n", match_default, make_array(0, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("\\**", perl, "**", match_default, make_array(0, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("\\*", perl, "*", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(ab)*", perl, "abab", match_default, make_array(0, 4, 2, 4, -2, 4, 4, -2, -2)); + + TEST_INVALID_REGEX("(*)", perl); + TEST_INVALID_REGEX("(*)", boost::regex::extended); + TEST_INVALID_REGEX("\\(*\\)", basic); + TEST_INVALID_REGEX("^*", perl); + TEST_INVALID_REGEX("^*", boost::regex::extended); + TEST_INVALID_REGEX("$*", perl); + TEST_INVALID_REGEX("$*", boost::regex::extended); + TEST_INVALID_REGEX("$*", basic); + TEST_INVALID_REGEX("\\b*", perl); + TEST_INVALID_REGEX("\\B*", perl); + TEST_INVALID_REGEX("\\A*", perl); + TEST_INVALID_REGEX("\\z*", perl); + TEST_INVALID_REGEX("\\Z*", perl); + TEST_INVALID_REGEX("\\A*", perl); + TEST_INVALID_REGEX("a|*", perl); + TEST_INVALID_REGEX("a|*", boost::regex::extended); + TEST_INVALID_REGEX("(+)", perl); + TEST_INVALID_REGEX("(+)", boost::regex::extended); + TEST_INVALID_REGEX("^+", perl); + TEST_INVALID_REGEX("^+", boost::regex::extended); + TEST_INVALID_REGEX("$+", perl); + TEST_INVALID_REGEX("$+", boost::regex::extended); + TEST_INVALID_REGEX("\\b+", perl); + TEST_INVALID_REGEX("\\B+", perl); + TEST_INVALID_REGEX("\\A+", perl); + TEST_INVALID_REGEX("\\z+", perl); + TEST_INVALID_REGEX("\\Z+", perl); + TEST_INVALID_REGEX("\\A+", perl); + TEST_INVALID_REGEX("a|+", perl); + TEST_INVALID_REGEX("a|+", boost::regex::extended); + TEST_INVALID_REGEX("(?)", perl); + TEST_INVALID_REGEX("(?)", boost::regex::extended); + TEST_INVALID_REGEX("^?", perl); + TEST_INVALID_REGEX("^?", boost::regex::extended); + TEST_INVALID_REGEX("$?", perl); + TEST_INVALID_REGEX("$?", boost::regex::extended); + TEST_INVALID_REGEX("\\b?", perl); + TEST_INVALID_REGEX("\\B?", perl); + TEST_INVALID_REGEX("\\A?", perl); + TEST_INVALID_REGEX("\\z?", perl); + TEST_INVALID_REGEX("\\Z?", perl); + TEST_INVALID_REGEX("\\A?", perl); + TEST_INVALID_REGEX("a|?", perl); + TEST_INVALID_REGEX("a|?", boost::regex::extended); + TEST_INVALID_REGEX("({1,2})", perl); + TEST_INVALID_REGEX("({1,2})", boost::regex::extended); + TEST_INVALID_REGEX("^{1,2}", perl); + TEST_INVALID_REGEX("^{1,2}", boost::regex::extended); + TEST_INVALID_REGEX("${1,2}", perl); + TEST_INVALID_REGEX("${1,2}", boost::regex::extended); + TEST_INVALID_REGEX("\\b{1,2}", perl); + TEST_INVALID_REGEX("\\B{1,2}", perl); + TEST_INVALID_REGEX("\\A{1,2}", perl); + TEST_INVALID_REGEX("\\z{1,2}", perl); + TEST_INVALID_REGEX("\\Z{1,2}", perl); + TEST_INVALID_REGEX("\\A{1,2}", perl); + TEST_INVALID_REGEX("a|{1,2}", perl); + TEST_INVALID_REGEX("a|{1,2}", boost::regex::extended); + + // now try operator + : + TEST_REGEX_SEARCH("ab+", perl, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab+", perl, "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, "abbb", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab+c+", perl, "accc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab+c+", perl, "abbcc", match_default, make_array(0, 5, -2, -2)); + TEST_INVALID_REGEX("+a", perl); + TEST_INVALID_REGEX("\\<+", perl); + TEST_INVALID_REGEX("\\>+", perl); + TEST_REGEX_SEARCH("\n+", perl, "\n\n", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\+", perl, "+", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\+", perl, "++", match_default, make_array(0, 1, -2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("\\++", perl, "++", match_default, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("+", basic|bk_plus_qm, "+", match_default, make_array(0, 1, -2, -2)); + TEST_INVALID_REGEX("\\+", basic|bk_plus_qm); + TEST_REGEX_SEARCH("a\\+", basic|bk_plus_qm, "aa", match_default, make_array(0, 2, -2, -2)); + + // now try operator ? + TEST_REGEX_SEARCH("a?", perl, "b", match_default, make_array(0, 0, -2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("ab?", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("ab?", perl, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab?", perl, "sssabbbbbbsss", match_default, make_array(3, 5, -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, 2, -2, -2)); + TEST_REGEX_SEARCH("ab?c?", perl, "accc", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab?c?", perl, "abcc", match_default, make_array(0, 3, -2, -2)); + TEST_INVALID_REGEX("?a", perl); + TEST_INVALID_REGEX("\\<?", perl); + TEST_INVALID_REGEX("\\>?", perl); + TEST_REGEX_SEARCH("\n?", perl, "\n\n", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("\\?", perl, "?", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\?", perl, "?", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\??", perl, "??", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("?", basic|bk_plus_qm, "?", match_default, make_array(0, 1, -2, -2)); + TEST_INVALID_REGEX("\\?", basic|bk_plus_qm); + TEST_REGEX_SEARCH("a\\?", basic|bk_plus_qm, "aa", match_default, make_array(0, 1, -2, 1, 2, -2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\?", basic|bk_plus_qm, "b", match_default, make_array(0, 0, -2, 1, 1, -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_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)); + + // now try operator {} + TEST_REGEX_SEARCH("a{2}", perl, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a{2}", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{2}", perl, "aaa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{2,}", perl, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a{2,}", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{2,}", perl, "aaaaa", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}", perl, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a{2,4}", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}", perl, "aaa", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}", perl, "aaaa", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}", perl, "aaaaa", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a{ 2 , 4 }", perl, "aaaaa", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a{ 2 , }", perl, "aaaaa", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a{ 2 }", perl, "aaa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\{\\}", perl, "a{}", match_default, make_array(0, 3, -2, -2)); + + TEST_REGEX_SEARCH("a{2,4}?", perl, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a{2,4}?", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}?", perl, "aaa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}?", perl, "aaaa", match_default, make_array(0, 2, -2, 2, 4, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}?", perl, "aaaaa", match_default, make_array(0, 2, -2, 2, 4, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}?$", perl, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}?$", perl, "aaa", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}?$", perl, "aaaa", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a{2,4}?$", perl, "aaaaa", match_default, make_array(1, 5, -2, -2)); + TEST_REGEX_SEARCH("^a{0,1}?$", perl, "aaaaa", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(?:a){0,1}?$", perl, "aaaaa", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^a(?:bc)?", perl, "abcbc", match_any|match_all, make_array(-2, -2)); + TEST_REGEX_SEARCH("a}", perl, "a}", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{12b", perl, "a{12bc", match_default, make_array(0, 5, -2, -2)); + TEST_INVALID_REGEX("a{b", boost::regex::extended); + TEST_INVALID_REGEX("a}b", boost::regex::extended); + test_simple_repeats2(); +} + +void test_simple_repeats2() +{ + using namespace boost::regex_constants; + + TEST_REGEX_SEARCH("a{}", basic, "a{}", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a{", basic, "a{", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{1", basic, "a{1", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a{1,", basic, "a{1,", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a{1,2", basic, "a{1,2", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a{ 1 , 2", basic, "a{ 1 , 2", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("a{ }", basic, "a{ }", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a}", basic, "a}", match_default, make_array(0, 2, -2, -2)); + TEST_INVALID_REGEX("{1}", perl); + TEST_REGEX_SEARCH("a{b}", basic, "a{b}", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a{1b", basic, "a{1b", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a{1,b}", basic, "a{1,b}", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("a{1,2v}", basic, "a{1,2v}", match_default, make_array(0, 7, -2, -2)); + 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)); + TEST_REGEX_SEARCH("a\\{2,\\}", basic, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\{2,\\}", basic, "aaaaa", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a\\{2,4\\}", basic, "a", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a\\{2,4\\}", basic, "aa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a\\{2,4\\}", basic, "aaa", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a\\{2,4\\}", basic, "aaaa", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a\\{2,4\\}", basic, "aaaaa", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a\\{ 2 , 4 \\}", basic, "aaaaa", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("a\\{ 2 , \\}", basic, "aaaaa", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("a\\{ 2 \\}", basic, "aaa", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("a{}", basic, "a{}", match_default, make_array(0, 3, -2, -2)); + 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\\{ \\}", basic); + TEST_INVALID_REGEX("a\\}", basic); + TEST_INVALID_REGEX("\\{1\\}", basic); + TEST_INVALID_REGEX("a\\{b\\}", basic); + 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); + +} + +void test_fast_repeats() +{ + using namespace boost::regex_constants; + // boost::regex::extended repeat checking to exercise new algorithms: + TEST_REGEX_SEARCH("ab.*xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab.*xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*xy", perl, "ab_xy", match_default, make_array(0, 5, -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, 4, -2, -2)); + TEST_REGEX_SEARCH(".*xy", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH(".*?xy", perl, "abc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a+?xy", perl, "abc", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}", perl, "ab_______", match_default, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab.*?xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*?xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab.*?xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*?xy", perl, "ab_xy", match_default, make_array(0, 5, -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.{2,5}?xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?", perl, "ab_______", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + + // again but with slower algorithm variant: + TEST_REGEX_SEARCH("ab.*xy", perl, "abxy_", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*xy", perl, "ab_xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab.*xy", perl, "abxy", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*xy", perl, "ab_xy", match_not_dot_newline|match_not_dot_null, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab.*", perl, "ab", match_not_dot_newline|match_not_dot_null, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab.*", perl, "ab__", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH(".*xy", perl, "abc", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + TEST_REGEX_SEARCH(".*?xy", perl, "abc", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + TEST_REGEX_SEARCH(".*xy", perl, "ab\nbc", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + TEST_REGEX_SEARCH(".*?xy", perl, "ax\nbc", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab__xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab____xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_____xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab__xy", match_not_dot_newline|match_not_dot_null, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_____xy", match_not_dot_newline|match_not_dot_null, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}", perl, "ab__", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}", perl, "ab_______", match_not_dot_newline|match_not_dot_null, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab______xy", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_xy", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab.*?xy", perl, "abxy_", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*?xy", perl, "ab_xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab.*?xy", perl, "abxy", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.*?xy", perl, "ab_xy", match_not_dot_newline|match_not_dot_null, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab.*?", perl, "ab", match_not_dot_newline|match_not_dot_null, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab.*?", perl, "ab__", match_not_dot_newline|match_not_dot_null, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab__xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab____xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab_____xy_", match_not_dot_newline|match_not_dot_null, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab__xy", match_not_dot_newline|match_not_dot_null, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab_____xy", match_not_dot_newline|match_not_dot_null, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?", perl, "ab__", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?", perl, "ab_______", match_not_dot_newline|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}?xy", perl, "ab______xy", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab.{2,5}xy", perl, "ab_xy", match_not_dot_newline|match_not_dot_null, make_array(-2, -2)); + + // now again for single character repeats: + TEST_REGEX_SEARCH("ab_*xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_*xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab_*xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_*xy", perl, "ab_xy", match_default, make_array(0, 5, -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, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_*?z", perl, "ab__", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}", perl, "ab_______", match_default, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab_*?xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_*?xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab_*?xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_*?xy", perl, "ab_xy", match_default, make_array(0, 5, -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_{2,5}?xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}?xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}?xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}?xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}?xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}?", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}?", perl, "ab_______", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}?xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab_{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(5*?).somesite", perl, "//555.somesite", match_default, make_array(2, 14, 2, 5, -2, -2)); +} + +void test_fast_repeats2() +{ + using namespace boost::regex_constants; + // and again for sets: + TEST_REGEX_SEARCH("ab[_,;]*xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*xy", perl, "ab_xy", match_default, make_array(0, 5, -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, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*?xy", perl, "ab__z", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*?z", perl, "ab__", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*?.z", perl, "ab__,;,__z", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*?.z", perl, "ab__,;,__y", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}", perl, "ab_______", match_default, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab[_,;]*?xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*?xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*?xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]*?xy", perl, "ab_xy", match_default, make_array(0, 5, -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[_,;]{2,5}?xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}?xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}?xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}?xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}?xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}?", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}?", perl, "ab_______", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}?xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab[_,;]{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + + // and again for tricky sets with digraphs: + TEST_REGEX_SEARCH("ab[_[.ae.]]*xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*xy", perl, "ab_xy", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*", perl, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}", perl, "ab_______", match_default, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("ab[_[.ae.]]*?xy", perl, "abxy_", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*?xy", perl, "ab_xy_", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*?xy", perl, "abxy", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*?xy", perl, "ab_xy", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*?", perl, "ab", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]*?", perl, "ab__", match_default, make_array(0, 2, -2, -2)); + + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?xy", perl, "ab__xy_", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?xy", perl, "ab____xy_", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?xy", perl, "ab_____xy_", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?xy", perl, "ab__xy", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?xy", perl, "ab_____xy", match_default, make_array(0, 9, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?", perl, "ab__", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?", perl, "ab_______", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}?xy", perl, "ab______xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("ab[_[.ae.]]{2,5}xy", perl, "ab_xy", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("([5[.ae.]]*?).somesite", perl, "//555.somesite", match_default, make_array(2, 14, 2, 5, -2, -2)); + + TEST_REGEX_SEARCH("A[^B]*?B.*?C", perl, "AxBxxxx", match_default|match_partial, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?B.*?C", perl, "AxBx", match_default|match_partial, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?B.*?C", perl, "AxBxxxx", match_default|match_partial|match_not_dot_null, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?B.*?C", perl, "AxBx", match_default|match_partial|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?Bx*?C", perl, "AxBxxxx", match_default|match_partial|match_not_dot_null, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?Bx*?C", perl, "AxBx", match_default|match_partial|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?B[xac]*?C", perl, "AxBxxxx", match_default|match_partial|match_not_dot_null, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?B[xac]*?C", perl, "AxBx", match_default|match_partial|match_not_dot_null, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?B[xac[.ae.]]*?C", perl, "AxBxxxx", match_default|match_partial|match_not_dot_null, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("A[^B]*?B[xac[.ae.]]*?C", perl, "AxBx", match_default|match_partial|match_not_dot_null, make_array(0, 4, -2, -2)); + + +} + +void test_pocessive_repeats() +{ + using namespace boost::regex_constants; + // and again for sets: + TEST_REGEX_SEARCH("^(\\w++|\\s++)*$", perl, "now is the time for all good men to come to the aid of the party", match_default, make_array(0, 64, 59, 64, -2, -2)); + TEST_REGEX_SEARCH("^(\\w++|\\s++)*$", perl, "this is not a line with only words and spaces!", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(\\d++)(\\w)", perl, "12345a", match_default, make_array(0, 6, 0, 5, 5, 6, -2, -2)); + TEST_REGEX_SEARCH("(\\d++)(\\w)", perl, "12345+", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(\\d++)(\\w)", perl, "12345", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a++b", perl, "aaab", match_default, make_array(0, 4, -2, -2)); + TEST_REGEX_SEARCH("(a++b)", perl, "aaab", match_default, make_array(0, 4, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("([^()]++|\\([^()]*\\))+", perl, "((abc(ade)ufh()()x", match_default, make_array(2, 18, 17, 18, -2, -2)); + TEST_REGEX_SEARCH("\\(([^()]++|\\([^()]+\\))+\\)", perl, "(abc)", match_default, make_array(0, 5, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("\\(([^()]++|\\([^()]+\\))+\\)", perl, "(abc(def)xyz)", match_default, make_array(0, 13, 9, 12, -2, -2)); + TEST_REGEX_SEARCH("\\(([^()]++|\\([^()]+\\))+\\)", perl, "((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", match_default, make_array(-2, -2)); + /* + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<>", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abcd>", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc <123> hij>", match_default, make_array(0, 15, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc <def> hij>", match_default, make_array(5, 10, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc<>def>", match_default, make_array(0, 10, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc<>", match_default, make_array(4, 6, -2, -2)); + TEST_REGEX_SEARCH("< (?: (?(R) \\d++ | [^<>]*+) | (?R)) * >", perl|mod_x, "<abc", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH("((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))", perl|mod_x, "<>", match_default, make_array(0, 2, 0, 2, 0, 2, -2, -2)); + TEST_REGEX_SEARCH("((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))", perl|mod_x, "<abcd>", match_default, make_array(0, 6, 0, 6, 0, 6, -2, -2)); + TEST_REGEX_SEARCH("((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))", perl|mod_x, "<abc <123> hij>", match_default, make_array(0, 15, 0, 15, 0, 15, -2, -2)); + TEST_REGEX_SEARCH("((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))", perl|mod_x, "<abc <def> hij>", match_default, make_array(5, 10, 5, 10, 5, 10, -2, -2)); + TEST_REGEX_SEARCH("((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))", perl|mod_x, "<abc<>def>", match_default, make_array(0, 10, 0, 10, 0, 10, -2, -2)); + TEST_REGEX_SEARCH("((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))", perl|mod_x, "<abc<>", match_default, make_array(4, 6, 4, 6, 4, 6, -2, -2)); + TEST_REGEX_SEARCH("((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))", perl|mod_x, "<abc", match_default, make_array(-2, -2)); + */ + TEST_REGEX_SEARCH("x*+\\w", perl, "xxxxx", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("x*+\\w", perl, "xxxxxa", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("x{1,6}+\\w", perl, "xxxxx", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("x{1,6}+\\w", perl, "xxxxxa", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("x{1,5}+\\w", perl, "xxxxxa", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("x{1,4}+\\w", perl, "xxxxxa", match_default, make_array(0, 5, -2, -2)); + TEST_REGEX_SEARCH("x{1,3}+\\w", perl, "xxxxxa", match_default, make_array(0, 4, -2, 4, 6, -2, -2)); + TEST_INVALID_REGEX("\\d+++", perl); + TEST_INVALID_REGEX("\\d++*", perl); + TEST_INVALID_REGEX("\\d++?", perl); + TEST_INVALID_REGEX("\\d++{3}", perl); + TEST_INVALID_REGEX("\\d*++", perl); + TEST_INVALID_REGEX("\\d?++", perl); + TEST_INVALID_REGEX("\\d{1,2}++", perl); + + TEST_REGEX_SEARCH("(ab +)", perl|mod_x, "abbb", match_default, make_array(0, 4, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("(ab +?)", perl | mod_x, "abbb", match_default, make_array(0, 2, 0, 2, -2, -2)); + TEST_REGEX_SEARCH("(ab + ?)", perl | mod_x, "abbb", match_default, make_array(0, 2, 0, 2, -2, -2)); + TEST_REGEX_SEARCH("(ab ++)", perl | mod_x, "abbb", match_default, make_array(0, 4, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("(ab + +)", perl | mod_x, "abbb", match_default, make_array(0, 4, 0, 4, -2, -2)); + TEST_INVALID_REGEX("(ab + ++)", perl | mod_x); + TEST_INVALID_REGEX("(ab + + +)", perl | mod_x); + TEST_INVALID_REGEX("(ab + + ?)", perl | mod_x); + +} + diff --git a/src/boost/libs/regex/test/regress/test_tricky_cases.cpp b/src/boost/libs/regex/test/regress/test_tricky_cases.cpp new file mode 100644 index 00000000..f9cc25d1 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_tricky_cases.cpp @@ -0,0 +1,450 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +void test_tricky_cases2(); +void test_tricky_cases3(); + +void test_tricky_cases() +{ + using namespace boost::regex_constants; + // + // now follows various complex expressions designed to try and bust the matcher: + // + TEST_REGEX_SEARCH("a(((b)))c", perl, "abc", match_default, make_array(0, 3, 1, 2, 1, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl, "abd", match_default, make_array(0, 3, 1, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl, "acd", match_default, make_array(0, 3, 1, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c)d", perl, "abbd", match_default, make_array(0, 4, 1, 3, -2, -2)); + // just gotta have one DFA-buster, of course + TEST_REGEX_SEARCH("a[ab]{20}", perl, "aaaaabaaaabaaaabaaaab", match_default, make_array(0, 21, -2, -2)); + // and an inline expansion in case somebody gets tricky + TEST_REGEX_SEARCH("a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab]", perl, "aaaaabaaaabaaaabaaaab", match_default, make_array(0, 21, -2, -2)); + // and in case somebody just slips in an NFA... + TEST_REGEX_SEARCH("a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night)", perl, "aaaaabaaaabaaaabaaaabweeknights", match_default, make_array(0, 31, 21, 24, 24, 31, -2, -2)); + // one really big one + TEST_REGEX_SEARCH("1234567890123456789012345678901234567890123456789012345678901234567890", perl, "a1234567890123456789012345678901234567890123456789012345678901234567890b", match_default, make_array(1, 71, -2, -2)); + // fish for problems as brackets go past 8 + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn]", perl, "xacegikmoq", match_default, make_array(1, 8, -2, -2)); + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn][op]", perl, "xacegikmoq", match_default, make_array(1, 9, -2, -2)); + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn][op][qr]", perl, "xacegikmoqy", match_default, make_array(1, 10, -2, -2)); + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn][op][q]", perl, "xacegikmoqy", match_default, make_array(1, 10, -2, -2)); + // and as parenthesis go past 9: + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)", perl, "zabcdefghi", match_default, make_array(1, 9, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, -2, -2)); + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)(i)", perl, "zabcdefghij", match_default, make_array(1, 10, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, -2, -2)); + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)", perl, "zabcdefghijk", match_default, make_array(1, 11, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, -2, -2)); + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)", perl, "zabcdefghijkl", match_default, make_array(1, 12, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, -2, -2)); + TEST_REGEX_SEARCH("(a)d|(b)c", perl, "abc", match_default, make_array(1, 3, -1, -1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("_+((www)|(ftp)|(mailto)):_*", perl, "_wwwnocolon _mailto:", match_default, make_array(12, 20, 13, 19, -1, -1, -1, -1, 13, 19, -2, -2)); + // subtleties of matching + TEST_REGEX_SEARCH("a(b)?c\\1d", perl, "acd", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("a(b?c)+d", perl, "accd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("(wee|week)(knights|night)", perl, "weeknights", match_default, make_array(0, 10, 0, 3, 3, 10, -2, -2)); + TEST_REGEX_SEARCH(".*", perl, "abc", match_default, make_array(0, 3, -2, 3, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl, "abd", match_default, make_array(0, 3, 1, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", perl, "acd", match_default, make_array(0, 3, 1, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl, "abbd", match_default, make_array(0, 4, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl, "acd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", perl, "ad", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", perl, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", perl, "ac", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", perl, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", perl, "abbbc", match_default, make_array(0, 5, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c", perl, "ac", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("(a|ab)(bc([de]+)f|cde)", perl, "abcdef", match_default, make_array(0, 6, 0, 1, 1, 6, 3, 5, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", perl, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", perl, "ac", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)c", perl, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)c", perl, "abcc", match_default, make_array(0, 4, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)bc", perl, "abcbc", match_default, make_array(0, 5, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bb+|b)b", perl, "abb", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", perl, "abb", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", perl, "abbb", match_default, make_array(0, 4, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)bb", perl, "abbb", match_default, make_array(0, 4, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(.*).*", perl, "abcdef", match_default, make_array(0, 6, 0, 6, -2, 6, 6, 6, 6, -2, -2)); + TEST_REGEX_SEARCH("(a*)*", perl, "bc", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 2, 2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("Z(((((((a+)+)+)+)+)+)+)+|Y(((((((a+)+)+)+)+)+)+)+|X(((((((a+)+)+)+)+)+)+)+|W(((((((a+)+)+)+)+)+)+)+|V(((((((a+)+)+)+)+)+)+)+|CZ(((((((a+)+)+)+)+)+)+)+|CY(((((((a+)+)+)+)+)+)+)+|CX(((((((a+)+)+)+)+)+)+)+|CW(((((((a+)+)+)+)+)+)+)+|CV(((((((a+)+)+)+)+)+)+)+|(a+)+", perl, "bc", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("Z(((((((a+)+)+)+)+)+)+)+|Y(((((((a+)+)+)+)+)+)+)+|X(((((((a+)+)+)+)+)+)+)+|W(((((((a+)+)+)+)+)+)+)+|V(((((((a+)+)+)+)+)+)+)+|CZ(((((((a+)+)+)+)+)+)+)+|CY(((((((a+)+)+)+)+)+)+)+|CX(((((((a+)+)+)+)+)+)+)+|CW(((((((a+)+)+)+)+)+)+)+|CV(((((((a+)+)+)+)+)+)+)+|(a+)+", perl, "aaa", match_default, + make_array(0, 3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, 3, + -2, -2)); + TEST_REGEX_SEARCH("Z(((((((a+)+)+)+)+)+)+)+|Y(((((((a+)+)+)+)+)+)+)+|X(((((((a+)+)+)+)+)+)+)+|W(((((((a+)+)+)+)+)+)+)+|V(((((((a+)+)+)+)+)+)+)+|CZ(((((((a+)+)+)+)+)+)+)+|CY(((((((a+)+)+)+)+)+)+)+|CX(((((((a+)+)+)+)+)+)+)+|CW(((((((a+)+)+)+)+)+)+)+|CV(((((((a+)+)+)+)+)+)+)+|(a+)+", + perl, "Zaaa", match_default, + make_array(0, 4, + 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, + -2, -2)); + TEST_REGEX_SEARCH("xyx*xz", perl, "xyxxxxyxxxz", match_default, make_array(5, 11, -2, -2)); + // do we get the right subexpression when it is used more than once? + TEST_REGEX_SEARCH("a(b|c)*d", perl, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)*d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)+d", perl, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)+d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c?)+d", perl, "ad", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,0}d", perl, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,1}d", perl, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,1}d", perl, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,2}d", perl, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,2}d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,}d", perl, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,}d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,1}d", perl, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,2}d", perl, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,2}d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,}d", perl, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,}d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,2}d", perl, "acbd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,2}d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,4}d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,4}d", perl, "abcbd", match_default, make_array(0, 5, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,4}d", perl, "abcbcd", match_default, make_array(0, 6, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,}d", perl, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,}d", perl, "abcbd", match_default, make_array(0, 5, 3, 4, -2, -2)); + + test_tricky_cases2(); + test_tricky_cases3(); +} + +void test_tricky_cases2() +{ + using namespace boost::regex_constants; + + TEST_REGEX_SEARCH("a(((b)))c", boost::regex::extended, "abc", match_default, make_array(0, 3, 1, 2, 1, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", boost::regex::extended, "acd", match_default, make_array(0, 3, 1, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c)d", boost::regex::extended, "abbd", match_default, make_array(0, 4, 1, 3, -2, -2)); + // just gotta have one DFA-buster, of course + TEST_REGEX_SEARCH("a[ab]{20}", boost::regex::extended, "aaaaabaaaabaaaabaaaab", match_default, make_array(0, 21, -2, -2)); + // and an inline expansion in case somebody gets tricky + TEST_REGEX_SEARCH("a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab]", boost::regex::extended, "aaaaabaaaabaaaabaaaab", match_default, make_array(0, 21, -2, -2)); + // and in case somebody just slips in an NFA... + TEST_REGEX_SEARCH("a[ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab][ab](wee|week)(knights|night)", boost::regex::extended, "aaaaabaaaabaaaabaaaabweeknights", match_default, make_array(0, 31, 21, 24, 24, 31, -2, -2)); + // one really big one + TEST_REGEX_SEARCH("1234567890123456789012345678901234567890123456789012345678901234567890", boost::regex::extended, "a1234567890123456789012345678901234567890123456789012345678901234567890b", match_default, make_array(1, 71, -2, -2)); + // fish for problems as brackets go past 8 + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn]", boost::regex::extended, "xacegikmoq", match_default, make_array(1, 8, -2, -2)); + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn][op]", boost::regex::extended, "xacegikmoq", match_default, make_array(1, 9, -2, -2)); + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn][op][qr]", boost::regex::extended, "xacegikmoqy", match_default, make_array(1, 10, -2, -2)); + TEST_REGEX_SEARCH("[ab][cd][ef][gh][ij][kl][mn][op][q]", boost::regex::extended, "xacegikmoqy", match_default, make_array(1, 10, -2, -2)); + // and as parenthesis go past 9: + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)", boost::regex::extended, "zabcdefghi", match_default, make_array(1, 9, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, -2, -2)); + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)(i)", boost::regex::extended, "zabcdefghij", match_default, make_array(1, 10, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, -2, -2)); + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)", boost::regex::extended, "zabcdefghijk", match_default, make_array(1, 11, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, -2, -2)); + TEST_REGEX_SEARCH("(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)", boost::regex::extended, "zabcdefghijkl", match_default, make_array(1, 12, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, -2, -2)); + TEST_REGEX_SEARCH("(a)d|(b)c", boost::regex::extended, "abc", match_default, make_array(1, 3, -1, -1, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("_+((www)|(ftp)|(mailto)):_*", boost::regex::extended, "_wwwnocolon _mailto:", match_default, make_array(12, 20, 13, 19, -1, -1, -1, -1, 13, 19, -2, -2)); + // subtleties of matching + TEST_REGEX_SEARCH("a\\(b\\)\\?c\\1d", basic|bk_plus_qm, "acd", match_default, make_array(0, 3, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b?c)+d", boost::regex::extended, "accd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("(wee|week)(knights|night)", boost::regex::extended, "weeknights", match_default, make_array(0, 10, 0, 3, 3, 10, -2, -2)); + TEST_REGEX_SEARCH(".*", boost::regex::extended, "abc", match_default, make_array(0, 3, -2, 3, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|(c))d", boost::regex::extended, "acd", match_default, make_array(0, 3, 1, 2, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", boost::regex::extended, "abbd", match_default, make_array(0, 4, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", boost::regex::extended, "acd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b*|c|e)d", boost::regex::extended, "ad", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", boost::regex::extended, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b?)c", boost::regex::extended, "ac", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", boost::regex::extended, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b+)c", boost::regex::extended, "abbbc", match_default, make_array(0, 5, 1, 4, -2, -2)); + TEST_REGEX_SEARCH("a(b*)c", boost::regex::extended, "ac", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("(a|ab)(bc([de]+)f|cde)", boost::regex::extended, "abcdef", match_default, make_array(0, 6, 0, 1, 1, 6, 3, 5, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", boost::regex::extended, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a([bc]?)c", boost::regex::extended, "ac", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)c", boost::regex::extended, "abc", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)c", boost::regex::extended, "abcc", match_default, make_array(0, 4, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a([bc]+)bc", boost::regex::extended, "abcbc", match_default, make_array(0, 5, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bb+|b)b", boost::regex::extended, "abb", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", boost::regex::extended, "abb", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)b", boost::regex::extended, "abbb", match_default, make_array(0, 4, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("a(bbb+|bb+|b)bb", boost::regex::extended, "abbb", match_default, make_array(0, 4, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("(.*).*", boost::regex::extended, "abcdef", match_default, make_array(0, 6, 0, 6, -2, 6, 6, 6, 6, -2, -2)); + TEST_REGEX_SEARCH("(a*)*", boost::regex::extended, "bc", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, 2, 2, 2, 2, -2, -2)); + TEST_REGEX_SEARCH("xyx*xz", boost::regex::extended, "xyxxxxyxxxz", match_default, make_array(5, 11, -2, -2)); + // do we get the right subexpression when it is used more than once? + TEST_REGEX_SEARCH("a(b|c)*d", boost::regex::extended, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)*d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)+d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c)+d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c?)+d", boost::regex::extended, "ad", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,0}d", boost::regex::extended, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,1}d", boost::regex::extended, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,1}d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,2}d", boost::regex::extended, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,2}d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,}d", boost::regex::extended, "ad", match_default, make_array(0, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){0,}d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,1}d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,2}d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,2}d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,}d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){1,}d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,2}d", boost::regex::extended, "acbd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,2}d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,4}d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,4}d", boost::regex::extended, "abcbd", match_default, make_array(0, 5, 3, 4, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,4}d", boost::regex::extended, "abcbcd", match_default, make_array(0, 6, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,}d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|c){2,}d", boost::regex::extended, "abcbd", match_default, make_array(0, 5, 3, 4, -2, -2)); + // perl only: + TEST_REGEX_SEARCH("a(b|c?)+d", perl, "abcd", match_default, make_array(0, 4, 3, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b+|((c)*))+d", perl, "abd", match_default, make_array(0, 3, 2, 2, 2, 2, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b+|((c)*))+d", perl, "abcd", match_default, make_array(0, 4, 3, 3, 3, 3, 2, 3, -2, -2)); + // posix only: + TEST_REGEX_SEARCH("a(b|c?)+d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b|((c)*))+d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, 2, 3, 2, 3, -2, -2)); + TEST_REGEX_SEARCH("a(b+|((c)*))+d", boost::regex::extended, "abd", match_default, make_array(0, 3, 1, 2, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("a(b+|((c)*))+d", boost::regex::extended, "abcd", match_default, make_array(0, 4, 2, 3, 2, 3, 2, 3, -2, -2)); + // literals: + TEST_REGEX_SEARCH("\\**?/{}", literal, "\\**?/{}", match_default, make_array(0, 7, -2, -2)); + TEST_REGEX_SEARCH("\\**?/{}", literal, "\\**?/{", match_default, make_array(-2, -2)); + // try to match C++ syntax elements: + // line comment: + TEST_REGEX_SEARCH("//[^\\n]*", perl, "++i //here is a line comment\n", match_default, make_array(4, 28, -2, -2)); + // block comment: + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", perl, "/* here is a block comment */", match_default, make_array(0, 29, 26, 27, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", perl, "/**/", match_default, make_array(0, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", perl, "/***/", match_default, make_array(0, 5, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", perl, "/****/", match_default, make_array(0, 6, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", perl, "/*****/", match_default, make_array(0, 7, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", perl, "/*****/*/", match_default, make_array(0, 7, -1, -1, -2, -2)); + // preprossor directives: + TEST_REGEX_SEARCH("^[[:blank:]]*#([^\\n]*\\\\[[:space:]]+)*[^\\n]*", perl, "#define some_symbol", match_default, make_array(0, 19, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("^[[:blank:]]*#([^\\n]*\\\\[[:space:]]+)*[^\\n]*", perl, "#define some_symbol(x) #x", match_default, make_array(0, 25, -1, -1, -2, -2)); + // try to match C++ syntax elements: + // line comment: + TEST_REGEX_SEARCH("//[^\\n]*", boost::regex::extended&~no_escape_in_lists, "++i //here is a line comment\n", match_default, make_array(4, 28, -2, -2)); + // block comment: + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", boost::regex::extended&~no_escape_in_lists, "/* here is a block comment */", match_default, make_array(0, 29, 26, 27, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", boost::regex::extended&~no_escape_in_lists, "/**/", match_default, make_array(0, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", boost::regex::extended&~no_escape_in_lists, "/***/", match_default, make_array(0, 5, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", boost::regex::extended&~no_escape_in_lists, "/****/", match_default, make_array(0, 6, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", boost::regex::extended&~no_escape_in_lists, "/*****/", match_default, make_array(0, 7, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("/\\*([^*]|\\*+[^*/])*\\*+/", boost::regex::extended&~no_escape_in_lists, "/*****/*/", match_default, make_array(0, 7, -1, -1, -2, -2)); + // preprossor directives: + TEST_REGEX_SEARCH("^[[:blank:]]*#([^\\n]*\\\\[[:space:]]+)*[^\\n]*", boost::regex::extended&~no_escape_in_lists, "#define some_symbol", match_default, make_array(0, 19, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("^[[:blank:]]*#([^\\n]*\\\\[[:space:]]+)*[^\\n]*", boost::regex::extended&~no_escape_in_lists, "#define some_symbol(x) #x", match_default, make_array(0, 25, -1, -1, -2, -2)); + // perl only: + TEST_REGEX_SEARCH("^[[:blank:]]*#([^\\n]*\\\\[[:space:]]+)*[^\\n]*", perl, "#define some_symbol(x) \\ \r\n foo();\\\r\n printf(#x);", match_default, make_array(0, 53, 30, 42, -2, -2)); + // POSIX leftmost longest checks: + TEST_REGEX_SEARCH("(aaa)|(\\w+)", boost::regex::extended&~no_escape_in_lists, "a", match_default, make_array(0, 1, -1, -1, 0, 1, -2, -2)); + TEST_REGEX_SEARCH("(aaa)|(\\w+)", boost::regex::extended&~no_escape_in_lists, "aa", match_default, make_array(0, 2, -1, -1, 0, 2, -2, -2)); + TEST_REGEX_SEARCH("(aaa)|(\\w+)", boost::regex::extended&~no_escape_in_lists, "aaa", match_default, make_array(0, 3, 0, 3, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("(aaa)|(\\w+)", boost::regex::extended&~no_escape_in_lists, "aaaa", match_default, make_array(0, 4, -1, -1, 0, 4, -2, -2)); + TEST_REGEX_SEARCH("($)|(\\>)", boost::regex::extended&~no_escape_in_lists, "aaaa", match_default, make_array(4, 4, 4, 4, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("($)|(\\>)", boost::regex::extended&~no_escape_in_lists, "aaaa", match_default|match_not_eol, make_array(4, 4, -1, -1, 4, 4, -2, -2)); + TEST_REGEX_SEARCH("(aaa)(ab)*", boost::regex::extended, "aaaabab", match_default, make_array(0, 7, 0, 3, 5, 7, -2, -2)); +} + +void test_tricky_cases3() +{ + using namespace boost::regex_constants; + TEST_REGEX_SEARCH("((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)?", perl, "0xFF", match_default, make_array(0, 4, 0, 4, 0, 4, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)?", perl, "35", match_default, make_array(0, 2, 0, 2, -1, -1, 0, 2, -1, -1, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)?", perl, "0xFFu", match_default, make_array(0, 5, 0, 4, 0, 4, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)?", perl, "0xFFL", match_default, make_array(0, 5, 0, 4, 0, 4, -1, -1, 4, 5, -1, -1, -1, -1, -2, -2)); + TEST_REGEX_SEARCH("((0x[[:xdigit:]]+)|([[:digit:]]+))u?((int(8|16|32|64))|L)?", perl, "0xFFFFFFFFFFFFFFFFuint64", match_default, make_array(0, 24, 0, 18, 0, 18, -1, -1, 19, 24, 19, 24, 22, 24, -2, -2)); + // strings: + TEST_REGEX_SEARCH("'([^\\\\']|\\\\.)*'", perl, "'\\x3A'", match_default, make_array(0, 6, 4, 5, -2, -2)); + TEST_REGEX_SEARCH("'([^\\\\']|\\\\.)*'", perl, "'\\''", match_default, make_array(0, 4, 1, 3, -2, -2)); + TEST_REGEX_SEARCH("'([^\\\\']|\\\\.)*'", perl, "'\\n'", match_default, make_array(0, 4, 1, 3, -2, -2)); + // posix only: + TEST_REGEX_SEARCH("^[[:blank:]]*#([^\\n]*\\\\[[:space:]]+)*[^\\n]*", awk, "#define some_symbol(x) \\ \r\n foo();\\\r\n printf(#x);", match_default, make_array(0, 53, 28, 42, -2, -2)); + // now try and test some unicode specific characters: +#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560) + TEST_REGEX_SEARCH_W(L"[[:unicode:]]+", perl, L"a\x0300\x0400z", match_default, make_array(1, 3, -2, -2)); + TEST_REGEX_SEARCH_W(L"[\x10-\xff]", perl, L"\x0300\x0400", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH_W(L"[\01-\05]{5}", perl, L"\x0300\x0400\x0300\x0400\x0300\x0400", match_default, make_array(-2, -2)); +#if !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) + TEST_REGEX_SEARCH_W(L"[\x300-\x400]+", perl, L"\x0300\x0400\x0300\x0400\x0300\x0400", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH_W(L"[\\x{300}-\\x{400}]+", perl, L"\x0300\x0400\x0300\x0400\x0300\x0400", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH_W(L"\\x{300}\\x{400}+", perl, L"\x0300\x0400\x0400\x0400\x0400\x0400", match_default, make_array(0, 6, -2, -2)); +#endif +#endif + // finally try some case insensitive matches: + TEST_REGEX_SEARCH("0123456789@abcdefghijklmnopqrstuvwxyz\\[\\\\\\]\\^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ\\{\\|\\}", perl|icase, "0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}", match_default, make_array(0, 72, -2, -2)); + TEST_REGEX_SEARCH("a", perl|icase, "A", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("A", perl|icase, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("[abc]+", perl|icase, "abcABC", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[ABC]+", perl|icase, "abcABC", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[a-z]+", perl|icase, "abcABC", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[A-Z]+", perl|icase, "abzANZ", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[a-Z]+", perl|icase, "abzABZ", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[A-z]+", perl|icase, "abzABZ", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[[:lower:]]+", perl|icase, "abyzABYZ", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("[[:upper:]]+", perl|icase, "abzABZ", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[[:word:]]+", perl|icase, "abcZZZ", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("[[:alpha:]]+", perl|icase, "abyzABYZ", match_default, make_array(0, 8, -2, -2)); + TEST_REGEX_SEARCH("[[:alnum:]]+", perl|icase, "09abyzABYZ", match_default, make_array(0, 10, -2, -2)); + + // known and suspected bugs: + TEST_REGEX_SEARCH("\\(", perl, "(", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\)", perl, ")", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\$", perl, "$", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\^", perl, "^", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\.", perl, ".", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\*", perl, "*", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\+", perl, "+", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\?", perl, "?", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\[", perl, "[", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\]", perl, "]", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\|", perl, "|", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\\\", perl, "\\", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("#", perl, "#", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\#", perl, "#", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a-", perl, "a-", match_default, make_array(0, 2, -2, -2)); + TEST_REGEX_SEARCH("\\-", perl, "-", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\{", perl, "{", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("\\}", perl, "}", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("0", perl, "0", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("1", perl, "1", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("9", perl, "9", 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("B", perl, "B", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("<", perl, "<", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(">", perl, ">", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("w", perl, "w", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("W", perl, "W", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("`", perl, "`", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(" ", perl, " ", 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(",", perl, ",", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("a", perl, "a", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("f", perl, "f", 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("r", perl, "r", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("t", perl, "t", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("v", perl, "v", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("c", perl, "c", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("x", perl, "x", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH(":", perl, ":", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH("(\\.[[:alnum:]]+){2}", perl, "w.a.b ", match_default, make_array(1, 5, 3, 5, -2, -2)); + + // new bugs detected in spring 2003: + TEST_REGEX_SEARCH("b", perl, "abc", match_default|match_continuous, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?!foo)bar", perl, "foobar", match_default, make_array(3, 6, -2, -2)); + TEST_REGEX_SEARCH("(?!foo)bar", perl, "??bar", match_default, make_array(2, 5, -2, -2)); + TEST_REGEX_SEARCH("(?!foo)bar", perl, "barfoo", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?!foo)bar", perl, "bar??", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("(?!foo)bar", perl, "bar", match_default, make_array(0, 3, -2, -2)); + TEST_REGEX_SEARCH("a\\Z", perl, "a\nb", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("()", perl, "abc", 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, "abc", match_default, make_array(0, 0, 0, 0, -2, -2)); + TEST_REGEX_SEARCH("^()+", perl, "abc", match_default, make_array(0, 0, 0, 0, -2, -2)); + TEST_REGEX_SEARCH("^(){1}", perl, "abc", match_default, make_array(0, 0, 0, 0, -2, -2)); + TEST_REGEX_SEARCH("^(){2}", perl, "abc", match_default, make_array(0, 0, 0, 0, -2, -2)); + TEST_REGEX_SEARCH("^((){2})", perl, "abc", match_default, make_array(0, 0, 0, 0, 0, 0, -2, -2)); + TEST_REGEX_SEARCH("()", perl, "", match_default, make_array(0, 0, 0, 0, -2, -2)); + TEST_REGEX_SEARCH("()\\1", perl, "", match_default, make_array(0, 0, 0, 0, -2, -2)); + TEST_REGEX_SEARCH("()\\1", perl, "a", match_default, make_array(0, 0, 0, 0, -2, 1, 1, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a()\\1b", perl, "ab", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("a()b\\1", perl, "ab", match_default, make_array(0, 2, 1, 1, -2, -2)); + TEST_REGEX_SEARCH("([a-c]+)\\1", perl, "abcbc", match_default, make_array(1, 5, 1, 3, -2, -2)); + TEST_REGEX_SEARCH(".+abc", perl, "xxxxxxxxyyyyyyyyab", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(.+)\\1", perl, "abcdxxxyyyxxxyyy", match_default, make_array(4, 16, 4, 10, -2, -2)); + // this should not throw: + TEST_REGEX_SEARCH("[_]+$", perl, "___________________________________________x", match_default, make_array(-2, -2)); + // bug in V4 code detected 2004/05/12: + TEST_REGEX_SEARCH("\\l+", perl|icase, "abcXYZ", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("\\u+", perl|icase, "abcXYZ", match_default, make_array(0, 6, -2, -2)); + TEST_REGEX_SEARCH("(a)(?:b)", perl|nosubs, "ab", match_default, make_array(0, 2, -2, -2)); + // bug reported 2006-09-20: + TEST_REGEX_SEARCH("(?:\\d{9}.*){2}", perl, "123456789dfsdfsdfsfsdfds123456789b", match_default, make_array(0, 34, -2, -2)); + TEST_REGEX_SEARCH("(?:\\d{9}.*){2}", perl, "123456789dfsdfsdfsfsdfds12345678", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("(?:\\d{9}.*){2}", perl, "123456789dfsdfsdfsfsdfds", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])){3}$", perl, "1.2.03", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])){3,4}$", perl, "1.2.03", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH("^(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])(\\.(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]?[0-9])){3,4}?$", perl, "1.2.03", match_default, make_array(-2, -2)); + + + // + // the strings in the next test case are too long for most compilers to cope with, + // we have to break them up and call the testing procs directly rather than rely on the macros: + // + static const char* big_text = "00001 01 \r\n00002 02 1 2 3 4 5 6" + "7 8 9 0\r\n00003 03 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\r\n" + "00004 04 \r\n00005 05 \r\n00006 06 " + "Seite: 0001\r\n00007 07 " + "StartSeitEEnde: 0001\r\n00008 08 " + "StartSeiTe Ende: 0001\r\n00009 09 " + "Start seiteEnde: 0001\r\n00010 10 " + "28.2.03\r\n00011 11 " + "Page: 0001\r\n00012 12 " + "Juhu die Erste: 0001\r\n00013 13 " + "Es war einmal! 0001\r\n00014 14 ABCDEFGHIJKLMNOPQRSTUVWXYZ0001\r\n" + "00015 15 abcdefghijklmnopqrstuvwxyz0001\r\n" + "00016 16 lars.schmeiser@gft.com\r\n00017 17 \r\n" + "00018 18 \r\n00019 19 \r\n00020 20 \r\n00021 21 1 2 3 4 5 " + "6 7 8 9 0\r\n" + "00022 22 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\r\n" + "00023 01 \r\n00024 02 1 2 3 4 5 6 7 8 9 0\r\n" + "00025 03 0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\r\n" + "00026 04 \r\n00027 05 \r\n00028 06 " + "Seite: 0002\r\n00029 07 StartSeitEEnde: 0002\r\n" + "00030 08 " + "StartSeiTe Ende: 0002\r\n00031 09 " + "Start seiteEnde: 0002\r\n00032 10 " + "28.02.2003\r\n00033 11 " + "Page: 0002\r\n00034 12 " + "Juhu die Erste: 0002\r\n00035 13 " + "Es war einmal! 0002\r\n00036 14 ABCDEFGHIJKLMNOPQRSTUVWXYZ0002\r\n00037 " + "15 abcdefghijklmnopqrstuvwxyz0002\r\n00038 16 " + "lars.schmeiser@194.1.12.111\r\n00039 17 \r\n00040 18 \r\n00041 19 \r\n" + "00042 20 \r\n00043 21 1 2 3 4 5 6 7 8 9 0\r\n"; + + do{ + test_info<char>::set_info(__FILE__, __LINE__, + "(.*\\r\\n){3}.* abcdefghijklmnopqrstuvwxyz.*\\r\\n", + perl, big_text, match_default|match_not_dot_newline, + 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) && !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + do{ + std::string st(big_text); + test_info<wchar_t>::set_info(__FILE__, __LINE__, + L"(.*\\r\\n){3}.* abcdefghijklmnopqrstuvwxyz.*\\r\\n", + perl, std::wstring(st.begin(), st.end()), match_default|match_not_dot_newline, + make_array(753, 1076, 934, 1005, -2, 2143, 2466, 2324, 2395, -2, -2)); + test(char(0), test_regex_search_tag()); + }while(0); +#endif + + do { + const unsigned char bytes[] = { 0x15,0x0,0x28,0x28,0x85,0x7c,0xb5,0x7c,0x7c,0x7c,0x7c,0x0,0x7c,0x7c,0x16,0x7c,0x7c,0x7c,0x67,0x85,0x0,0xb5,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x3d,0x0,0x7c,0x7c,0x29,0x3f,0x28,0x3f,0x31,0x29,0xb5,0x2a,0xb5,0xff,0xb5,0xb5,0x85,0xb5,0x67,0xa,0x2a,0xf7,0x2a,0x7c,0x7c,0x32,0x29,0x5c,0x5a,0x3a,0x6b }; + std::string str((char*)bytes, sizeof(bytes)); + test_info<char>::set_info(__FILE__, __LINE__, + str.c_str(), + perl, str.c_str(), match_default | match_not_dot_newline, + make_array(0, 1, -2, -2)); + test(char(0), test_regex_search_tag()); + } while(0); + + +} + diff --git a/src/boost/libs/regex/test/regress/test_unicode.cpp b/src/boost/libs/regex/test/regress/test_unicode.cpp new file mode 100644 index 00000000..eed5b456 --- /dev/null +++ b/src/boost/libs/regex/test/regress/test_unicode.cpp @@ -0,0 +1,170 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE test_unicode.hpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Unicode specific tests (requires ICU). + */ + +#include <boost/regex/config.hpp> +#ifdef BOOST_HAS_ICU +#include "test.hpp" + +#ifdef BOOST_MSVC +#pragma warning(disable:4127) +#endif + +#ifndef BOOST_NO_STD_WSTRING + +#define TEST_REGEX_SEARCH_U(s, f, t, m, a)\ + do{\ + const wchar_t e[] = { s };\ + std::wstring se(e, (sizeof(e) / sizeof(wchar_t)) - 1);\ + const wchar_t st[] = { t };\ + std::wstring sst(st, (sizeof(st) / sizeof(wchar_t)) - 1);\ + test_info<wchar_t>::set_info(__FILE__, __LINE__, se, f, sst, m, a);\ + test_icu(wchar_t(0), test_regex_search_tag());\ + }while(0) + +#define TEST_REGEX_CLASS_U(classname, character)\ + TEST_REGEX_SEARCH_U(\ + L"[[:" BOOST_JOIN(L, BOOST_STRINGIZE(classname)) L":]]",\ + perl, \ + BOOST_JOIN(L, \ + BOOST_STRINGIZE(\ + BOOST_JOIN(\x, character))), \ + match_default, \ + make_array(0, 1, -2, -2)) + +#else + +#define TEST_REGEX_SEARCH_U(s, f, t, m, a) +#define TEST_REGEX_CLASS_U(classname, character) + +#endif + +void test_unicode() +{ + using namespace boost::regex_constants; + + TEST_REGEX_CLASS_U(L*, 3108); + TEST_REGEX_CLASS_U(Letter, 3108); + TEST_REGEX_CLASS_U(Lu, 2145); + TEST_REGEX_CLASS_U(Uppercase Letter, 2145); + TEST_REGEX_CLASS_U(Ll, 2146); + TEST_REGEX_CLASS_U(Lowercase Letter, 2146); + TEST_REGEX_CLASS_U(Lt, 1FFC); + TEST_REGEX_CLASS_U(Titlecase Letter, 1FFC); + TEST_REGEX_CLASS_U(Lm, 1D61); + TEST_REGEX_CLASS_U(Modifier Letter, 1D61); + TEST_REGEX_CLASS_U(Lo, 1974); + TEST_REGEX_CLASS_U(Other Letter, 1974); + TEST_REGEX_CLASS_U(M*, 20EA); + TEST_REGEX_CLASS_U(Mark, 20EA); + TEST_REGEX_CLASS_U(Mn, 20EA); + TEST_REGEX_CLASS_U(Non-Spacing Mark, 20EA); + TEST_REGEX_CLASS_U(Mc, 1938); + TEST_REGEX_CLASS_U(Spacing Combining Mark, 1938); + TEST_REGEX_CLASS_U(Me, 0488); + TEST_REGEX_CLASS_U(Enclosing Mark, 0488); + TEST_REGEX_CLASS_U(N*, 0669); + TEST_REGEX_CLASS_U(Number, 0669); + TEST_REGEX_CLASS_U(Nd, 0669); + TEST_REGEX_CLASS_U(Decimal Digit Number, 0669); + TEST_REGEX_CLASS_U(Nl, 303A); + TEST_REGEX_CLASS_U(Letter Number, 303A); + TEST_REGEX_CLASS_U(No, 2793); + TEST_REGEX_CLASS_U(Other Number, 2793); + + TEST_REGEX_CLASS_U(S*, 2144); + TEST_REGEX_CLASS_U(Symbol, 2144); + TEST_REGEX_CLASS_U(Sm, 2144); + TEST_REGEX_CLASS_U(Math Symbol, 2144); + TEST_REGEX_CLASS_U(Sc, 20B1); + TEST_REGEX_CLASS_U(Currency Symbol, 20B1); + TEST_REGEX_CLASS_U(Sk, 1FFE); + TEST_REGEX_CLASS_U(Modifier Symbol, 1FFE); + TEST_REGEX_CLASS_U(So, 19FF); + TEST_REGEX_CLASS_U(Other Symbol, 19FF); + + TEST_REGEX_CLASS_U(P*, 005F); + TEST_REGEX_CLASS_U(Punctuation, 005F); + TEST_REGEX_CLASS_U(Pc, 005F); + TEST_REGEX_CLASS_U(Connector Punctuation, 005F); + TEST_REGEX_CLASS_U(Pd, 002D); + TEST_REGEX_CLASS_U(Dash Punctuation, 002D); + TEST_REGEX_CLASS_U(Ps, 0028); + TEST_REGEX_CLASS_U(Open Punctuation, 0028); + TEST_REGEX_CLASS_U(Pe, FF63); + TEST_REGEX_CLASS_U(Close Punctuation, FF63); + TEST_REGEX_CLASS_U(Pi, 2039); + TEST_REGEX_CLASS_U(Initial Punctuation, 2039); + TEST_REGEX_CLASS_U(Pf, 203A); + TEST_REGEX_CLASS_U(Final Punctuation, 203A); + TEST_REGEX_CLASS_U(Po, 2038); + TEST_REGEX_CLASS_U(Other Punctuation, 2038); + + TEST_REGEX_CLASS_U(Z*, 202F); + TEST_REGEX_CLASS_U(Separator, 202F); + TEST_REGEX_CLASS_U(Zs, 202F); + TEST_REGEX_CLASS_U(Space Separator, 202F); + TEST_REGEX_CLASS_U(Zl, 2028); + TEST_REGEX_CLASS_U(Line Separator, 2028); + TEST_REGEX_CLASS_U(Zp, 2029); + TEST_REGEX_CLASS_U(Paragraph Separator, 2029); +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // Some tests have to be disabled for VC6 because the compiler + // mangles the string literals... + TEST_REGEX_CLASS_U(C*, 009F); + TEST_REGEX_CLASS_U(Other, 009F); + TEST_REGEX_CLASS_U(Cc, 009F); + TEST_REGEX_CLASS_U(Control, 009F); +#endif + TEST_REGEX_CLASS_U(Cf, FFFB); + TEST_REGEX_CLASS_U(Format, FFFB); + //TEST_REGEX_CLASS_U(Cs, DC00); + //TEST_REGEX_CLASS_U(Surrogate, DC00); + TEST_REGEX_CLASS_U(Co, F8FF); + TEST_REGEX_CLASS_U(Private Use, F8FF); + TEST_REGEX_CLASS_U(Cn, FFFF); + TEST_REGEX_CLASS_U(Not Assigned, FFFF); + TEST_REGEX_CLASS_U(Any, 2038); + TEST_REGEX_CLASS_U(Assigned, 2038); + TEST_REGEX_CLASS_U(ASCII, 7f); + TEST_REGEX_SEARCH_U(L"[[:Assigned:]]", perl, L"\xffff", match_default, make_array(-2, -2)); + TEST_REGEX_SEARCH_U(L"[[:ASCII:]]", perl, L"\x80", match_default, make_array(-2, -2)); + + TEST_REGEX_SEARCH_U(L"\\N{KHMER DIGIT SIX}", perl, L"\x17E6", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH_U(L"\\N{MODIFIER LETTER LOW ACUTE ACCENT}", perl, L"\x02CF", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH_U(L"\\N{SUPERSCRIPT ONE}", perl, L"\x00B9", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH_U(L"[\\N{KHMER DIGIT SIX}]", perl, L"\x17E6", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH_U(L"[\\N{MODIFIER LETTER LOW ACUTE ACCENT}]", perl, L"\x02CF", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH_U(L"[\\N{SUPERSCRIPT ONE}]", perl, L"\x00B9", match_default, make_array(0, 1, -2, -2)); + TEST_REGEX_SEARCH_U(L"\\N{CJK UNIFIED IDEOGRAPH-7FED}", perl, L"\x7FED", match_default, make_array(0, 1, -2, -2)); +#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300) + // Some tests have to be disabled for VC6 because the compiler + // mangles the string literals... + TEST_REGEX_SEARCH_U(L"\\w+", perl, L" e\x301" L"coute ", match_default, make_array(1, 8, -2, -2)); + + TEST_REGEX_SEARCH_U(L"^", perl, L" \x2028 \x2029 \x000D\x000A \x000A \x000C \x000D \x0085 ", + match_default | match_not_bol, make_array(2, 2, -2, 4, 4, -2, 7, 7, -2, 9, 9, -2, 11, 11, -2, 13, 13, -2, 15, 15, -2, -2)); + TEST_REGEX_SEARCH_U(L"$", perl, L" \x2028 \x2029 \x000D\x000A \x000A \x000C \x000D \x0085 ", + match_default | match_not_eol, make_array(1, 1, -2, 3, 3, -2, 5, 5, -2, 8, 8, -2, 10, 10, -2, 12, 12, -2, 14, 14, -2, -2)); + TEST_REGEX_SEARCH_U(L".", perl, L" \x2028\x2029\x000D\x000A\x000A\x000C\x000D\x0085 ", + match_default | match_not_dot_newline, make_array(0, 1, -2, 9, 10, -2, -2)); +#endif +} + +#else +void test_unicode(){} +#endif diff --git a/src/boost/libs/regex/test/regress/vc6-stlport.mak b/src/boost/libs/regex/test/regress/vc6-stlport.mak new file mode 100644 index 00000000..4e1acff0 --- /dev/null +++ b/src/boost/libs/regex/test/regress/vc6-stlport.mak @@ -0,0 +1,77 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regression tests +# +# Visual C++ 6 + full stlport 4.x +# +# we don't test single threaded builds as stlport doesn't support these... +# +# +# Add additional compiler options here: +# +CXXFLAGS= +# +# Add additional debugging options here: +# +CXXDEBUG=/D_STLP_DEBUG=1 +# +# Add additional include directories here: +# +INCLUDES= +# +# add additional linker flags here: +# +XLFLAGS= +# +# sources to compile for each test: +# +SOURCES=*.cpp + +!IF "$(MSVCDIR)" == "" +!ERROR Variable MSVCDIR not set. +!ENDIF + +!IF "$(STLPORT_PATH)" == "" +!ERROR Variable STLPORT_PATH not set. +!ENDIF + + +CFLAGS= $(INCLUDES) /I$(STLPORT_PATH)\stlport /Zm400 /GF /Gy -GX -GR -I..\..\..\..\ $(CXXFLAGS) /DBOOST_LIB_DIAGNOSTIC=1 + +LFLAGS= -link /LIBPATH:..\..\..\..\stage\lib /LIBPATH:..\..\build\vc6-stlport /LIBPATH:$(STLPORT_PATH)\lib user32.lib $(XLFLAGS) + +all :: r3-vc6-stlport.exe r4-vc6-stlport.exe r5-vc6-stlport.exe r6-vc6-stlport.exe r7-vc6-stlport.exe r8-vc6-stlport.exe + r1-vc6-stlport + r2-vc6-stlport + r3-vc6-stlport + r4-vc6-stlport + r5-vc6-stlport + r6-vc6-stlport + -copy ..\..\build\vc6\boost_regex*.dll + -copy ..\..\..\..\stage\lib\boost_regex*.dll + r7-vc6-stlport + r8-vc6-stlport + +r3-vc6-stlport.exe : + cl /MT $(CFLAGS) /O2 -o r3-vc6-stlport.exe $(SOURCES) $(LFLAGS) + +r4-vc6-stlport.exe : + cl /MTd $(CFLAGS) -o r4-vc6-stlport.exe $(SOURCES) $(LFLAGS) + +r5-vc6-stlport.exe : + cl /MD $(CFLAGS) /O2 -o r5-vc6-stlport.exe $(SOURCES) $(LFLAGS) + +r6-vc6-stlport.exe : + cl /MDd $(CFLAGS) -o r6-vc6-stlport.exe $(SOURCES) $(LFLAGS) + +r7-vc6-stlport.exe : + cl /MD $(CFLAGS) /O2 /DBOOST_ALL_DYN_LINK -o r7-vc6-stlport.exe $(SOURCES) $(LFLAGS) + +r8-vc6-stlport.exe : + cl /MDd $(CFLAGS) /DBOOST_ALL_DYN_LINK -o r8-vc6-stlport.exe $(SOURCES) $(LFLAGS) + + + diff --git a/src/boost/libs/regex/test/regress/vc6.mak b/src/boost/libs/regex/test/regress/vc6.mak new file mode 100644 index 00000000..019fcf62 --- /dev/null +++ b/src/boost/libs/regex/test/regress/vc6.mak @@ -0,0 +1,68 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regression tests +# +# Visual C++ 6 +# +# +# Add additional compiler options here: +# +CXXFLAGS= +# +# Add additional include directories here: +# +INCLUDES= +# +# add additional linker flags here: +# +XLFLAGS= +# +# sources to compile for each test: +# +SOURCES=*.cpp + +CFLAGS= $(INCLUDES) /Zm400 /GF /Gy -GX -GR -I..\..\..\..\ /DBOOST_LIB_DIAGNOSTIC=1 $(CXXFLAGS) + +LFLAGS= -link /LIBPATH:..\..\..\..\stage\lib /LIBPATH:..\..\build\vc6 user32.lib $(XLFLAGS) + +all :: r1-vc6.exe r2-vc6.exe r3-vc6.exe r4-vc6.exe r5-vc6.exe r6-vc6.exe r7-vc6.exe r8-vc6.exe + r1-vc6 + r2-vc6 + r3-vc6 + r4-vc6 + r5-vc6 + r6-vc6 + -copy ..\..\build\vc6\boost_regex*.dll + -copy ..\..\..\..\stage\lib\boost_regex*.dll + r7-vc6 + r8-vc6 + +r1-vc6.exe : + cl /ML $(CFLAGS) /O2 -o r1-vc6.exe $(SOURCES) $(LFLAGS) + +r2-vc6.exe : + cl /MLd $(CFLAGS) -o r2-vc6.exe $(SOURCES) $(LFLAGS) + +r3-vc6.exe : + cl /MT $(CFLAGS) /O2 -o r3-vc6.exe $(SOURCES) $(LFLAGS) + +r4-vc6.exe : + cl /MTd $(CFLAGS) -o r4-vc6.exe $(SOURCES) $(LFLAGS) + +r5-vc6.exe : + cl /MD $(CFLAGS) /O2 -o r5-vc6.exe $(SOURCES) $(LFLAGS) + +r6-vc6.exe : + cl /MDd $(CFLAGS) -o r6-vc6.exe $(SOURCES) $(LFLAGS) + +r7-vc6.exe : + cl /MD $(CFLAGS) /O2 /DBOOST_ALL_DYN_LINK -o r7-vc6.exe $(SOURCES) $(LFLAGS) + +r8-vc6.exe : + cl /MDd $(CFLAGS) /DBOOST_ALL_DYN_LINK -o r8-vc6.exe $(SOURCES) $(LFLAGS) + + + diff --git a/src/boost/libs/regex/test/regress/vc7.mak b/src/boost/libs/regex/test/regress/vc7.mak new file mode 100644 index 00000000..d4ea3bc1 --- /dev/null +++ b/src/boost/libs/regex/test/regress/vc7.mak @@ -0,0 +1,68 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regression tests +# +# Visual C++ 6 +# +# +# Add additional compiler options here: +# +CXXFLAGS= +# +# Add additional include directories here: +# +INCLUDES= +# +# add additional linker flags here: +# +XLFLAGS= +# +# sources to compile for each test: +# +SOURCES=*.cpp + +CFLAGS= $(INCLUDES) /Zm400 /O2 /GB /GF /Gy -GX -GR -I..\..\..\..\ $(CXXFLAGS) /DBOOST_LIB_DIAGNOSTIC=1 /Zc:wchar_t + +LFLAGS= -link /LIBPATH:..\..\..\..\stage\lib /LIBPATH:..\..\build\vc7 $(XLFLAGS) + +all :: r1-vc7.exe r2-vc7.exe r3-vc7.exe r4-vc7.exe r5-vc7.exe r6-vc7.exe r7-vc7.exe r8-vc7.exe + r1-vc7 + r2-vc7 + r3-vc7 + r4-vc7 + r5-vc7 + r6-vc7 + -copy ..\..\build\vc7\boost_regex*.dll + -copy ..\..\..\..\stage\lib\boost_regex*.dll + r7-vc7 + r8-vc7 + +r1-vc7.exe : + cl /ML $(CFLAGS) /O2 -o r1-vc7.exe $(SOURCES) $(LFLAGS) + +r2-vc7.exe : + cl /MLd $(CFLAGS) -o r2-vc7.exe $(SOURCES) $(LFLAGS) + +r3-vc7.exe : + cl /MT $(CFLAGS) /O2 -o r3-vc7.exe $(SOURCES) $(LFLAGS) + +r4-vc7.exe : + cl /MTd $(CFLAGS) -o r4-vc7.exe $(SOURCES) $(LFLAGS) + +r5-vc7.exe : + cl /MD $(CFLAGS) /O2 -o r5-vc7.exe $(SOURCES) $(LFLAGS) + +r6-vc7.exe : + cl /MDd $(CFLAGS) -o r6-vc7.exe $(SOURCES) $(LFLAGS) + +r7-vc7.exe : + cl /MD $(CFLAGS) /O2 /DBOOST_ALL_DYN_LINK -o r7-vc7.exe $(SOURCES) $(LFLAGS) + +r8-vc7.exe : + cl /MDd $(CFLAGS) /DBOOST_ALL_DYN_LINK -o r8-vc7.exe $(SOURCES) $(LFLAGS) + + + diff --git a/src/boost/libs/regex/test/regress/vc71.mak b/src/boost/libs/regex/test/regress/vc71.mak new file mode 100644 index 00000000..831b2523 --- /dev/null +++ b/src/boost/libs/regex/test/regress/vc71.mak @@ -0,0 +1,68 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regression tests +# +# Visual C++ 7.1 +# +# +# Add additional compiler options here: +# +CXXFLAGS= +# +# Add additional include directories here: +# +INCLUDES= +# +# add additional linker flags here: +# +XLFLAGS= +# +# sources to compile for each test: +# +SOURCES=*.cpp + +CFLAGS= $(INCLUDES) /Zm400 /GB /GF /Gy -GX -GR -I..\..\..\..\ $(CXXFLAGS) /DBOOST_LIB_DIAGNOSTIC=1 /Zc:wchar_t + +LFLAGS= -link /LIBPATH:..\..\..\..\stage\lib /LIBPATH:..\..\build\vc71 $(XLFLAGS) + +all :: r1-vc71.exe r2-vc71.exe r3-vc71.exe r4-vc71.exe r5-vc71.exe r6-vc71.exe r7-vc71.exe r8-vc71.exe + r1-vc71 + r2-vc71 + r3-vc71 + r4-vc71 + r5-vc71 + r6-vc71 + -copy ..\..\build\vc71\boost_regex*.dll + -copy ..\..\..\..\stage\lib\boost_regex*.dll + r7-vc71 + r8-vc71 + +r1-vc71.exe : + cl /ML $(CFLAGS) /O2 -o r1-vc71.exe $(SOURCES) $(LFLAGS) + +r2-vc71.exe : + cl /MLd $(CFLAGS) -o r2-vc71.exe $(SOURCES) $(LFLAGS) + +r3-vc71.exe : + cl /MT $(CFLAGS) /O2 -o r3-vc71.exe $(SOURCES) $(LFLAGS) + +r4-vc71.exe : + cl /MTd $(CFLAGS) -o r4-vc71.exe $(SOURCES) $(LFLAGS) + +r5-vc71.exe : + cl /MD $(CFLAGS) /O2 -o r5-vc71.exe $(SOURCES) $(LFLAGS) + +r6-vc71.exe : + cl /MDd $(CFLAGS) -o r6-vc71.exe $(SOURCES) $(LFLAGS) + +r7-vc71.exe : + cl /MD $(CFLAGS) /O2 /DBOOST_ALL_DYN_LINK -o r7-vc71.exe $(SOURCES) $(LFLAGS) + +r8-vc71.exe : + cl /MDd $(CFLAGS) /DBOOST_ALL_DYN_LINK -o r8-vc71.exe $(SOURCES) $(LFLAGS) + + + diff --git a/src/boost/libs/regex/test/regress/vc8.mak b/src/boost/libs/regex/test/regress/vc8.mak new file mode 100644 index 00000000..68c4a8fe --- /dev/null +++ b/src/boost/libs/regex/test/regress/vc8.mak @@ -0,0 +1,68 @@ +# copyright John Maddock 2003 +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt. + +# very basic makefile for regression tests +# +# Visual C++ 8.0 +# +# +# Add additional compiler options here: +# +CXXFLAGS= +# +# Add additional include directories here: +# +INCLUDES= +# +# add additional linker flags here: +# +XLFLAGS= +# +# sources to compile for each test: +# +SOURCES=*.cpp + +CFLAGS= $(INCLUDES) /Zm400 /GB /GF /Gy -GX -GR -I..\..\..\..\ $(CXXFLAGS) /DBOOST_LIB_DIAGNOSTIC=1 /Zc:wchar_t + +LFLAGS= -link /LIBPATH:..\..\..\..\stage\lib /LIBPATH:..\..\build\vc80 $(XLFLAGS) + +all :: r1-vc8.exe r2-vc8.exe r3-vc8.exe r4-vc8.exe r5-vc8.exe r6-vc8.exe r7-vc8.exe r8-vc8.exe + r1-vc8 + r2-vc8 + r3-vc8 + r4-vc8 + r5-vc8 + r6-vc8 + -copy ..\..\build\vc80\boost_regex*.dll + -copy ..\..\..\..\stage\lib\boost_regex*.dll + r7-vc8 + r8-vc8 + +r1-vc8.exe : + cl /ML $(CFLAGS) /O2 -o r1-vc8.exe $(SOURCES) $(LFLAGS) + +r2-vc8.exe : + cl /MLd $(CFLAGS) -o r2-vc8.exe $(SOURCES) $(LFLAGS) + +r3-vc8.exe : + cl /MT $(CFLAGS) /O2 -o r3-vc8.exe $(SOURCES) $(LFLAGS) + +r4-vc8.exe : + cl /MTd $(CFLAGS) -o r4-vc8.exe $(SOURCES) $(LFLAGS) + +r5-vc8.exe : + cl /MD $(CFLAGS) /O2 -o r5-vc8.exe $(SOURCES) $(LFLAGS) + +r6-vc8.exe : + cl /MDd $(CFLAGS) -o r6-vc8.exe $(SOURCES) $(LFLAGS) + +r7-vc8.exe : + cl /MD $(CFLAGS) /O2 /DBOOST_ALL_DYN_LINK -o r7-vc8.exe $(SOURCES) $(LFLAGS) + +r8-vc8.exe : + cl /MDd $(CFLAGS) /DBOOST_ALL_DYN_LINK -o r8-vc8.exe $(SOURCES) $(LFLAGS) + + + diff --git a/src/boost/libs/regex/test/static_mutex/static_mutex_test.cpp b/src/boost/libs/regex/test/static_mutex/static_mutex_test.cpp new file mode 100644 index 00000000..f029a4be --- /dev/null +++ b/src/boost/libs/regex/test/static_mutex/static_mutex_test.cpp @@ -0,0 +1,207 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE static_mutex_test.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: test program for boost::static_mutex. + */ + +#include <boost/regex/pending/static_mutex.hpp> +#include <boost/thread/thread.hpp> +#include <boost/timer.hpp> +#include <iostream> +#include <iomanip> + +// +// we cannot use the regular Boost.Test in here: it is not thread safe +// and calls to BOOST_CHECK will eventually crash on some compilers +// (Borland certainly) due to race conditions inside the Boost.Test lib. +// +#define BOOST_CHECK(pred) if(!(pred)) failed_test(__FILE__, __LINE__, BOOST_STRINGIZE(pred)); + +int total_failures = 0; +void failed_test(const char* file, int line, const char* pred) +{ + static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ; + boost::static_mutex::scoped_lock guard(mut); + ++total_failures; + std::cout << "Failed test in \"" << file << "\" at line " << line << ": " << pred << std::endl; +} + +void print_cycles(int c) +{ + static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ; + boost::static_mutex::scoped_lock guard(mut); + std::cout << "Thread exited after " << c << " cycles." << std::endl; +} + +bool sufficient_time() +{ + // return true if enough time has passed since the tests began: + static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ; + boost::static_mutex::scoped_lock guard(mut); + static boost::timer t; + // is 10 seconds enough? + return t.elapsed() >= 10.0; +} + +// define three trivial test proceedures: +bool t1() +{ + static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ; + static int has_lock = 0; + static int data = 10000; + + boost::static_mutex::scoped_lock guard(mut); + BOOST_CHECK(++has_lock == 1); + BOOST_CHECK(guard.locked()); + BOOST_CHECK(guard); + bool result = (--data > 0) ? true : false; + BOOST_CHECK(--has_lock == 0); + return result; +} + +bool t2() +{ + static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ; + static int has_lock = 0; + static int data = 10000; + + boost::static_mutex::scoped_lock guard(mut, false); + BOOST_CHECK(0 == guard.locked()); + BOOST_CHECK(!guard); + guard.lock(); + BOOST_CHECK(++has_lock == 1); + BOOST_CHECK(guard.locked()); + BOOST_CHECK(guard); + bool result = (--data > 0) ? true : false; + BOOST_CHECK(--has_lock == 0); + guard.unlock(); + BOOST_CHECK(0 == guard.locked()); + BOOST_CHECK(!guard); + return result; +} + +bool t3() +{ + static boost::static_mutex mut = BOOST_STATIC_MUTEX_INIT ; + static int has_lock = 0; + static int data = 10000; + + boost::static_mutex::scoped_lock guard(mut); + BOOST_CHECK(++has_lock == 1); + BOOST_CHECK(guard.locked()); + BOOST_CHECK(guard); + bool result = (--data > 0) ? true : false; + BOOST_CHECK(--has_lock == 0); + return result; +} + +// define their thread procs: +void thread1_proc() +{ + int cycles = 0; + while(!sufficient_time()) + { + t1(); + t2(); + ++cycles; + } + print_cycles(cycles); +} + +void thread2_proc() +{ + int cycles = 0; + while(!sufficient_time()) + { + t2(); + t3(); + ++cycles; + } + print_cycles(cycles); +} + +void thread3_proc() +{ + int cycles = 0; + while(!sufficient_time()) + { + t1(); + t3(); + ++cycles; + } + print_cycles(cycles); +} + +// make sure that at least one of our test proceedures +// is called during program startup: +struct startup1 +{ + startup1() + { + t1(); + } + ~startup1() + { + t1(); + } +}; + +startup1 up1; + +int main() +{ + (void)up1; + + std::list<boost::shared_ptr<boost::thread> > threads; + for(int i = 0; i < 2; ++i) + { + try{ + threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&thread1_proc))); + } + catch(const std::exception& e) + { + std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl; + } + } + for(int i = 0; i < 2; ++i) + { + try{ + threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&thread2_proc))); + } + catch(const std::exception& e) + { + std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl; + } + } + for(int i = 0; i < 2; ++i) + { + try{ + threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&thread3_proc))); + } + catch(const std::exception& e) + { + std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl; + } + } + + std::list<boost::shared_ptr<boost::thread> >::const_iterator a(threads.begin()), b(threads.end()); + while(a != b) + { + (*a)->join(); + ++a; + } + + return total_failures; +} diff --git a/src/boost/libs/regex/test/test_consolidated.cpp b/src/boost/libs/regex/test/test_consolidated.cpp new file mode 100644 index 00000000..188033f7 --- /dev/null +++ b/src/boost/libs/regex/test/test_consolidated.cpp @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2011 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + +#include <libs/regex/src/c_regex_traits.cpp> +#include <libs/regex/src/cpp_regex_traits.cpp> +#include <libs/regex/src/cregex.cpp> +#include <libs/regex/src/fileiter.cpp> +#include <libs/regex/src/icu.cpp> +#include <libs/regex/src/instances.cpp> +#include <libs/regex/src/posix_api.cpp> +#include <libs/regex/src/regex.cpp> +#include <libs/regex/src/regex_debug.cpp> +#include <libs/regex/src/regex_raw_buffer.cpp> +#include <libs/regex/src/regex_traits_defaults.cpp> +#include <libs/regex/src/static_mutex.cpp> +#include <libs/regex/src/usinstances.cpp> +#include <libs/regex/src/wc_regex_traits.cpp> +#include <libs/regex/src/w32_regex_traits.cpp> +#include <libs/regex/src/wide_posix_api.cpp> +#include <libs/regex/src/winstances.cpp> diff --git a/src/boost/libs/regex/test/test_macros.hpp b/src/boost/libs/regex/test/test_macros.hpp new file mode 100644 index 00000000..ef28fe0a --- /dev/null +++ b/src/boost/libs/regex/test/test_macros.hpp @@ -0,0 +1,227 @@ +/////////////////////////////////////////////////////////////// +// Copyright 2012 John Maddock. Distributed under the Boost +// Software License, Version 1.0. (See accompanying file +// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_ +// + +#ifndef BOOST_MULTIPRECISION_TEST_HPP +#define BOOST_MULTIPRECISION_TEST_HPP + +#include <limits> +#include <cmath> +#include <typeinfo> +#include <iostream> +#include <iomanip> +#include <stdlib.h> + +#include <boost/core/lightweight_test.hpp> +#include <boost/current_function.hpp> +#include <boost/static_assert.hpp> +#include <boost/utility/enable_if.hpp> + +enum +{ + warn_on_fail, + error_on_fail, + abort_on_fail +}; + +template <class T> +inline int digits_of(const T&) +{ + return std::numeric_limits<T>::is_specialized ? std::numeric_limits<T>::digits : 18; +} + + +inline std::ostream& report_where(const char* file, int line, const char* function) +{ + if(function) + BOOST_LIGHTWEIGHT_TEST_OSTREAM << "In function: "<< function << std::endl; + BOOST_LIGHTWEIGHT_TEST_OSTREAM << file << ":" << line; + return BOOST_LIGHTWEIGHT_TEST_OSTREAM; +} + +#define BOOST_MP_REPORT_WHERE report_where(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION) + +inline void report_severity(int severity) +{ + if(severity == error_on_fail) + ++boost::detail::test_errors(); + else if(severity == abort_on_fail) + { + ++boost::detail::test_errors(); + abort(); + } +} + +#define BOOST_MP_REPORT_SEVERITY(severity) report_severity(severity) + +template <class E> +void report_unexpected_exception(const E& e, int severity, const char* file, int line, const char* function) +{ + report_where(file, line, function) << " Unexpected exception of type " << typeid(e).name() << std::endl; + BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Errot message was: " << e.what() << std::endl; + BOOST_MP_REPORT_SEVERITY(severity); +} + +#define BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) \ + catch(const std::exception& __e) \ + { report_unexpected_exception(__e, severity, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); }\ + catch(...)\ + { BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Exception of unknown type was thrown" << std::endl; report_severity(severity); } + + +#define BOOST_CHECK_IMP(x, severity)\ + try{ if(x){}else{\ + BOOST_MP_REPORT_WHERE << " Failed predicate: " << BOOST_STRINGIZE(x) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +#define BOOST_CHECK(x) BOOST_CHECK_IMP(x, error_on_fail) +#define BOOST_WARN(x) BOOST_CHECK_IMP(x, warn_on_fail) +#define BOOST_REQUIRE(x) BOOST_CHECK_IMP(x, abort_on_fail) + +#define BOOST_EQUAL_IMP(x, y, severity)\ + try{ if(!((x) == (y))){\ + BOOST_MP_REPORT_WHERE << " Failed check for equality: \n" \ + << std::setprecision(digits_of(x)) << std::scientific\ + << "Value of LHS was: " << (x) << "\n"\ + << "Value of RHS was: " << (y) << "\n"\ + << std::setprecision(3) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +#define BOOST_NE_IMP(x, y, severity)\ + try{ if(!(x != y)){\ + BOOST_MP_REPORT_WHERE << " Failed check for non-equality: \n" \ + << std::setprecision(digits_of(x)) << std::scientific\ + << "Value of LHS was: " << x << "\n"\ + << "Value of RHS was: " << y << "\n"\ + << std::setprecision(3) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +#define BOOST_LT_IMP(x, y, severity)\ + try{ if(!(x < y)){\ + BOOST_MP_REPORT_WHERE << " Failed check for less than: \n" \ + << std::setprecision(digits_of(x)) << std::scientific\ + << "Value of LHS was: " << x << "\n"\ + << "Value of RHS was: " << y << "\n"\ + << std::setprecision(3) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +#define BOOST_GT_IMP(x, y, severity)\ + try{ if(!(x > y)){\ + BOOST_MP_REPORT_WHERE << " Failed check for greater than: \n" \ + << std::setprecision(digits_of(x)) << std::scientific\ + << "Value of LHS was: " << x << "\n"\ + << "Value of RHS was: " << y << "\n"\ + << std::setprecision(3) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +#define BOOST_LE_IMP(x, y, severity)\ + try{ if(!(x <= y)){\ + BOOST_MP_REPORT_WHERE << " Failed check for less-than-equal-to: \n" \ + << std::setprecision(digits_of(x)) << std::scientific\ + << "Value of LHS was: " << x << "\n"\ + << "Value of RHS was: " << y << "\n"\ + << std::setprecision(3) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +#define BOOST_GE_IMP(x, y, severity)\ + try{ if(!(x >= y)){\ + BOOST_MP_REPORT_WHERE << " Failed check for greater-than-equal-to \n" \ + << std::setprecision(digits_of(x)) << std::scientific\ + << "Value of LHS was: " << x << "\n"\ + << "Value of RHS was: " << y << "\n"\ + << std::setprecision(3) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +#define BOOST_MT_CHECK_THROW_IMP(x, E, severity)\ + try{ \ + x;\ + BOOST_MP_REPORT_WHERE << " Expected exception not thrown in expression " << BOOST_STRINGIZE(x) << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + catch(const E&){}\ + BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + +template <class I, class J> +bool check_equal_collections(I a, I b, J x, J y) +{ + int i = 0; + while(a != b) + { + if(x == y) + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM << " Unexpected end of second sequence" << std::endl; + return false; + } + if(*a != *x) + { + BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Error occured in position " << i << " of the collection." << std::endl; + BOOST_LIGHTWEIGHT_TEST_OSTREAM << "First value was " << std::setprecision(digits_of(x)) << std::scientific << *a << std::endl; + BOOST_LIGHTWEIGHT_TEST_OSTREAM << "Second value was " << std::setprecision(digits_of(x)) << std::scientific << *x << std::endl; + return false; + } + ++a; + ++x; + } + return true; +} + +#define BOOST_MT_CHECK_EQ_COLLECTIONS(a, b, x, y, severity)\ + try{ \ + if(!check_equal_collections(a, b, x, y))\ + {\ + BOOST_MP_REPORT_WHERE << " Collections were not equal" << std::endl;\ + BOOST_MP_REPORT_SEVERITY(severity);\ + }\ + }\ + BOOST_MP_UNEXPECTED_EXCEPTION_CHECK(severity) + + +#define BOOST_CHECK_EQUAL(x, y) BOOST_EQUAL_IMP(x, y, error_on_fail) +#define BOOST_WARN_EQUAL(x, y) BOOST_EQUAL_IMP(x, y, warn_on_fail) +#define BOOST_REQUIRE_EQUAL(x, y) BOOST_EQUAL_IMP(x, y, abort_on_fail) + +#define BOOST_CHECK_NE(x, y) BOOST_NE_IMP(x, y, error_on_fail) +#define BOOST_WARN_NE(x, y) BOOST_NE_IMP(x, y, warn_on_fail) +#define BOOST_REQUIRE_NE(x, y) BOOST_NE_IMP(x, y, abort_on_fail) + +#define BOOST_CHECK_LT(x, y) BOOST_LT_IMP(x, y, error_on_fail) +#define BOOST_WARN_LT(x, y) BOOST_LT_IMP(x, y, warn_on_fail) +#define BOOST_REQUIRE_LT(x, y) BOOST_LT_IMP(x, y, abort_on_fail) + +#define BOOST_CHECK_GT(x, y) BOOST_GT_IMP(x, y, error_on_fail) +#define BOOST_WARN_GT(x, y) BOOST_GT_IMP(x, y, warn_on_fail) +#define BOOST_REQUIRE_GT(x, y) BOOST_GT_IMP(x, y, abort_on_fail) + +#define BOOST_CHECK_LE(x, y) BOOST_LE_IMP(x, y, error_on_fail) +#define BOOST_WARN_LE(x, y) BOOST_LE_IMP(x, y, warn_on_fail) +#define BOOST_REQUIRE_LE(x, y) BOOST_LE_IMP(x, y, abort_on_fail) + +#define BOOST_CHECK_GE(x, y) BOOST_GE_IMP(x, y, error_on_fail) +#define BOOST_WARN_GE(x, y) BOOST_GE_IMP(x, y, warn_on_fail) +#define BOOST_REQUIRE_GE(x, y) BOOST_GE_IMP(x, y, abort_on_fail) + +#define BOOST_CHECK_THROW(x, E) BOOST_MT_CHECK_THROW_IMP(x, E, error_on_fail) +#define BOOST_WARN_THROW(x, E) BOOST_MT_CHECK_THROW_IMP(x, E, warn_on_fail) +#define BOOST_REQUIRE_THROW(x, E) BOOST_MT_CHECK_THROW_IMP(x, E, abort_on_fail) + +#define BOOST_CHECK_EQUAL_COLLECTIONS(a, b, x, y) BOOST_MT_CHECK_EQ_COLLECTIONS(a, b, x, y, error_on_fail) +#define BOOST_WARN_EQUAL_COLLECTIONS(a, b, x, y) BOOST_MT_CHECK_EQ_COLLECTIONS(a, b, x, y, warn_on_fail) +#define BOOST_REQUIRE_EQUAL_COLLECTIONS(a, b, x, y) BOOST_MT_CHECK_EQ_COLLECTIONS(a, b, x, y, abort_on_fail) + +#endif diff --git a/src/boost/libs/regex/test/test_warnings.cpp b/src/boost/libs/regex/test/test_warnings.cpp new file mode 100644 index 00000000..f85d437d --- /dev/null +++ b/src/boost/libs/regex/test/test_warnings.cpp @@ -0,0 +1,29 @@ +/* +* +* Copyright (c) 2018 +* John Maddock +* +* Use, modification and distribution are subject to the +* Boost Software License, Version 1.0. (See accompanying file +* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +* +*/ + + +#ifdef _MSC_VER +#pragma warning(disable:4820 4668) +#endif + +#ifdef __APPLE_CC__ +#pragma clang diagnostic ignored "-Wc++11-long-long" +#endif + +#include <boost/regex.hpp> + +void test_proc() +{ + std::string text, re; + boost::regex exp(re); + regex_match(text, exp); +} + diff --git a/src/boost/libs/regex/test/unicode/unicode_iterator_test.cpp b/src/boost/libs/regex/test/unicode/unicode_iterator_test.cpp new file mode 100644 index 00000000..2e6bcec1 --- /dev/null +++ b/src/boost/libs/regex/test/unicode/unicode_iterator_test.cpp @@ -0,0 +1,322 @@ +/* + * + * Copyright (c) 2004 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE unicode_iterator_test.cpp + * VERSION see <boost/version.hpp> + * DESCRIPTION: Simple test suite for Unicode interconversions. + */ + +#include <boost/regex/pending/unicode_iterator.hpp> +#include <boost/detail/lightweight_main.hpp> +#include "../test_macros.hpp" +#include <vector> +#include <iterator> +#include <algorithm> +#include <iostream> +#include <iomanip> +#include <cstring> + +#if !defined(TEST_UTF8) && !defined(TEST_UTF16) +# define TEST_UTF8 +# define TEST_UTF16 +#endif + +template <class I> +typename I::value_type iterate_over(I a, I b) +{ + typedef typename I::value_type value_type; + value_type v = 0; + while(a != b) + { + v ^= *a; + ++a; + } + return v; +} + +void spot_checks() +{ + // test specific values ripped straight out of the Unicode standard + // to verify that our encoding is the same as theirs, as well as + // self-consistent: + ::boost::uint32_t spot16[] = { 0x10302u, }; + typedef boost::u32_to_u16_iterator<const ::boost::uint32_t*> u32to16type; + + u32to16type it(spot16); + BOOST_CHECK_EQUAL(*it++, 0xD800u); + BOOST_CHECK_EQUAL(*it++, 0xDF02u); + BOOST_CHECK_EQUAL(*--it, 0xDF02u); + BOOST_CHECK_EQUAL(*--it, 0xD800u); + + ::boost::uint32_t spot8[] = { 0x004Du, 0x0430u, 0x4E8Cu, 0x10302u, }; + typedef boost::u32_to_u8_iterator<const ::boost::uint32_t*> u32to8type; + + u32to8type it8(spot8); + BOOST_CHECK_EQUAL(*it8++, 0x4Du); + BOOST_CHECK_EQUAL(*it8++, 0xD0u); + BOOST_CHECK_EQUAL(*it8++, 0xB0u); + BOOST_CHECK_EQUAL(*it8++, 0xE4u); + BOOST_CHECK_EQUAL(*it8++, 0xBAu); + BOOST_CHECK_EQUAL(*it8++, 0x8Cu); + BOOST_CHECK_EQUAL(*it8++, 0xF0u); + BOOST_CHECK_EQUAL(*it8++, 0x90u); + BOOST_CHECK_EQUAL(*it8++, 0x8Cu); + BOOST_CHECK_EQUAL(*it8++, 0x82u); + + BOOST_CHECK_EQUAL(*--it8, 0x82u); + BOOST_CHECK_EQUAL(*--it8, 0x8Cu); + BOOST_CHECK_EQUAL(*--it8, 0x90u); + BOOST_CHECK_EQUAL(*--it8, 0xF0u); + BOOST_CHECK_EQUAL(*--it8, 0x8Cu); + BOOST_CHECK_EQUAL(*--it8, 0xBAu); + BOOST_CHECK_EQUAL(*--it8, 0xE4u); + BOOST_CHECK_EQUAL(*--it8, 0xB0u); + BOOST_CHECK_EQUAL(*--it8, 0xD0u); + BOOST_CHECK_EQUAL(*--it8, 0x4Du); + // + // Test some bad sequences and verify that our iterators will catch them: + // + boost::uint8_t bad_seq[10] = { 0x4Du, 0xD0u, 0xB0u, 0xE4u, 0xBAu, 0x8Cu, 0xF0u, 0x90u, 0x8Cu, 0x82u }; + BOOST_CHECK_EQUAL( + iterate_over( + boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq, bad_seq, bad_seq + 10), + boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq+10, bad_seq, bad_seq + 10)), + 0x000149f3u); + BOOST_CHECK_THROW(boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq, bad_seq, bad_seq + 9), std::out_of_range); + BOOST_CHECK_THROW(boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq, bad_seq, bad_seq + 8), std::out_of_range); + BOOST_CHECK_THROW(boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq, bad_seq, bad_seq + 7), std::out_of_range); + BOOST_CHECK_THROW(boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq + 2, bad_seq, bad_seq + 10), std::out_of_range); + BOOST_CHECK_THROW(boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq + 2, bad_seq + 2, bad_seq + 10), std::out_of_range); + + boost::uint16_t bad_seq2[6] = { 0xD800, 0xDF02, 0xD800, 0xDF02, 0xD800, 0xDF02 }; + BOOST_CHECK_EQUAL( + iterate_over( + boost::u16_to_u32_iterator<const boost::uint16_t*>(bad_seq2, bad_seq2, bad_seq2 + 6), + boost::u16_to_u32_iterator<const boost::uint16_t*>(bad_seq2+6, bad_seq2, bad_seq2 + 6)), + 66306u); + BOOST_CHECK_THROW(boost::u16_to_u32_iterator<const boost::uint16_t*>(bad_seq2, bad_seq2, bad_seq2 + 5), std::out_of_range); + BOOST_CHECK_THROW(boost::u16_to_u32_iterator<const boost::uint16_t*>(bad_seq2 + 1, bad_seq2 + 1, bad_seq2 + 6), std::out_of_range); + BOOST_CHECK_THROW(boost::u16_to_u32_iterator<const boost::uint16_t*>(bad_seq2 + 1, bad_seq2, bad_seq2 + 6), std::out_of_range); + + boost::uint8_t bad_seq3[5] = { '.', '*', 0xe4, '.', '*' }; + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq3, bad_seq3, bad_seq3 + 5), boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq3 + 5, bad_seq3, bad_seq3 + 5)), std::out_of_range); + boost::uint8_t bad_seq4[5] = { '.', '*', 0xf6, '.', '*' }; + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq4, bad_seq4, bad_seq4 + 5), boost::u8_to_u32_iterator<const boost::uint8_t*>(bad_seq4 + 5, bad_seq4, bad_seq4 + 5)), std::out_of_range); + + // Invalid sequences containing surrogate pairs: + const char* invalid_pseq = "\xed\xa0\x80"; // single lowest lead surrogate U+D800 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xed\xb0\x80"; // single lowest trail surrogate U+DC00 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xed\xb0\x80"; // single lowest trail surrogate U+DC00 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xed\xbf\xbf"; // single highest trail surrogate U+DFFF + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + + // overlong encodings (created by left-padding with zero bits) + invalid_pseq = "\xc0\x80"; // illegal 2-byte encoding of 1-byte character U+0000 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xe0\x80\x80"; // illegal 3-byte encoding of 1-byte character U+0000 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xf0\x80\x80\x80"; // illegal 4-byte encoding of 1-byte character U+0000 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + + invalid_pseq = "\xc1\xbf"; // illegal 2-byte encoding of 1-byte character U+007F + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xe0\x81\xbf"; // illegal 3-byte encoding of 1-byte character U+007F + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xf0\x80\x81\xbf"; // illegal 4-byte encoding of 1-byte character U+007F + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + + invalid_pseq = "\xe0\x82\x80"; // illegal 3-byte encoding of 2-byte character U+0080 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xf0\x80\x82\x80"; // illegal 4-byte encoding of 2-byte character U+0080 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + + invalid_pseq = "\xe0\x9f\xbf"; // illegal 3-byte encoding of 2-byte character U+07FF + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xf0\x80\x9f\xbf"; // illegal 4-byte encoding of 2-byte character U+07FF + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + + invalid_pseq = "\xf0\x80\xa0\x80"; // illegal 4-byte encoding of 3-byte character U+0800 + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); + invalid_pseq = "\xf0\x8f\xbf\xbf"; // illegal 4-byte encoding of 3-byte character U+FFFF + BOOST_CHECK_THROW(iterate_over(boost::u8_to_u32_iterator<const char*>(invalid_pseq, invalid_pseq, invalid_pseq + std::strlen(invalid_pseq)), boost::u8_to_u32_iterator<const char*>(invalid_pseq + std::strlen(invalid_pseq), invalid_pseq, invalid_pseq + std::strlen(invalid_pseq))), std::out_of_range); +} + +void test(const std::vector< ::boost::uint32_t>& v) +{ + typedef std::vector< ::boost::uint32_t> vector32_type; +#ifdef TEST_UTF16 + typedef std::vector< ::boost::uint16_t> vector16_type; +#endif + typedef std::vector< ::boost::uint8_t> vector8_type; +#ifdef TEST_UTF16 + typedef boost::u32_to_u16_iterator<vector32_type::const_iterator, ::boost::uint16_t> u32to16type; + typedef boost::u16_to_u32_iterator<vector16_type::const_iterator, ::boost::uint32_t> u16to32type; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR) && !defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator<u32to16type> ru32to16type; + typedef std::reverse_iterator<u16to32type> ru16to32type; +#endif +#endif // TEST_UTF16 +#ifdef TEST_UTF8 + typedef boost::u32_to_u8_iterator<vector32_type::const_iterator, ::boost::uint8_t> u32to8type; + typedef boost::u8_to_u32_iterator<vector8_type::const_iterator, ::boost::uint32_t> u8to32type; +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR) && !defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + typedef std::reverse_iterator<u32to8type> ru32to8type; + typedef std::reverse_iterator<u8to32type> ru8to32type; +#endif +#endif // TEST_UTF8 + vector8_type v8; +#ifdef TEST_UTF16 + vector16_type v16; +#endif + vector32_type v32; + vector32_type::const_iterator i, j, k; + +#ifdef TEST_UTF16 + // + // begin by testing forward iteration, of 32-16 bit interconversions: + // +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + v16.assign(u32to16type(v.begin()), u32to16type(v.end())); +#else + v16.clear(); + std::copy(u32to16type(v.begin()), u32to16type(v.end()), std::back_inserter(v16)); +#endif +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(u32to16type(v.begin()), u32to16type(v.end())), v16.size()); +#endif +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + v32.assign(u16to32type(v16.begin(), v16.begin(), v16.end()), u16to32type(v16.end(), v16.begin(), v16.end())); +#else + v32.clear(); + std::copy(u16to32type(v16.begin(), v16.begin(), v16.end()), u16to32type(v16.end(), v16.begin(), v16.end()), std::back_inserter(v32)); +#endif +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(u16to32type(v16.begin(), v16.begin(), v16.end()), u16to32type(v16.end(), v16.begin(), v16.end())), v32.size()); +#endif + BOOST_CHECK_EQUAL(v.size(), v32.size()); + i = v.begin(); + j = i; + std::advance(j, (std::min)(v.size(), v32.size())); + k = v32.begin(); + BOOST_CHECK_EQUAL_COLLECTIONS(v.begin(), v.end(), v32.begin(), v32.end()); + // + // test backward iteration, of 32-16 bit interconversions: + // +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR) && !defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + v16.assign(ru32to16type(u32to16type(v.end())), ru32to16type(u32to16type(v.begin()))); +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(ru32to16type(u32to16type(v.end())), ru32to16type(u32to16type(v.begin()))), v16.size()); +#endif + std::reverse(v16.begin(), v16.end()); + v32.assign(ru16to32type(u16to32type(v16.end(), v16.begin(), v16.end())), ru16to32type(u16to32type(v16.begin(), v16.begin(), v16.end()))); +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(ru16to32type(u16to32type(v16.end(), v16.begin(), v16.end())), ru16to32type(u16to32type(v16.begin(), v16.begin(), v16.end()))), v32.size()); +#endif + BOOST_CHECK_EQUAL(v.size(), v32.size()); + std::reverse(v32.begin(), v32.end()); + i = v.begin(); + j = i; + std::advance(j, (std::min)(v.size(), v32.size())); + k = v32.begin(); + BOOST_CHECK_EQUAL_COLLECTIONS(v.begin(), v.end(), v32.begin(), v32.end()); +#endif +#endif // TEST_UTF16 + +#ifdef TEST_UTF8 + // + // Test forward iteration, of 32-8 bit interconversions: + // +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + v8.assign(u32to8type(v.begin()), u32to8type(v.end())); +#else + v8.clear(); + std::copy(u32to8type(v.begin()), u32to8type(v.end()), std::back_inserter(v8)); +#endif +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(u32to8type(v.begin()), u32to8type(v.end())), v8.size()); +#endif +#if !defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) + v32.assign(u8to32type(v8.begin(), v8.begin(), v8.end()), u8to32type(v8.end(), v8.begin(), v8.end())); +#else + v32.clear(); + std::copy(u8to32type(v8.begin(), v8.begin(), v8.end()), u8to32type(v8.end(), v8.begin(), v8.end()), std::back_inserter(v32)); +#endif +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(u8to32type(v8.begin(), v8.begin(), v8.end()), u8to32type(v8.end(), v8.begin(), v8.end())), v32.size()); +#endif + BOOST_CHECK_EQUAL(v.size(), v32.size()); + i = v.begin(); + j = i; + std::advance(j, (std::min)(v.size(), v32.size())); + k = v32.begin(); + BOOST_CHECK_EQUAL_COLLECTIONS(v.begin(), v.end(), v32.begin(), v32.end()); + // + // test backward iteration, of 32-8 bit interconversions: + // +#if !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_NO_STD_ITERATOR) && !defined(_RWSTD_NO_CLASS_PARTIAL_SPEC) + v8.assign(ru32to8type(u32to8type(v.end())), ru32to8type(u32to8type(v.begin()))); +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(ru32to8type(u32to8type(v.end())), ru32to8type(u32to8type(v.begin()))), v8.size()); +#endif + std::reverse(v8.begin(), v8.end()); + v32.assign(ru8to32type(u8to32type(v8.end(), v8.begin(), v8.end())), ru8to32type(u8to32type(v8.begin(), v8.begin(), v8.end()))); +#ifndef BOOST_NO_STD_DISTANCE + BOOST_CHECK_EQUAL((std::size_t)std::distance(ru8to32type(u8to32type(v8.end(), v8.begin(), v8.end())), ru8to32type(u8to32type(v8.begin(), v8.begin(), v8.end()))), v32.size()); +#endif + BOOST_CHECK_EQUAL(v.size(), v32.size()); + std::reverse(v32.begin(), v32.end()); + i = v.begin(); + j = i; + std::advance(j, (std::min)(v.size(), v32.size())); + k = v32.begin(); + BOOST_CHECK_EQUAL_COLLECTIONS(v.begin(), v.end(), v32.begin(), v32.end()); +#endif +#endif // TEST_UTF8 + // + // Test checked construction of UTF-8/16 iterators at each location in the sequences: + // +#ifdef TEST_UTF8 + for(u8to32type v8p(v8.begin(), v8.begin(), v8.end()), v8e(v8.end(), v8.begin(), v8.end()); v8p != v8e; ++v8p) + { + u8to32type pos(v8p.base(), v8p.base(), v8.end()); + BOOST_CHECK(pos == v8p); + BOOST_CHECK(*pos == *v8p); + } +#endif +#ifdef TEST_UTF16 + for(u16to32type v16p(v16.begin(), v16.begin(), v16.end()), v16e(v16.end(), v16.begin(), v16.end()); v16p != v16e; ++v16p) + { + u16to32type pos(v16p.base(), v16p.base(), v16.end()); + BOOST_CHECK(pos == v16p); + BOOST_CHECK(*pos == *v16p); + } +#endif +} + +int cpp_main( int, char* [] ) +{ + // test specific value points from the standard: + spot_checks(); + // now test a bunch of values for self-consistency and round-tripping: + std::vector< ::boost::uint32_t> v; + for(unsigned i = 0; i < 0xD800; ++i) + v.push_back(i); + for(unsigned i = 0xDFFF + 1; i < 0x10FFFF; ++i) + v.push_back(i); + test(v); + return 0; +} + |