early-access version 3088

This commit is contained in:
pineappleEA
2022-11-05 15:35:56 +01:00
parent 4e4fc25ce3
commit b601909c6d
35519 changed files with 5996896 additions and 860 deletions

View File

@@ -0,0 +1,242 @@
# 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
wmain.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/posix_api.cpp
../src/regex.cpp
../src/regex_debug.cpp
../src/static_mutex.cpp
../src/wide_posix_api.cpp
../build//icu_options
:
<define>BOOST_REGEX_RECURSIVE=1
<define>BOOST_REGEX_CXX03=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 ]
[ run regress/$(R_SOURCE) ../build//boost_regex
../../thread/build//boost_thread ../build//icu_options
: # command line
: # input files
: # requirements
<define>TEST_THREADS
<define>BOOST_REGEX_MAX_CACHE_BLOCKS=0
: regex_regress_threaded_no_cache ]
[ 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 : : :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
]
[ run pathology/recursion_test.cpp : : :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
]
[ run named_subexpressions/named_subexpressions_test.cpp : : :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
]
[ run unicode/unicode_iterator_test.cpp : : :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
release <define>TEST_UTF8 : unicode_iterator_test_utf8 ]
[ run unicode/unicode_iterator_test.cpp : : :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
release <define>TEST_UTF16 : unicode_iterator_test_utf16 ]
[ run unicode/unicode_casefold_test.cpp
../build//boost_regex ../build//icu_options
]
[ run static_mutex/static_mutex_test.cpp
../../thread/build//boost_thread ../build//boost_regex
]
[ run object_cache/object_cache_test.cpp : : :
[ check-target-builds ../build//is_legacy_03 : : <source>../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 :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
]
[ link concepts/concept_check.cpp :
<define>BOOST_REGEX_STANDALONE [ check-target-builds ../build//is_legacy_03 : : <build>no ] : standalone_concept_check
]
[ link concepts/icu_concept_check.cpp :
<define>BOOST_REGEX_STANDALONE [ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
]
[ link concepts/icu_concept_check.cpp :
[ check-target-builds ../build//is_legacy_03 : : <build>no ] : standalone_icu_concept_check
]
[ link concepts/range_concept_check.cpp :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
]
[ run concepts/test_bug_11988.cpp : : :
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
]
[ run
# sources
captures/captures_test.cpp
../build//icu_options
: # additional args
: # test-files
: # requirements
<threading>multi
<define>BOOST_REGEX_MATCH_EXTRA=1
<define>BOOST_REGEX_NO_LIB=1
[ check-target-builds ../build//is_legacy_03 : : <source>../build//boost_regex ]
: # test name
captures_test
]
[ run regress/$(R_SOURCE) .//boost_regex_recursive
../build//icu_options
: # command line
: # input files
: # requirements
<define>BOOST_REGEX_RECURSIVE=1
<define>BOOST_REGEX_CXX03=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 ;
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
<define>BOOST_REGEX_STANDALONE
[ check-target-builds ../build//is_legacy_03 : : <build>no ]
: test_warnings_standalone ;
compile test_windows_defs_1.cpp ;
compile test_windows_defs_2.cpp ;
compile test_windows_defs_3.cpp ;
compile test_windows_defs_4.cpp ;
run issue153.cpp : : : <toolset>msvc:<linkflags>-STACK:2097152 ;

View File

@@ -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;
}

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,26 @@
# 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 =
posix_api.cpp
regex.cpp
regex_debug.cpp
static_mutex.cpp
wide_posix_api.cpp ;
lib boost_regex_extra : $(EX_SOURCES) ../../build//icu_options
:
<define>BOOST_REGEX_MATCH_EXTRA=1
<link>shared:<define>BOOST_REGEX_DYN_LINK=1
:
;

View File

@@ -0,0 +1,181 @@
/*
*
* 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]);
}
}
}
#if !defined(BOOST_NO_WREGEX)
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]));
}
}
}
#endif
#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;
}

View File

@@ -0,0 +1,18 @@
# Copyright 2018, 2019 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
cmake_minimum_required(VERSION 3.5...3.16)
project(cmake_install_test LANGUAGES CXX)
find_package(boost_regex REQUIRED)
find_package(boost_core REQUIRED)
add_executable(quick ../quick.cpp)
target_link_libraries(quick Boost::regex Boost::core)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)

View File

@@ -0,0 +1,23 @@
# Copyright 2018, 2019 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
cmake_minimum_required(VERSION 3.5...3.16)
project(cmake_subdir_test LANGUAGES CXX)
add_subdirectory(../.. boostorg/reegx)
add_subdirectory(../../../config boostorg/config)
add_subdirectory(../../../core boostorg/core)
add_subdirectory(../../../assert boostorg/assert)
add_subdirectory(../../../static_assert boostorg/static_assert)
add_subdirectory(../../../throw_exception boostorg/throw_exception)
add_subdirectory(../../../predef boostorg/predef)
add_executable(quick ../quick.cpp)
target_link_libraries(quick Boost::regex Boost::core)
enable_testing()
add_test(quick quick)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)

View File

@@ -0,0 +1,22 @@
# Copyright 2018, 2019 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
cmake_minimum_required(VERSION 3.5...3.16)
project(cmake_subdir_test LANGUAGES CXX)
add_subdirectory(../.. boostorg/regex)
add_subdirectory(../../../config boostorg/config)
add_subdirectory(../../../core boostorg/core)
add_subdirectory(../../../assert boostorg/assert)
add_subdirectory(../../../throw_exception boostorg/throw_exception)
add_subdirectory(../../../predef boostorg/predef)
add_executable(quick_icu ../quick_icu.cpp)
target_link_libraries(quick_icu Boost::regex_icu)
enable_testing()
add_test(quick_icu quick_icu)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure -C $<CONFIG>)

View File

@@ -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(BOOST_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;
}

View File

@@ -0,0 +1,94 @@
/*
*
* 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/regex.hpp>
#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 BOOST_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/concepts.hpp>
int main()
{
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
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
#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
>
>();
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
>
>();
return 0;
}

View File

@@ -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 BOOST_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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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
;

View File

@@ -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)"

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (c) 2021
* 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)
*
*/
//#define BOOST_REGEX_MAX_BLOCKS 10
// See https://github.com/boostorg/regex/issues/153
#include <iostream>
#include <boost/regex.hpp>
int main(int argc, char** argv)
{
try
{
boost::regex e("\x28\x28\x1f\x28\x28\x28\x3f\x31\x29\x8\x29\xf3\x29\x21\x3d\x29\x3f\x3f\xe4\x2e\x2b\x1f\x3f\x7c\x28\x3f\x21\x28\x28\x61\x3f\x3f\x28\x2a\x53\x4b\x49\x50\x29\x4\x3f\x2e\x2a\x3f\x28\x3f\x31\x29\x30\x77\x29\x29\x29\x49\x29\x61\x63\xbe\x45\x30\xa1\x5c\xfe\x5\xd2\x26\xc0\xf5\x17\x6c\xd4\xc3\x72\xe9\xb6\x74");
if (boost::regex_match("\xb9\x32\x7c\xbc\x2d\xa0\xb\x85\xf3\xcf\x93\xa7\xd0\x44\x7b\x21\x12\x93\x6a\x7b\x72\x6d\x1e\x69\x56\x31\x37\x30\x31\x34\x31\x31\x38\x33\x34\x36\x30\x34\x36\x39\x32\x33\x31\x37\x33\x31\x36\x38\x37\x33\x30\x33\x37\x31\x35\x38\x38\x34\x31\x30\x35\x37\x32\x37\xba\x3e\x4\xc7\x27\xe9\xae\xf2\x01\x84\x47\x1f\xdc\xc9\x4c\xe5\xbc\xcf\x17\x31\x37\x30\x31\x34\x31\x31\x38\x33\x34\x36\x30\x34\x36\x39\x32\x33\x31\x37\x33\x31\x36\x38\x37\x33\x30\x33\x37\x31\x35\x38\x38\x34\x31\x2c\xd6\xf5\x42\xe4\x13\x15\xde\x7e\xa1\x84\x5a\x32\xf5\x67\xd5\x13\x9a\xd1\xa6\x99\x18\x23\xf7\x5c\xf6\x40\x80\x9c\x79\xbe\x4a\xc2\x54\x94\x93\xa3\x50\x27\xaf\xd4\xc4\x3b\xd3\x49\x95\xe7\xa9\xa0\xa5\x14\x81\xd2\x9a\x77\x92\xa8\x81\xb0\xf4\x5b\xa8\x9c\x3e\x17\x3b\xbd\x86\x26\x9a\x57\x56\x12\xce\x8c\x4a\xca\x68\x86\x3d\xf5\xba\x75\xab\xb1\x76\x2d\xd\xf1\xc\x24\x5e\xc5\x6d\xc8\xdf\xa6\x18\x86\x5e\x56", e, boost::regex_constants::match_default | boost::regex_constants::match_partial))
{
std::cout << "OK" << std::endl;
}
}
catch (const boost::regex_error& e)
{
assert(e.code() == boost::regex_constants::error_complexity);
std::cout << e.what() << std::endl;
}
return 0;
}

View File

@@ -0,0 +1,114 @@
/*
*
* 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));
#if !defined(BOOST_NO_WREGEX)
test_named_subexpressions(wchar_t(0));
#endif
return 0;
}

View File

@@ -0,0 +1,38 @@
# 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/posix_api.cpp
../../src/regex.cpp
../../src/regex_debug.cpp
../../src/static_mutex.cpp
../../src/wide_posix_api.cpp
../../build//icu_options
:
<link>static
<define>BOOST_NO_EXCEPTIONS=1
<exception-handling>off
:
;

View File

@@ -0,0 +1,84 @@
/*
*
* 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/config.hpp>
#ifdef BOOST_REGEX_CXX03
#include <boost/regex/v4/object_cache.hpp>
#define SP_NS boost
#else
#include <boost/regex/v5/object_cache.hpp>
#define SP_NS std
#endif
#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)
{
SP_NS::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)
{
SP_NS::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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 <cassert>
#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" };
assert(!validate_card_format(s[0]));
assert(machine_readable_card_number(s[0]) == s[0]);
assert(human_readable_card_number(s[0]) == s[2]);
assert(validate_card_format(s[1]));
assert(machine_readable_card_number(s[1]) == s[0]);
assert(human_readable_card_number(s[1]) == s[2]);
assert(validate_card_format(s[2]));
assert(machine_readable_card_number(s[2]) == s[0]);
assert(human_readable_card_number(s[2]) == s[2]);
assert(!validate_card_format(s[3]));
return 0;
}

View File

@@ -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/icu.hpp>
#include <cassert>
#include <string>
bool validate_card_format(const std::string& s)
{
static const boost::u32regex e = boost::make_u32regex("(\\d{4}[- ]){3}\\d{4}");
return boost::u32regex_match(s, e);
}
const boost::u32regex card_rx = boost::make_u32regex("\\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::u32regex_replace(s, card_rx, machine_format, boost::match_default | boost::format_sed);
}
std::string human_readable_card_number(const std::string& s)
{
return boost::u32regex_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" };
assert( !validate_card_format( s[0] ) );
assert( machine_readable_card_number( s[0] ) == s[0] );
assert( human_readable_card_number( s[0] ) == s[2] );
assert( validate_card_format( s[1] ) );
assert( machine_readable_card_number( s[1] ) == s[0] );
assert( human_readable_card_number( s[1] ) == s[2] );
assert( validate_card_format( s[2] ) );
assert( machine_readable_card_number( s[2] ) == s[0] );
assert( human_readable_card_number( s[2] ) == s[2] );
assert( !validate_card_format( s[3] ) );
return 0;
}

View File

@@ -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(BOOST_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));
}

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -0,0 +1,224 @@
/*
*
* 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, 800> > tp;
if(tp.get() == 0)
tp.reset(new boost::array<int, 800>);
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[800];
#endif
std::fill_n(data, 800, -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);
}
#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

View File

@@ -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

View File

@@ -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)
(void)e1.imbue(test_locale::cpp_locale());
if(test_locale::cpp_locale_state() != test_locale::no_test)
test(e1, tag);
#endif
#if !BOOST_WORKAROUND(BOOST_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

View File

@@ -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));
}

View File

@@ -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(BOOST_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
}

View File

@@ -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);
}

View File

@@ -0,0 +1,130 @@
/*
*
* 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);
#ifdef BOOST_REGEX_CXX03
TEST_INVALID_REGEX("a(b\\1)c", perl);
#endif
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));
#ifndef BOOST_REGEX_CXX03
TEST_REGEX_SEARCH("(\\2two|(one))+", perl, "oneonetwo", match_default, make_array(0, 9, 3, 9, 0, 3, -2, -2));
TEST_INVALID_REGEX("(\\3two|(one))+", perl);
#endif
// 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);
#ifdef BOOST_REGEX_CXX03
TEST_INVALID_REGEX("a(b\\g1)c", perl);
#endif
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);
#ifdef BOOST_REGEX_CXX03
TEST_INVALID_REGEX("a(b\\g{1})c", perl);
#endif
TEST_INVALID_REGEX("a(b\\g{0})c", perl);
#ifndef BOOST_REGEX_CXX03
TEST_REGEX_SEARCH("(\\g{2}two|(one))+", perl, "oneonetwo", match_default, make_array(0, 9, 3, 9, 0, 3, -2, -2));
TEST_INVALID_REGEX("(\\g{3}two|(one))+", perl);
#endif
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);
#ifdef BOOST_REGEX_CXX03
TEST_INVALID_REGEX("a(b\\g-1)c", perl);
#endif
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);
#ifdef BOOST_REGEX_CXX03
TEST_INVALID_REGEX("a(b\\g{-1})c", perl);
#endif
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));
// Bug cases from https://github.com/boostorg/regex/issues/75
TEST_REGEX_SEARCH("(?:(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)\\g{-1}|WORKING)", perl, "WORKING", match_default, make_array(0, 7, -2, -2));
TEST_REGEX_SEARCH("(?:(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)(z)\\g{-1}|WORKING)", perl, "WORKING", match_default, make_array(0, 7, -2, -2));
}

View File

@@ -0,0 +1,281 @@
/*
*
* 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 occurrence:
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);
}
std::string to_narrow_string(std::wstring const& w)
{
return std::string(w.begin(), w.end());
}
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 : \"" << to_narrow_string(expression.c_str()) << "\" did not compile with the POSIX C API.", wchar_t);
return;
}
// try and find the first occurrence:
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 : \"" << to_narrow_string(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);
}
}
}
}
}
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 : \"" << to_narrow_string(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
}

View File

@@ -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

View File

@@ -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));
}

View File

@@ -0,0 +1,217 @@
/*
*
* 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(BOOST_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));
TEST_REGEX_SEARCH(".\\B.", perl, "!?", match_default, make_array(0, 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));
}
}

View File

@@ -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));
}

View File

@@ -0,0 +1,704 @@
/*
*
* 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 <boost/mpl/int.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) != std::distance(iterator_type(w2.prefix().first), iterator_type(w2[i].first))) || (w1.length(i) != std::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") != std::distance(iterator_type(w2.prefix().first), iterator_type(w2["abc"].first))) || (w1.length("abc") != std::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") != std::distance(iterator_type(w2.prefix().first), iterator_type(w2["N"].first))) || (w1.length("N") != std::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) != std::distance(iterator_type(w2.prefix().first), iterator_type(w2[i].first))) || (w1.length(i) != std::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

View File

@@ -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

View File

@@ -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(BOOST_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
}

View File

@@ -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

View File

@@ -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(std::distance(s.GetString(), tstart2->first) != last_end2)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of start of field split, found: "
<< std::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(std::distance(s.GetString(), tstart2->second) != expected_end)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of end2 of field split, found: "
<< std::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(std::distance(s.GetString(), tstart2->first) != last_end2)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of start of field split, found: "
<< std::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(std::distance(s.GetString(), tstart2->second) != expected_end)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of end2 of field split, found: "
<< std::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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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

View File

@@ -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))
}

View File

@@ -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(std::distance(base, sub.first) != answer_table[2*i])
{
BOOST_REGEX_TEST_ERROR(
"Error in start location of sub-expression "
<< i << ", found " << std::distance(base, sub.first)
<< ", expected " << answer_table[2*i] << ".", charT);
}
if(std::distance(base, sub.second) != answer_table[1+ 2*i])
{
BOOST_REGEX_TEST_ERROR(
"Error in end location of sub-expression "
<< i << ", found " << std::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(std::distance(search_text.begin(), start2->first) != last_end2)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of start of field split, found: "
<< std::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(std::distance(search_text.begin(), start2->second) != expected_end)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of end2 of field split, found: "
<< std::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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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(std::distance(base, sub.first) != answer_table[2*i])
{
BOOST_REGEX_TEST_ERROR(
"Error in start location of sub-expression "
<< i << ", found " << std::distance(base, sub.first)
<< ", expected " << answer_table[2*i] << ".", charT);
}
if(std::distance(base, sub.second) != answer_table[1+ 2*i])
{
BOOST_REGEX_TEST_ERROR(
"Error in end location of sub-expression "
<< i << ", found " << std::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(std::distance(search_text.begin(), start2->first) != last_end2)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of start of field split, found: "
<< std::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(std::distance(search_text.begin(), start2->second) != expected_end)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of end2 of field split, found: "
<< std::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(std::distance(search_text.begin(), start2->first) != last_end2)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of start of field split, found: "
<< std::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(std::distance(search_text.begin(), start2->second) != expected_end)
{
BOOST_REGEX_TEST_ERROR(
"Error in location of end2 of field split, found: "
<< std::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

View File

@@ -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 occurrence 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{}");
}

View File

@@ -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.]]", extended|icase, "A", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.A.]]", extended|icase, "a", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[[.A.]-b]+", extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("[A-[.b.]]+", extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("[[.a.]-B]+", extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("[a-[.B.]]+", extended|icase, "AaBb", match_default, make_array(0, 4, -2, -2));
TEST_REGEX_SEARCH("[\x61]", extended, "a", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("[\x61-c]+", extended, "abcd", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("[a-\x63]+", extended, "abcd", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("[[.a.]-c]+", extended, "abcd", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("[a-[.c.]]+", extended, "abcd", match_default, make_array(0, 3, -2, -2));
TEST_INVALID_REGEX("[[:alpha:]-a]", extended);
TEST_INVALID_REGEX("[a-[:alpha:]]", 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);
}

View File

@@ -0,0 +1,508 @@
/*
*
* 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);
#ifndef BOOST_REGEX_CXX03
// Some bug cases from https://github.com/boostorg/regex/issues/151
TEST_INVALID_REGEX("a|?+", perl | mod_x);
TEST_INVALID_REGEX("(?xi)a|?+", perl | mod_x);
TEST_INVALID_REGEX("(?xi)a|#\r*", perl | mod_x);
TEST_INVALID_REGEX("(?xi)|#\r*", perl | mod_x);
TEST_INVALID_REGEX("(?xi)|?+#\r*", perl | mod_x);
#endif
}

View File

@@ -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(BOOST_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);
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -0,0 +1,54 @@
/*
*
* 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
#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

View File

@@ -0,0 +1,211 @@
/*
*
* 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>
#ifdef BOOST_REGEX_CXX03
//
// 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;
}
#else
int main() {}
#endif

View File

@@ -0,0 +1,17 @@
/*
*
* 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/posix_api.cpp>
#include <libs/regex/src/regex.cpp>
#include <libs/regex/src/regex_debug.cpp>
#include <libs/regex/src/static_mutex.cpp>
#include <libs/regex/src/wide_posix_api.cpp>

View File

@@ -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

View File

@@ -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);
}

View File

@@ -0,0 +1,29 @@
/*
*
* Copyright (c) 2021
* 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)
*
*/
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
//
// Make sure our forward declarations match those in windows.h:
//
#define STRICT
#include <boost/regex.hpp>
#include <windows.h>
void test_proc()
{
std::string text, re;
boost::regex exp(re);
regex_match(text, exp);
}
#endif

View File

@@ -0,0 +1,29 @@
/*
*
* Copyright (c) 2021
* 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)
*
*/
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
//
// Make sure our forward declarations match those in windows.h:
//
#define NO_STRICT
#include <boost/regex.hpp>
#include <windows.h>
void test_proc()
{
std::string text, re;
boost::regex exp(re);
regex_match(text, exp);
}
#endif

View File

@@ -0,0 +1,27 @@
/*
*
* Copyright (c) 2021
* 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)
*
*/
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
//
// Make sure our forward declarations match those in windows.h:
//
#include <windows.h>
#include <boost/regex.hpp>
void test_proc()
{
std::string text, re;
boost::regex exp(re);
regex_match(text, exp);
}
#endif

View File

@@ -0,0 +1,28 @@
/*
*
* Copyright (c) 2021
* 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)
*
*/
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
//
// Make sure our forward declarations match those in windows.h:
//
#define STRICT
#define BOOST_NO_ANSI_APIS
#include <boost/regex.hpp>
#include <windows.h>
void test_proc()
{
std::string text, re;
boost::regex exp(re);
regex_match(text, exp);
}
#endif

View File

@@ -0,0 +1,204 @@
/*
*
* Copyright (c) 2021 John Maddock
* Copyright (c) 2021 Daniel Kruegler
*
* 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_casefold_test.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Simple test suite for Unicode case folding.
*/
#include <boost/regex/config.hpp>
#include <boost/detail/lightweight_main.hpp>
#include "../test_macros.hpp"
#if defined(BOOST_HAS_ICU)
#include <boost/regex/icu.hpp>
#include <utility>
#include <unicode/uversion.h>
#include <unicode/uchar.h>
typedef std::pair<int, int> unicode_verinfo;
// Function to query the effective Unicode major and minor
// version, because some spot test cases can only be tested
// for specific Unicode versions.
unicode_verinfo get_unicode_version()
{
UVersionInfo versionArray = {};
u_getUnicodeVersion(versionArray);
unicode_verinfo result(versionArray[0] , versionArray[1]);
return result;
}
void latin_1_checks()
{
typedef boost::icu_regex_traits traits_type;
traits_type traits;
// Test range [U+0000, U+0041): Identity fold
for (traits_type::char_type c = 0x0; c < 0x41; ++c)
{
traits_type::char_type nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, c);
}
// Test ASCII upper case letters [A, Z]: Each character folds
// to its lowercase variant:
for (traits_type::char_type c = 0x41; c <= 0x5A; ++c)
{
traits_type::char_type nc = traits.translate_nocase(c);
const int shift = 0x61 - 0x41;
BOOST_CHECK_EQUAL(nc, c + shift);
BOOST_CHECK_EQUAL(nc, traits.tolower(c));
}
// Test range (U+005A, U+00B5): Identity fold
for (traits_type::char_type c = 0x5A + 1; c < 0xB5; ++c)
{
traits_type::char_type nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, c);
}
// U+00B5 maps to its decomposition GREEK SMALL LETTER MU
// (U+03BC):
{
traits_type::char_type c = 0xB5;
traits_type::char_type nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, 0x03BC);
}
// Test range (U+00B5, U+00BF]: Identity fold
for (traits_type::char_type c = 0xB5 + 1; c <= 0xBF; ++c)
{
traits_type::char_type nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, c);
}
// Test range [U+00C0, U+00D6]: Each character folds
// to its lowercase variant:
for (traits_type::char_type c = 0xC0; c <= 0xD6; ++c)
{
traits_type::char_type nc = traits.translate_nocase(c);
traits_type::char_type lc = traits.tolower(c);
BOOST_CHECK_EQUAL(nc, lc);
BOOST_CHECK_NE(nc, c);
}
// U+00D7: Identity fold
{
traits_type::char_type c = 0xD7;
traits_type::char_type nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, c);
}
// Test range [U+00D8, U+00DE]: Each character folds
// to its lowercase variant:
for (traits_type::char_type c = 0xD8; c <= 0xDE; ++c)
{
traits_type::char_type nc = traits.translate_nocase(c);
traits_type::char_type lc = traits.tolower(c);
BOOST_CHECK_EQUAL(nc, lc);
BOOST_CHECK_NE(nc, c);
}
// Test range [U+00DF, U+00BF]: Identity fold
// Note that case folding of U+00DF (LATIN SMALL
// LETTER SHARP S) does not fold to U+1E9E (LATIN
// CAPITAL LETTER SHARP S) due to case folding
// stability contract
for (traits_type::char_type c = 0xDF; c <= 0xFF; ++c)
{
traits_type::char_type nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, c);
}
}
void spot_checks()
{
// test specific values ripped straight out of the Unicode standard
// to verify that our case folding is the same as theirs:
typedef boost::icu_regex_traits traits_type;
traits_type traits;
const unicode_verinfo unicode_version = get_unicode_version();
// 'LATIN CAPITAL LETTER SHARP S' folds to
// 'LATIN SMALL LETTER SHARP S'
if (unicode_version >= unicode_verinfo(5, 1))
{
traits_type::char_type c = 0x1E9E;
traits_type::char_type nc = traits.translate_nocase(c);
traits_type::char_type lc = traits.tolower(c);
BOOST_CHECK_EQUAL(nc, lc);
BOOST_CHECK_EQUAL(nc, 0xDF);
}
// Capital sigma (U+03A3) is the uppercase form of both the regular (U+03C2)
// and final (U+03C3) lowercase sigma. All these characters exists since
// Unicode 1.1.0.
{
traits_type::char_type c = 0x03A3;
traits_type::char_type nc = traits.translate_nocase(c);
traits_type::char_type lc = traits.tolower(c);
BOOST_CHECK_EQUAL(nc, lc);
BOOST_CHECK_EQUAL(nc, 0x03C3);
c = 0x03C2;
nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, 0x03C3);
c = 0x03C3;
nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, c);
}
// In Turkish languages the lowercase letter 'i' (U+0069) maps to an
// uppercase dotted I (U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE),
// while the uppercase letter 'I' (U+0049) maps to the dotless lowercase
// i (U+0131). The Unicode simple default mapping folds U+0130 to itself,
// but folds U+0049 to U+0069.
{
traits_type::char_type c = 0x0130;
traits_type::char_type nc = traits.translate_nocase(c);
BOOST_CHECK_EQUAL(nc, c);
c = 0x0049;
nc = traits.translate_nocase(c);
traits_type::char_type lc = traits.tolower(c);
BOOST_CHECK_EQUAL(nc, lc);
BOOST_CHECK_EQUAL(nc, 0x0069);
}
// Cherokee small letters were added with Unicode 8.0,
// but the upper case letters existed before, therefore
// the small letters case fold to upper case letters.
if (unicode_version >= unicode_verinfo(8, 0))
{
traits_type::char_type c = 0x13F8;
traits_type::char_type nc = traits.translate_nocase(c);
traits_type::char_type uc = traits.toupper(c);
BOOST_CHECK_EQUAL(nc, uc);
BOOST_CHECK_EQUAL(nc, 0x13F0);
}
}
#endif
int cpp_main( int, char* [] )
{
#if defined(BOOST_HAS_ICU)
latin_1_checks();
spot_checks();
#endif
return boost::report_errors();
}

View File

@@ -0,0 +1,323 @@
/*
*
* 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/config.hpp>
#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 boost::report_errors();
}