294 lines
8.8 KiB
C++
294 lines
8.8 KiB
C++
/*
|
|
*
|
|
* Copyright (c) 2004
|
|
* John Maddock
|
|
*
|
|
* Use, modification and distribution are subject to the
|
|
* Boost Software License, Version 1.0. (See accompanying file
|
|
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
*
|
|
*/
|
|
|
|
/*
|
|
* LOCATION: see http://www.boost.org for most recent version.
|
|
* FILE test.hpp
|
|
* VERSION see <boost/version.hpp>
|
|
* DESCRIPTION: Macros for test cases.
|
|
*/
|
|
|
|
|
|
#ifndef BOOST_REGEX_REGRESS_TEST_HPP
|
|
#define BOOST_REGEX_REGRESS_TEST_HPP
|
|
|
|
#include <boost/regex.hpp>
|
|
|
|
#ifdef BOOST_INTEL
|
|
// disable Intel's "remarks":
|
|
#pragma warning(disable:1418 981 383 1419 7)
|
|
#endif
|
|
|
|
#include <typeinfo>
|
|
#include "test_not_regex.hpp"
|
|
#include "test_regex_search.hpp"
|
|
#include "test_regex_replace.hpp"
|
|
#include "test_deprecated.hpp"
|
|
#include "test_mfc.hpp"
|
|
#include "test_icu.hpp"
|
|
#include "test_locale.hpp"
|
|
|
|
#ifdef TEST_THREADS
|
|
#include <boost/thread/once.hpp>
|
|
#endif
|
|
|
|
//
|
|
// define test entry proc, this forwards on to the appropriate
|
|
// real test:
|
|
//
|
|
template <class charT, class tagT>
|
|
void do_test(const charT& c, const tagT& tag);
|
|
|
|
template <class charT, class tagT>
|
|
void test(const charT& c, const tagT& tag)
|
|
{
|
|
do_test(c, tag);
|
|
}
|
|
//
|
|
// make these non-templates to speed up compilation times:
|
|
//
|
|
void test(const char&, const test_regex_replace_tag&);
|
|
void test(const char&, const test_regex_search_tag&);
|
|
void test(const char&, const test_invalid_regex_tag&);
|
|
|
|
#ifndef BOOST_NO_WREGEX
|
|
void test(const wchar_t&, const test_regex_replace_tag&);
|
|
void test(const wchar_t&, const test_regex_search_tag&);
|
|
void test(const wchar_t&, const test_invalid_regex_tag&);
|
|
#endif
|
|
|
|
template <class Regex>
|
|
struct call_once_func
|
|
{
|
|
Regex* pregex;
|
|
void operator()()const
|
|
{
|
|
return test_empty(*pregex);
|
|
}
|
|
};
|
|
|
|
template <class charT, class tagT>
|
|
void do_test(const charT& c, const tagT& tag)
|
|
{
|
|
#ifndef BOOST_NO_STD_LOCALE
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) && defined(TEST_THREADS)
|
|
// typeid appears to fail in multithreaded environments:
|
|
test_info<charT>::set_typename("");
|
|
#else
|
|
test_info<charT>::set_typename(typeid(boost::basic_regex<charT, boost::cpp_regex_traits<charT> >).name());
|
|
#endif
|
|
boost::basic_regex<charT, boost::cpp_regex_traits<charT> > e1;
|
|
#ifndef TEST_THREADS
|
|
static bool done_empty_test = false;
|
|
if(done_empty_test == false)
|
|
{
|
|
test_empty(e1);
|
|
done_empty_test = true;
|
|
}
|
|
#else
|
|
boost::once_flag f = BOOST_ONCE_INIT;
|
|
call_once_func<boost::basic_regex<charT, boost::cpp_regex_traits<charT> > > proc = { &e1 };
|
|
boost::call_once(f, proc);
|
|
#endif
|
|
if(test_locale::cpp_locale_state() == test_locale::test_with_locale)
|
|
e1.imbue(test_locale::cpp_locale());
|
|
if(test_locale::cpp_locale_state() != test_locale::no_test)
|
|
test(e1, tag);
|
|
#endif
|
|
#if !BOOST_WORKAROUND(__BORLANDC__, < 0x560)
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) && defined(TEST_THREADS)
|
|
// typeid appears to fail in multithreaded environments:
|
|
test_info<charT>::set_typename("");
|
|
#else
|
|
test_info<charT>::set_typename(typeid(boost::basic_regex<charT, boost::c_regex_traits<charT> >).name());
|
|
#endif
|
|
boost::basic_regex<charT, boost::c_regex_traits<charT> > e2;
|
|
if(test_locale::c_locale_state() != test_locale::no_test)
|
|
test(e2, tag);
|
|
#endif
|
|
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
|
|
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) && defined(TEST_THREADS)
|
|
// typeid appears to fail in multithreaded environments:
|
|
test_info<charT>::set_typename("");
|
|
#else
|
|
test_info<charT>::set_typename(typeid(boost::basic_regex<charT, boost::w32_regex_traits<charT> >).name());
|
|
#endif
|
|
boost::basic_regex<charT, boost::w32_regex_traits<charT> > e3;
|
|
if(test_locale::win_locale_state() == test_locale::test_with_locale)
|
|
e3.imbue(test_locale::win_locale());
|
|
if(test_locale::win_locale_state() != test_locale::no_test)
|
|
test(e3, tag);
|
|
#endif
|
|
// test old depecated code:
|
|
test_info<charT>::set_typename("Deprecated interfaces");
|
|
if((test_locale::win_locale_state() == test_locale::test_no_locale)
|
|
&& (test_locale::c_locale_state() == test_locale::test_no_locale)
|
|
&&(test_locale::cpp_locale_state() == test_locale::test_no_locale))
|
|
test_deprecated(c, tag);
|
|
// test MFC/ATL wrappers:
|
|
test_info<charT>::set_typename("MFC/ATL interfaces");
|
|
if((test_locale::win_locale_state() == test_locale::test_no_locale)
|
|
&& (test_locale::c_locale_state() == test_locale::test_no_locale)
|
|
&&(test_locale::cpp_locale_state() == test_locale::test_no_locale))
|
|
test_mfc(c, tag);
|
|
// test ICU code:
|
|
test_info<charT>::set_typename("ICU interfaces");
|
|
test_icu(c, tag);
|
|
}
|
|
|
|
//
|
|
// define function to pack args into an array:
|
|
//
|
|
const int* make_array(int first, ...);
|
|
|
|
|
|
//
|
|
// define macros for testing invalid regexes:
|
|
//
|
|
#define TEST_INVALID_REGEX_N(s, f)\
|
|
do{\
|
|
const char e[] = { s };\
|
|
std::string se(e, sizeof(e) - 1);\
|
|
test_info<char>::set_info(__FILE__, __LINE__, se, f);\
|
|
test(char(0), test_invalid_regex_tag());\
|
|
}while(0)
|
|
|
|
#ifndef BOOST_NO_WREGEX
|
|
#define TEST_INVALID_REGEX_W(s, f)\
|
|
do{\
|
|
const wchar_t e[] = { s };\
|
|
std::wstring se(e, (sizeof(e) / sizeof(wchar_t)) - 1);\
|
|
test_info<wchar_t>::set_info(__FILE__, __LINE__, se, f);\
|
|
test(wchar_t(0), test_invalid_regex_tag());\
|
|
}while(0)
|
|
#else
|
|
#define TEST_INVALID_REGEX_W(s, f)
|
|
#endif
|
|
|
|
#define TEST_INVALID_REGEX(s, f)\
|
|
TEST_INVALID_REGEX_N(s, f);\
|
|
TEST_INVALID_REGEX_W(BOOST_JOIN(L, s), f)
|
|
|
|
//
|
|
// define macros for testing regex searches:
|
|
//
|
|
#define TEST_REGEX_SEARCH_N(s, f, t, m, a)\
|
|
do{\
|
|
const char e[] = { s };\
|
|
std::string se(e, sizeof(e) - 1);\
|
|
const char st[] = { t };\
|
|
std::string sst(st, sizeof(st) - 1);\
|
|
test_info<char>::set_info(__FILE__, __LINE__, se, f, sst, m, a);\
|
|
test(char(0), test_regex_search_tag());\
|
|
}while(0)
|
|
|
|
#ifndef BOOST_NO_WREGEX
|
|
#define TEST_REGEX_SEARCH_W(s, f, t, m, a)\
|
|
do{\
|
|
const wchar_t e[] = { s };\
|
|
std::wstring se(e, (sizeof(e) / sizeof(wchar_t)) - 1);\
|
|
const wchar_t st[] = { t };\
|
|
std::wstring sst(st, (sizeof(st) / sizeof(wchar_t)) - 1);\
|
|
test_info<wchar_t>::set_info(__FILE__, __LINE__, se, f, sst, m, a);\
|
|
test(wchar_t(0), test_regex_search_tag());\
|
|
}while(0)
|
|
#else
|
|
#define TEST_REGEX_SEARCH_W(s, f, t, m, a)
|
|
#endif
|
|
|
|
#define TEST_REGEX_SEARCH(s, f, t, m, a)\
|
|
TEST_REGEX_SEARCH_N(s, f, t, m, a);\
|
|
TEST_REGEX_SEARCH_W(BOOST_JOIN(L, s), f, BOOST_JOIN(L, t), m, a)
|
|
|
|
#if (defined(__GNUC__) && (__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))
|
|
#define TEST_REGEX_SEARCH_L(s, f, t, m, a) TEST_REGEX_SEARCH_W(BOOST_JOIN(L, s), f, BOOST_JOIN(L, t), m, a)
|
|
#else
|
|
#define TEST_REGEX_SEARCH_L(s, f, t, m, a) TEST_REGEX_SEARCH(s, f, t, m, a)
|
|
#endif
|
|
|
|
//
|
|
// define macros for testing regex replaces:
|
|
//
|
|
#define TEST_REGEX_REPLACE_N(s, f, t, m, fs, r)\
|
|
do{\
|
|
const char e[] = { s };\
|
|
std::string se(e, sizeof(e) - 1);\
|
|
const char st[] = { t };\
|
|
std::string sst(st, sizeof(st) - 1);\
|
|
const char ft[] = { fs };\
|
|
std::string sft(ft, sizeof(ft) - 1);\
|
|
const char rt[] = { r };\
|
|
std::string srt(rt, sizeof(rt) - 1);\
|
|
test_info<char>::set_info(__FILE__, __LINE__, se, f, sst, m, 0, sft, srt);\
|
|
test(char(0), test_regex_replace_tag());\
|
|
}while(0)
|
|
|
|
#ifndef BOOST_NO_WREGEX
|
|
#define TEST_REGEX_REPLACE_W(s, f, t, m, fs, r)\
|
|
do{\
|
|
const wchar_t e[] = { s };\
|
|
std::wstring se(e, (sizeof(e) / sizeof(wchar_t)) - 1);\
|
|
const wchar_t st[] = { t };\
|
|
std::wstring sst(st, (sizeof(st) / sizeof(wchar_t)) - 1);\
|
|
const wchar_t ft[] = { fs };\
|
|
std::wstring sft(ft, (sizeof(ft) / sizeof(wchar_t)) - 1);\
|
|
const wchar_t rt[] = { r };\
|
|
std::wstring srt(rt, (sizeof(rt) / sizeof(wchar_t)) - 1);\
|
|
test_info<wchar_t>::set_info(__FILE__, __LINE__, se, f, sst, m, 0, sft, srt);\
|
|
test(wchar_t(0), test_regex_replace_tag());\
|
|
}while(0)
|
|
#else
|
|
#define TEST_REGEX_REPLACE_W(s, f, t, m, fs, r)
|
|
#endif
|
|
|
|
#define TEST_REGEX_REPLACE(s, f, t, m, fs, r)\
|
|
TEST_REGEX_REPLACE_N(s, f, t, m, fs, r);\
|
|
TEST_REGEX_REPLACE_W(BOOST_JOIN(L, s), f, BOOST_JOIN(L, t), m, BOOST_JOIN(L, fs), BOOST_JOIN(L, r))
|
|
|
|
//
|
|
// define the test group proceedures:
|
|
//
|
|
void basic_tests();
|
|
void test_simple_repeats();
|
|
void test_alt();
|
|
void test_sets();
|
|
void test_sets2();
|
|
void test_anchors();
|
|
void test_backrefs();
|
|
void test_character_escapes();
|
|
void test_assertion_escapes();
|
|
void test_tricky_cases();
|
|
void test_grep();
|
|
void test_replace();
|
|
void test_non_greedy_repeats();
|
|
void test_non_marking_paren();
|
|
void test_partial_match();
|
|
void test_forward_lookahead_asserts();
|
|
void test_fast_repeats();
|
|
void test_fast_repeats2();
|
|
void test_tricky_cases2();
|
|
void test_independent_subs();
|
|
void test_nosubs();
|
|
void test_conditionals();
|
|
void test_options();
|
|
void test_options2();
|
|
void test_en_locale();
|
|
void test_emacs();
|
|
void test_operators();
|
|
void test_overloads();
|
|
void test_unicode();
|
|
void test_pocessive_repeats();
|
|
void test_mark_resets();
|
|
void test_recursion();
|
|
void test_verbs();
|
|
|
|
#endif
|