forked from boostorg/regex
First cut at new v5 regex version, doesn't really work yet, but all the infrastructure is in place...
[SVN r22489]
This commit is contained in:
1 parent
99d5760d2b
commit
4d2d3a1450
65 files changed
+5155
-7075
No files matched your search
+2
-3
@@ -22,9 +22,8 @@ template test
|
||||
#
|
||||
template regression
|
||||
: <template>test # sources
|
||||
regress/parse.cpp
|
||||
regress/regress.cpp
|
||||
regress/tests.cpp
|
||||
regress/main.cpp
|
||||
regress/basic_tests.cpp
|
||||
<lib>../../test/build/boost_prg_exec_monitor
|
||||
;
|
||||
|
||||
|
||||
+13
-3
@@ -2,9 +2,19 @@
|
||||
|
||||
subproject libs/regex/test/captures ;
|
||||
|
||||
EX_SOURCES = c_regex_traits c_regex_traits_common cpp_regex_traits
|
||||
cregex fileiter posix_api regex regex_debug
|
||||
regex_synch w32_regex_traits wide_posix_api instances winstances ;
|
||||
EX_SOURCES =
|
||||
cpp_regex_traits.cpp
|
||||
cregex.cpp
|
||||
fileiter.cpp
|
||||
instances.cpp
|
||||
posix_api.cpp
|
||||
regex.cpp
|
||||
regex_debug.cpp
|
||||
regex_raw_buffer.cpp
|
||||
regex_traits_defaults.cpp
|
||||
static_mutex.cpp
|
||||
wide_posix_api.cpp
|
||||
winstances.cpp ;
|
||||
|
||||
lib boost_regex_extra : ../../src/$(EX_SOURCES).cpp <template>../../build/regex-options
|
||||
:
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,126 @@
|
||||
|
||||
#ifndef BOOST_REGEX_REGRESS_INFO_HPP
|
||||
#define BOOST_REGEX_REGRESS_INFO_HPP
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <boost/regex.hpp>
|
||||
//
|
||||
// class test info,
|
||||
// store information about the test we are about to conduct:
|
||||
//
|
||||
template <class charT>
|
||||
class test_info
|
||||
{
|
||||
typedef std::basic_string<charT> string_type;
|
||||
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;
|
||||
};
|
||||
static data_type& data()
|
||||
{
|
||||
static data_type d;
|
||||
return d;
|
||||
}
|
||||
public:
|
||||
test_info(){};
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
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 << std::endl
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
#include "test.hpp"
|
||||
#include <stdarg.h>
|
||||
|
||||
int error_count = 0;
|
||||
|
||||
int cpp_main(int argc, char * argv[])
|
||||
{
|
||||
basic_tests();
|
||||
return error_count;
|
||||
}
|
||||
|
||||
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).
|
||||
//
|
||||
static int data[200];
|
||||
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;
|
||||
}
|
||||
@@ -1,346 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2002
|
||||
* Dr 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* FILE parse.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
*
|
||||
* Input parsing functions for regress.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include "regress.h"
|
||||
|
||||
#ifndef BOOST_REGEX_NO_TEST
|
||||
|
||||
#ifndef BOOST_RE_ALGO_INCLUDED
|
||||
#include <algorithm>
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
|
||||
#ifdef BOOST_REGEX_V3
|
||||
#define regex_constants regbase
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// start by defining all our flag types:
|
||||
|
||||
flag_info flag_data[] = {
|
||||
{ BOOST_RE_STR("REG_BASIC"), 9, REG_BASIC, 0 },
|
||||
{ BOOST_RE_STR("REG_EXTENDED"), 12, REG_EXTENDED, 0 },
|
||||
{ BOOST_RE_STR("REG_ESCAPE_IN_LISTS"), 19, REG_ESCAPE_IN_LISTS, 0 },
|
||||
{ BOOST_RE_STR("REG_ICASE"), 9, REG_ICASE, 0 },
|
||||
{ BOOST_RE_STR("REG_NOSUB"), 9, REG_NOSUB, 0 },
|
||||
{ BOOST_RE_STR("REG_NEWLINE"), 11, REG_NEWLINE, 0 },
|
||||
{ BOOST_RE_STR("REG_NOCOLLATE"), 13, REG_NOCOLLATE, 0 },
|
||||
{ BOOST_RE_STR("REG_NOSPEC"), 10, REG_NOSPEC, 0 },
|
||||
{ BOOST_RE_STR("REG_NEWLINE_ALT"), 15, REG_NEWLINE_ALT , 0 },
|
||||
{ BOOST_RE_STR("REG_PERL"), 8, REG_PERL, 0 },
|
||||
{ BOOST_RE_STR("REG_AWK"), 7, REG_AWK, 0 },
|
||||
{ BOOST_RE_STR("REG_EGREP"), 9, REG_EGREP, 0 },
|
||||
|
||||
{ BOOST_RE_STR("REG_NOTBOL"), 10, REG_NOTBOL, 1 },
|
||||
{ BOOST_RE_STR("REG_NOTEOL"), 10, REG_NOTEOL, 1 },
|
||||
{ BOOST_RE_STR("REG_STARTEND"), 12, REG_STARTEND, 1 },
|
||||
|
||||
{ BOOST_RE_STR("basic"), 5, regex_constants::basic, 2 },
|
||||
{ BOOST_RE_STR("escape_in_lists"), 15, regex_constants::escape_in_lists, 2 },
|
||||
{ BOOST_RE_STR("char_classes"), 12, regex_constants::char_classes, 2 },
|
||||
{ BOOST_RE_STR("intervals"), 9, regex_constants::intervals, 2 },
|
||||
{ BOOST_RE_STR("limited_ops"), 11, regex_constants::limited_ops, 2 },
|
||||
{ BOOST_RE_STR("newline_alt"), 11, regex_constants::newline_alt, 2 },
|
||||
{ BOOST_RE_STR("bk_plus_qm"), 10, regex_constants::bk_plus_qm, 2 },
|
||||
{ BOOST_RE_STR("bk_braces"), 9, regex_constants::bk_braces, 2 },
|
||||
{ BOOST_RE_STR("bk_parens"), 9, regex_constants::bk_parens, 2 },
|
||||
{ BOOST_RE_STR("bk_refs"), 7, regex_constants::bk_refs, 2 },
|
||||
{ BOOST_RE_STR("bk_vbar"), 7, regex_constants::bk_vbar, 2 },
|
||||
{ BOOST_RE_STR("use_except"), 10, regex_constants::use_except, 2 },
|
||||
{ BOOST_RE_STR("literal"), 7, regex_constants::literal, 2 },
|
||||
#ifndef BOOST_REGEX_V3
|
||||
{ BOOST_RE_STR("nosubs"), 6, regex_constants::nosubs, 2 },
|
||||
{ BOOST_RE_STR("optimize"), 8, regex_constants::optimize, 2 },
|
||||
{ BOOST_RE_STR("perlex"), 6, regex_constants::perlex, 2 },
|
||||
#endif
|
||||
{ BOOST_RE_STR("normal"), 6, regex_constants::normal, 2 },
|
||||
{ BOOST_RE_STR("basic"), 5, regex_constants::basic, 2 },
|
||||
{ BOOST_RE_STR("extended"), 8, regex_constants::extended, 2 },
|
||||
{ BOOST_RE_STR("perl"), 6, regex_constants::perl, 2 },
|
||||
|
||||
{ BOOST_RE_STR("match_default"), 13, match_default, 3 },
|
||||
{ BOOST_RE_STR("match_not_bol"), 13, match_not_bol, 3 },
|
||||
{ BOOST_RE_STR("match_not_eol"), 13, match_not_eol, 3 },
|
||||
{ BOOST_RE_STR("match_not_bob"), 13, match_not_bob, 3 },
|
||||
{ BOOST_RE_STR("match_not_eob"), 13, match_not_eob, 3 },
|
||||
{ BOOST_RE_STR("match_not_bow"), 13, match_not_bow, 3 },
|
||||
{ BOOST_RE_STR("match_not_eow"), 13, match_not_eow, 3 },
|
||||
{ BOOST_RE_STR("match_not_dot_newline"), 21, match_not_dot_newline, 3 },
|
||||
{ BOOST_RE_STR("match_not_dot_null"), 18, match_not_dot_null, 3 },
|
||||
{ BOOST_RE_STR("match_prev_avail"), 16, match_prev_avail, 3 },
|
||||
{ BOOST_RE_STR("match_any"), 9, match_any, 3 },
|
||||
{ BOOST_RE_STR("match_not_null"), 14, match_not_null, 3 },
|
||||
{ BOOST_RE_STR("match_continuous"), 16, match_continuous, 3 },
|
||||
{ BOOST_RE_STR("match_partial"), 13, match_partial, 3 },
|
||||
#ifndef BOOST_REGEX_V3
|
||||
{ BOOST_RE_STR("match_nosubs"), 12, match_nosubs, 3 },
|
||||
{ BOOST_RE_STR("match_single_line"), 17, match_single_line, 3 },
|
||||
#endif
|
||||
{ BOOST_RE_STR("format_all"), 10, format_all, 3 },
|
||||
{ BOOST_RE_STR("format_sed"), 10, format_sed, 3 },
|
||||
{ BOOST_RE_STR("format_perl"), 11, format_perl, 3 },
|
||||
{ BOOST_RE_STR("format_no_copy"), 14, format_no_copy, 3 },
|
||||
{ BOOST_RE_STR("format_first_only"), 17, format_first_only, 3 },
|
||||
|
||||
{ BOOST_RE_STR("REG_NO_POSIX_TEST"), 17, REG_NO_POSIX_TEST, 4 },
|
||||
{ BOOST_RE_STR("REG_UNICODE_ONLY"), 16, REG_UNICODE_ONLY, 4 },
|
||||
{ BOOST_RE_STR("REG_GREP"), 8, REG_GREP, 4 },
|
||||
{ BOOST_RE_STR("REG_MERGE"), 9, REG_MERGE, 4 },
|
||||
{ BOOST_RE_STR("REG_MERGE_COPY"), 14, REG_MERGE_COPY, 4 },
|
||||
{ BOOST_RE_STR("REG_PARTIAL_MATCH"), 17, REG_PARTIAL_MATCH, 4 },
|
||||
|
||||
{ BOOST_RE_STR(""), 0, 0, 0 },
|
||||
};
|
||||
|
||||
// basically we create a simple token parser
|
||||
// using regular expressions
|
||||
|
||||
const char_t* expression_text = BOOST_RE_STR("(;.*)|") // comment
|
||||
BOOST_RE_STR("(^[[:blank:]]*-)|") // -
|
||||
BOOST_RE_STR("([^\"[:space:]][^[:space:]]*)|") // token
|
||||
BOOST_RE_STR("(\"((\\\\\"|[^\"])*)\")") // "token"
|
||||
;
|
||||
|
||||
typedef basic_regex<char_t> re_parse_t;
|
||||
typedef match_results<string_type::const_iterator> parse_grep;
|
||||
typedef string_type::const_iterator parse_iterator;
|
||||
|
||||
re_parse_t parse_expression(expression_text, regex_constants::normal);
|
||||
|
||||
//
|
||||
// now define our grep predicate function object:
|
||||
class parse_function
|
||||
{
|
||||
int mode;
|
||||
public:
|
||||
parse_function() : mode(0) {}
|
||||
parse_function(const parse_function& o) : mode(o.mode) {}
|
||||
bool operator()(const parse_grep& i);
|
||||
};
|
||||
|
||||
bool parse_function::operator()(const parse_grep& g)
|
||||
{
|
||||
parse_iterator i, j;
|
||||
// determine what caused the match:
|
||||
if(g[1].matched)
|
||||
{
|
||||
// we have a comment:
|
||||
return true;
|
||||
}
|
||||
else if(g[2].matched)
|
||||
{
|
||||
// we have the start of a line of flags
|
||||
mode = -1;
|
||||
for(int i = 0; i < 5; ++i)
|
||||
flags[i] = 0;
|
||||
return true;
|
||||
}
|
||||
else if(g[3].matched)
|
||||
{
|
||||
// token:
|
||||
i = g[3].first;
|
||||
j = g[3].second;
|
||||
}
|
||||
else
|
||||
{
|
||||
// token delimited by ""
|
||||
i = g[5].first;
|
||||
j = g[5].second;
|
||||
}
|
||||
|
||||
// now we need to switch depending upon what mode we are in:
|
||||
switch(mode)
|
||||
{
|
||||
case -1:
|
||||
{
|
||||
// parse the flag:
|
||||
unsigned int id = 0;
|
||||
while(flag_data[id].len != 0)
|
||||
{
|
||||
if(static_cast<unsigned int>(j - i) != flag_data[id].len)
|
||||
{
|
||||
++id;
|
||||
continue;
|
||||
}
|
||||
if(std::equal(i, j, flag_data[id].name) == true)
|
||||
{
|
||||
flags[flag_data[id].id] |= flag_data[id].value;
|
||||
return true;
|
||||
}
|
||||
++id;
|
||||
}
|
||||
cout << "Warning: Unknown flag: ";
|
||||
string_type t(i, j);
|
||||
cout << make_narrow(t).c_str();
|
||||
cout << endl;
|
||||
return true;
|
||||
}
|
||||
case 0:
|
||||
// set the expression text:
|
||||
expression = string_type(i, j);
|
||||
do_test = true;
|
||||
break;
|
||||
case 1:
|
||||
// set the text to match:
|
||||
search_text = string_type(i, j);
|
||||
jm_trace("Initial search text: " << make_narrow(search_text).c_str());
|
||||
expand_escapes(search_text);
|
||||
jm_trace("Search text after escapes expanded: " << make_narrow(search_text).c_str());
|
||||
break;
|
||||
case 2:
|
||||
// maybe set format string:
|
||||
if(flags[4] & REG_MERGE)
|
||||
{
|
||||
format_string = string_type(i, j);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
matches[mode - 2] = to_int(i, j);
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
// maybe set format result:
|
||||
if(flags[4] & REG_MERGE)
|
||||
{
|
||||
merge_string = string_type(i, j);
|
||||
expand_escapes(merge_string);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
matches[mode - 2] = to_int(i, j);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
jm_assert(mode >= 2);
|
||||
// set the relevent int value:
|
||||
matches[mode - 2] = to_int(i, j);
|
||||
}
|
||||
++mode;
|
||||
return true;
|
||||
}
|
||||
|
||||
void parse_input_line(const string_type& s)
|
||||
{
|
||||
// set matches back to starting values:
|
||||
for(int i = 0; i < MAX_MATCHES; ++i)
|
||||
{
|
||||
matches[i] = -2;
|
||||
}
|
||||
parse_function op;
|
||||
do_test = false;
|
||||
regex_grep(op, s.begin(), s.end(), parse_expression);
|
||||
jm_trace("expression: " << make_narrow(expression).c_str());
|
||||
jm_trace("search string: " << make_narrow(search_text).c_str());
|
||||
}
|
||||
|
||||
int to_int(string_type::const_iterator i, string_type::const_iterator j)
|
||||
{
|
||||
int val = 0;
|
||||
bool neg = false;
|
||||
if((i != j) && (*i == BOOST_RE_STR('-')))
|
||||
{
|
||||
neg = true;
|
||||
++i;
|
||||
}
|
||||
while (i != j)
|
||||
{
|
||||
val *= 10;
|
||||
val += *i - BOOST_RE_STR('0');
|
||||
++i;
|
||||
}
|
||||
if(neg)
|
||||
val *= -1;
|
||||
return val;
|
||||
}
|
||||
|
||||
void expand_escapes(string_type& s)
|
||||
{
|
||||
for(unsigned int i = 0; i < s.size(); ++i)
|
||||
{
|
||||
if(s[i] == BOOST_RE_STR('\\'))
|
||||
{
|
||||
switch(s[i+1])
|
||||
{
|
||||
case BOOST_RE_STR('a'):
|
||||
s.erase(s.begin() + i);
|
||||
s[i] = BOOST_RE_STR('\a');
|
||||
break;
|
||||
case BOOST_RE_STR('b'):
|
||||
s.erase(s.begin() + i);
|
||||
s[i] = BOOST_RE_STR('\b');
|
||||
break;
|
||||
case BOOST_RE_STR('f'):
|
||||
s.erase(s.begin() + i);
|
||||
s[i] = BOOST_RE_STR('\f');
|
||||
break;
|
||||
case BOOST_RE_STR('n'):
|
||||
s.erase(s.begin() + i);
|
||||
s[i] = BOOST_RE_STR('\n');
|
||||
break;
|
||||
case BOOST_RE_STR('r'):
|
||||
s.erase(s.begin() + i);
|
||||
s[i] = BOOST_RE_STR('\r');
|
||||
break;
|
||||
case BOOST_RE_STR('t'):
|
||||
s.erase(s.begin() + i);
|
||||
s[i] = BOOST_RE_STR('\t');
|
||||
break;
|
||||
case BOOST_RE_STR('v'):
|
||||
s.erase(s.begin() + i);
|
||||
s[i] = BOOST_RE_STR('\v');
|
||||
break;
|
||||
default:
|
||||
if( (s[i + 1] >= BOOST_RE_STR('0')) && (s[i + 1] <= BOOST_RE_STR('9')) )
|
||||
{
|
||||
int val = 0;
|
||||
unsigned int pos = i;
|
||||
++i;
|
||||
while((i < s.size()) && (s[i] >= BOOST_RE_STR('0')) && (s[i] <= BOOST_RE_STR('9')))
|
||||
{
|
||||
val *= 10;
|
||||
val += s[i] - BOOST_RE_STR('0');
|
||||
++i;
|
||||
}
|
||||
s.erase(s.begin() + pos, s.begin() + i);
|
||||
if(0 == val)
|
||||
{
|
||||
s.insert(s.begin()+pos, ' ');
|
||||
s[pos] = 0;
|
||||
}
|
||||
else
|
||||
s.insert(s.begin() + pos, (string_type::value_type)val);
|
||||
i = pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.erase(s.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2002
|
||||
* Dr 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 regex_test.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Builds regression test program with default
|
||||
* locale and narrow character tests. Also
|
||||
* instantiates all the templates in the library
|
||||
* as a sanity check.
|
||||
*/
|
||||
|
||||
// disable automatic selection of support library:
|
||||
#define BOOST_REGEX_NO_LIB
|
||||
#define BOOST_REGEX_STATIC_LINK
|
||||
#define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/regex/src.cpp>
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(disable: 4660)
|
||||
#endif
|
||||
//
|
||||
// instantiate templates used:
|
||||
//
|
||||
namespace boost{
|
||||
|
||||
#if defined(__GNUC__) && defined(__BEOS__)
|
||||
#define ra_it const char*
|
||||
#define test_char_type char
|
||||
#else
|
||||
typedef const char* ra_it;
|
||||
typedef char test_char_type;
|
||||
#endif
|
||||
typedef std::basic_string<test_char_type> test_string_type;
|
||||
|
||||
bool pred1(const match_results<ra_it>&)
|
||||
{ return true; }
|
||||
|
||||
typedef bool (*pred1_type)(const match_results<ra_it>&);
|
||||
typedef bool (*pred2_type)(const match_results<test_string_type::const_iterator>&);
|
||||
|
||||
//check that all the defined flags are available:
|
||||
regex::flag_type f = regex::escape_in_lists | regex::char_classes | regex::intervals | regex::limited_ops
|
||||
| regex::newline_alt | regex::bk_plus_qm | regex::bk_braces
|
||||
| regex::bk_parens | regex::bk_refs | regex::bk_vbar | regex::use_except
|
||||
| regex::failbit | regex::literal | regex::icase | regex::nocollate | regex::basic
|
||||
| regex::extended | regex::normal | regex::emacs | regex::awk | regex::grep | regex::egrep | regex::sed;
|
||||
|
||||
template class reg_expression<test_char_type>;
|
||||
template struct sub_match<ra_it>;
|
||||
template class match_results<ra_it>;
|
||||
#if 0
|
||||
template bool regex_match(ra_it,
|
||||
ra_it,
|
||||
match_results<ra_it>& m,
|
||||
const reg_expression<test_char_type>& e,
|
||||
unsigned flags);
|
||||
template bool regex_match(ra_it,
|
||||
ra_it,
|
||||
const reg_expression<test_char_type>& e,
|
||||
unsigned flags);
|
||||
template bool regex_search(ra_it,
|
||||
ra_it,
|
||||
match_results<ra_it>& m,
|
||||
const reg_expression<test_char_type>& e,
|
||||
unsigned flags);
|
||||
template unsigned int regex_grep(pred1_type,
|
||||
ra_it,
|
||||
ra_it,
|
||||
const reg_expression<test_char_type>& e,
|
||||
unsigned flags);
|
||||
template test_char_type* regex_format(test_char_type*,
|
||||
const match_results<ra_it>& m,
|
||||
const test_char_type* fmt,
|
||||
unsigned flags);
|
||||
template test_char_type* regex_format(test_char_type*,
|
||||
const match_results<ra_it>& m,
|
||||
const test_string_type& fmt,
|
||||
unsigned flags);
|
||||
template test_char_type* regex_replace(test_char_type*,
|
||||
ra_it,
|
||||
ra_it,
|
||||
const reg_expression<test_char_type>&,
|
||||
const test_char_type*,
|
||||
unsigned int flags);
|
||||
template test_char_type* regex_replace(test_char_type*,
|
||||
ra_it,
|
||||
ra_it,
|
||||
const reg_expression<test_char_type>& e,
|
||||
const test_string_type&,
|
||||
unsigned int flags);
|
||||
template std::size_t regex_split(test_string_type*,
|
||||
test_string_type&,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags,
|
||||
std::size_t);
|
||||
template std::size_t regex_split(test_string_type*,
|
||||
test_string_type& s,
|
||||
const reg_expression<test_char_type>& e,
|
||||
unsigned flags);
|
||||
|
||||
template std::size_t regex_split(test_string_type*, test_string_type&);
|
||||
|
||||
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
//
|
||||
// the following prototypes are only available if partial ordering
|
||||
// of template functions is supported:
|
||||
//
|
||||
template bool regex_match(const test_char_type*,
|
||||
match_results<const test_char_type*>& m,
|
||||
const reg_expression<test_char_type>& e,
|
||||
unsigned flags);
|
||||
template bool regex_match(const test_string_type&,
|
||||
match_results<test_string_type::const_iterator>&,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_match(const test_char_type*,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_match(const test_string_type&,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_search(const test_char_type*,
|
||||
match_results<const test_char_type*>&,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_search(const test_string_type&,
|
||||
match_results<test_string_type::const_iterator>&,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags);
|
||||
template unsigned int regex_grep(pred1_type,
|
||||
const test_char_type*,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags);
|
||||
template unsigned int regex_grep(pred2_type,
|
||||
const test_string_type&,
|
||||
const reg_expression<test_char_type>&,
|
||||
unsigned flags);
|
||||
template test_string_type regex_format
|
||||
(const match_results<test_string_type::const_iterator>& m,
|
||||
const test_char_type*,
|
||||
unsigned flags);
|
||||
template test_string_type regex_format
|
||||
(const match_results<test_string_type::const_iterator>&,
|
||||
const test_string_type&,
|
||||
unsigned flags);
|
||||
template test_string_type regex_replace(const test_string_type&,
|
||||
const reg_expression<test_char_type>&,
|
||||
const test_char_type*,
|
||||
unsigned int flags);
|
||||
template test_string_type regex_replace(const test_string_type&,
|
||||
const reg_expression<test_char_type>&,
|
||||
const test_string_type&,
|
||||
unsigned int flags);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
} // namespace boost
|
||||
|
||||
//
|
||||
// include regression test source files:
|
||||
//
|
||||
#ifdef BOOST_REGEX_USE_WIN32_LOCALE
|
||||
#define BOOST_RE_TEST_LOCALE_W32
|
||||
#elif !defined(BOOST_REGEX_USE_C_LOCALE)
|
||||
#define BOOST_RE_TEST_LOCALE_CPP
|
||||
#endif
|
||||
|
||||
#include "tests.cpp"
|
||||
#include "parse.cpp"
|
||||
#include "regress.cpp"
|
||||
|
||||
//
|
||||
// Como goes into an infinite loop trying to link this,
|
||||
// just have it fail for now:
|
||||
//
|
||||
#if defined(__COMO__) && defined(_MSC_VER)
|
||||
#error "Comeau in VC6 mode goes into an infinite loop trying to link this program!!!"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,306 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2002
|
||||
* Dr 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* FILE regress.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
*
|
||||
* main() and associated code for regress.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
#include <boost/regex.hpp>
|
||||
#ifdef BOOST_RE_OLD_IOSTREAM
|
||||
#include <fstream.h>
|
||||
#else
|
||||
#include <fstream>
|
||||
using std::ifstream;
|
||||
using std::ofstream;
|
||||
//using std::cin;
|
||||
//using std::cout;
|
||||
using std::endl;
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hrdstop
|
||||
#endif
|
||||
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
|
||||
#include "regress.h"
|
||||
|
||||
#ifndef BOOST_REGEX_NO_TEST
|
||||
|
||||
#if defined(BOOST_MSVC) && defined(_DEBUG)
|
||||
#include <CRTDBG.H>
|
||||
#endif
|
||||
#ifdef TIME_TEST
|
||||
#include <boost/timer.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// declare all our globals here:
|
||||
//
|
||||
|
||||
string_type expression;
|
||||
string_type search_text;
|
||||
string_type format_string;
|
||||
string_type merge_string;
|
||||
int matches[MAX_MATCHES];
|
||||
|
||||
char file[MAX_PATH];
|
||||
int line;
|
||||
bool do_test = false;
|
||||
unsigned int flags[5];
|
||||
unsigned error_count = 0;
|
||||
|
||||
void usage()
|
||||
{
|
||||
cout <<
|
||||
|
||||
"Usage: regress filename [filename2...]\n"
|
||||
"see tests.txt for an example test script\n"
|
||||
"and the script format.\n";
|
||||
|
||||
}
|
||||
|
||||
int cpp_main(int argc, char * argv[])
|
||||
{
|
||||
#if defined(BOOST_MSVC) && defined(_DEBUG)
|
||||
// turn on heap reporting at program exit:
|
||||
//int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
|
||||
//tmpFlag |= _CRTDBG_LEAK_CHECK_DF;
|
||||
//tmpFlag &= ~_CRTDBG_CHECK_CRT_DF;
|
||||
//_CrtSetDbgFlag( tmpFlag );
|
||||
#endif
|
||||
#ifdef TIME_TEST
|
||||
boost::timer tim;
|
||||
#endif
|
||||
if(argc < 2)
|
||||
usage();
|
||||
int i;
|
||||
for(i = 1; i < argc; ++i)
|
||||
{
|
||||
reset_error();
|
||||
ifstream is(argv[i]);
|
||||
if(is.good() == false)
|
||||
{
|
||||
cout << "Error unable to open file: " << argv[i] << endl << endl;
|
||||
return -1;
|
||||
}
|
||||
std::strcpy(file, argv[i]);
|
||||
line = 0;
|
||||
unsigned int tests = 0;
|
||||
while(is.good())
|
||||
{
|
||||
string_type s;
|
||||
get_line(is, s);
|
||||
++line;
|
||||
jm_trace("Reading test script line " << line << " " << make_narrow(s).c_str());
|
||||
parse_input_line(s);
|
||||
if(do_test)
|
||||
{
|
||||
run_tests();
|
||||
++tests;
|
||||
}
|
||||
}
|
||||
cout << line << " lines, " << tests << " tests completed in file " << argv[i] << endl;
|
||||
}
|
||||
#ifdef TIME_TEST
|
||||
double elapsed_time = tim.elapsed();
|
||||
cout << "Elapsed time = " << elapsed_time << "s" << endl;
|
||||
#endif
|
||||
|
||||
return error_count;
|
||||
}
|
||||
|
||||
#ifdef TEST_UNICODE
|
||||
|
||||
std::string make_narrow(const wchar_t* ptr)
|
||||
{
|
||||
std::string result;
|
||||
while(*ptr)
|
||||
{
|
||||
if(*ptr & ~0x7F)
|
||||
{
|
||||
char buf[10];
|
||||
std::sprintf(buf, "\\x%.4x", (int)*ptr);
|
||||
result.append(buf);
|
||||
++ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
result.append(1, (char)*ptr);
|
||||
++ptr;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
istream& get_line(istream& is, nstring_type& s, char delim)
|
||||
{
|
||||
char c = (char)is.get();
|
||||
s.erase(s.begin(), s.end());
|
||||
while((c != delim) && is.good())
|
||||
{
|
||||
s.append(1, c);
|
||||
c = (char)is.get();
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std{ using ::mbtowc; }
|
||||
#endif
|
||||
|
||||
istream& get_line(istream& is, string_type& s, char delim)
|
||||
{
|
||||
nstring_type t;
|
||||
get_line(is, t, delim);
|
||||
s.erase(s.begin(), s.end());
|
||||
const char* i, *j;
|
||||
i = t.c_str();
|
||||
j = t.c_str() + t.size();
|
||||
wchar_t* buf = new wchar_t[MB_CUR_MAX + 1];
|
||||
int cchars;
|
||||
while(i != j)
|
||||
{
|
||||
cchars = std::mbtowc(buf, i, j - i);
|
||||
if(cchars == -1)
|
||||
break;
|
||||
if(cchars == 0)
|
||||
break;
|
||||
s.insert(s.end(), buf, buf + cchars);
|
||||
i += cchars;
|
||||
}
|
||||
delete[] buf;
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
istream& get_line(istream& is, string_type& s, char delim)
|
||||
{
|
||||
char c = (char)is.get();
|
||||
s.erase(s.begin(), s.end());
|
||||
while((c != delim) && is.good())
|
||||
{
|
||||
s.append(1, c);
|
||||
c = (char)is.get();
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
jm_debug_alloc::jm_debug_alloc()
|
||||
{
|
||||
blocks = new int;
|
||||
count = new int;
|
||||
*blocks = 0;
|
||||
*count = 1;
|
||||
guard = this;
|
||||
}
|
||||
|
||||
jm_debug_alloc::jm_debug_alloc(const jm_debug_alloc& d)
|
||||
{
|
||||
if(&d != this)
|
||||
{
|
||||
blocks = d.blocks;
|
||||
count = d.count;
|
||||
++(*count);
|
||||
guard = this;
|
||||
}
|
||||
}
|
||||
jm_debug_alloc& jm_debug_alloc::operator=(const jm_debug_alloc& d)
|
||||
{
|
||||
if(&d != this)
|
||||
{
|
||||
free_();
|
||||
blocks = d.blocks;
|
||||
count = d.count;
|
||||
++(*count);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
jm_debug_alloc::~jm_debug_alloc()
|
||||
{
|
||||
if(guard != this)
|
||||
{
|
||||
cout << "Error: attempt to destroy object already destroyed" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
free_();
|
||||
guard = 0;
|
||||
}
|
||||
}
|
||||
void jm_debug_alloc::free_()
|
||||
{
|
||||
if(--(*count) == 0)
|
||||
{
|
||||
if(*blocks)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Error: " << *blocks << " blocks not freed by allocator" << endl;
|
||||
}
|
||||
delete count;
|
||||
delete blocks;
|
||||
}
|
||||
}
|
||||
|
||||
void* jm_debug_alloc::allocate(size_type n, void*)
|
||||
{
|
||||
pointer p = new char[n + maxi(sizeof(size_type), boost::re_detail::padding_size)];
|
||||
*(size_type*)p = n;
|
||||
++(*blocks);
|
||||
return p + maxi(sizeof(size_type), boost::re_detail::padding_size);
|
||||
}
|
||||
void jm_debug_alloc::deallocate(void* pv, size_type n)
|
||||
{
|
||||
char* p = (char*)pv;
|
||||
p -= maxi(sizeof(size_type), boost::re_detail::padding_size);
|
||||
if(*(size_type*)p != n)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Error: size mismatch in allocate/deallocate calls" << endl;
|
||||
}
|
||||
--(*blocks);
|
||||
delete[] p;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <iostream>
|
||||
|
||||
int cpp_main(int argc, char * argv[])
|
||||
{
|
||||
std::cout <<
|
||||
"\n<note>\n"
|
||||
#if defined(BOOST_NO_WREGEX) && defined(TEST_UNICODE)
|
||||
"This platform does not provide the needed wide character support for this test.\n"
|
||||
#elif defined(BOOST_REGEX_DYN_LINK)
|
||||
"Dynamic linking with this compiler is known not to work in this case - please complain to your compiler vendor.\n"
|
||||
#else
|
||||
"This test has been disabled due to a compiler bug - please complain to your compiler vendor.\n"
|
||||
#endif
|
||||
"</note>\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -429,15 +429,19 @@ __iterator_category(const debug_iterator<T>&) {
|
||||
#define BOOST_RE_TEST_LOCALE_W32
|
||||
#endif
|
||||
|
||||
// TODO:
|
||||
#define BOOST_RE_TEST_LOCALE_CPP
|
||||
#undef BOOST_RE_TEST_LOCALE_W32
|
||||
|
||||
#ifdef BOOST_REGEX_V3
|
||||
# define basic_regex reg_expression
|
||||
#endif
|
||||
#ifdef BOOST_RE_TEST_LOCALE_W32
|
||||
typedef boost::basic_regex<char_t, boost::w32_regex_traits<char_t>, jm_debug_alloc> re_type;
|
||||
typedef boost::basic_regex<char_t, boost::w32_regex_traits<char_t> > re_type;
|
||||
#elif defined(BOOST_RE_TEST_LOCALE_CPP)
|
||||
typedef boost::basic_regex<char_t, boost::cpp_regex_traits<char_t>, jm_debug_alloc> re_type;
|
||||
typedef boost::basic_regex<char_t, boost::cpp_regex_traits<char_t> > re_type;
|
||||
#else
|
||||
typedef boost::basic_regex<char_t, boost::c_regex_traits<char_t>, jm_debug_alloc> re_type;
|
||||
typedef boost::basic_regex<char_t, boost::c_regex_traits<char_t> > re_type;
|
||||
#endif
|
||||
#define REG_NO_POSIX_TEST 1
|
||||
#define REG_UNICODE_ONLY 2
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
|
||||
|
||||
#ifndef BOOST_REGEX_REGRESS_TEST_HPP
|
||||
#define BOOST_REGEX_REGRESS_TEST_HPP
|
||||
#include "test_not_regex.hpp"
|
||||
#include "test_regex_search.hpp"
|
||||
|
||||
|
||||
//
|
||||
// define test entry proc, this forwards on to the appropriate
|
||||
// real test:
|
||||
//
|
||||
template <class charT, class tagT>
|
||||
void test(charT, const tagT& tag)
|
||||
{
|
||||
boost::basic_regex<charT> e;
|
||||
test(e, 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)
|
||||
|
||||
//
|
||||
// define the test group proceedures:
|
||||
//
|
||||
void basic_tests();
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
|
||||
#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(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();
|
||||
bool have_catch = false;
|
||||
try{
|
||||
r.assign(expression, syntax_options);
|
||||
}
|
||||
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(), charT);
|
||||
}
|
||||
catch(const std::exception& r)
|
||||
{
|
||||
have_catch = true;
|
||||
BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but a std::exception instead: " << r.what(), charT);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
have_catch = true;
|
||||
BOOST_REGEX_TEST_ERROR("Expected a bad_expression exception, but got an exception of unknown type instead", charT);
|
||||
}
|
||||
if(!have_catch)
|
||||
{
|
||||
// oops expected exception was not thrown:
|
||||
BOOST_REGEX_TEST_ERROR("Expected an exception, but didn't find one.", charT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
|
||||
#ifndef BOOST_REGEX_REGRESS_REGEX_SEARCH_HPP
|
||||
#define BOOST_REGEX_REGRESS_REGEX_SEARCH_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)
|
||||
{
|
||||
typedef typename boost::sub_match<BidirectionalIterator>::value_type charT;
|
||||
if(sub.matched == 0)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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<typename std::basic_string<charT>::const_iterator> what;
|
||||
if(boost::regex_search(
|
||||
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);
|
||||
test_simple_search(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
|
||||
@@ -1,963 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2002
|
||||
* Dr 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)
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
* FILE tests.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
*
|
||||
* the actual tests conducted by regress.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
#include <boost/regex.hpp>
|
||||
#include "regress.h"
|
||||
|
||||
#ifndef BOOST_REGEX_NO_TEST
|
||||
|
||||
# ifdef BOOST_MSVC
|
||||
# pragma warning(disable: 4244 4267)
|
||||
#endif
|
||||
|
||||
using namespace boost;
|
||||
|
||||
template <class M1, class M2>
|
||||
bool compare_result(const M1& sm, const M2& m)
|
||||
{
|
||||
if(sm.size() != m.size())
|
||||
return false;
|
||||
#ifdef BOOST_REGEX_V3
|
||||
if(sm.line() != m.line())
|
||||
return false;
|
||||
#endif
|
||||
for(unsigned int i = 0; i < sm.size(); ++i)
|
||||
{
|
||||
if(sm.position(i) != m.position(i))
|
||||
return false;
|
||||
if(sm.length(i) != m.length(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class M1>
|
||||
bool compare_result(const M1& sm, const M1& m)
|
||||
{
|
||||
return sm == m;
|
||||
}
|
||||
|
||||
|
||||
template <class C, class T, class A>
|
||||
void cpp_eh_tests(const basic_regex<C, T, A>& )
|
||||
{
|
||||
#ifndef __GNUC__
|
||||
bool thrown = false;
|
||||
// try set_expression form first:
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
A a;
|
||||
basic_regex<C, T, A> e(a);
|
||||
e.set_expression(expression.c_str(), flags[2] | regex::use_except);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(const boost::bad_expression&)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
catch(...){}
|
||||
if(!thrown)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Error: expected exception not thrown" << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// now try constructor form:
|
||||
thrown = false;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
#endif
|
||||
{
|
||||
A a;
|
||||
basic_regex<C, T, A> e(expression.c_str(), flags[2] | regex::use_except, a);
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
catch(const boost::bad_expression&)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
catch(...){}
|
||||
if(!thrown)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Error: expected exception not thrown" << endl;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
template <class iterator>
|
||||
iterator find_last_line(iterator start, iterator end)
|
||||
{
|
||||
iterator result = start;
|
||||
while(start != end)
|
||||
{
|
||||
if(*start == '\n')
|
||||
{
|
||||
++start;
|
||||
result = start;
|
||||
}
|
||||
else
|
||||
++start;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class iterator>
|
||||
unsigned int count_lines(iterator start, iterator end)
|
||||
{
|
||||
unsigned int result = 0;
|
||||
while(start != end)
|
||||
{
|
||||
if(*start == '\n')
|
||||
++result;
|
||||
++start;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class iterator, class Alloc>
|
||||
class grep_test_predicate
|
||||
{
|
||||
int match_id;
|
||||
iterator base, term;
|
||||
// rebind allocator to correct type:
|
||||
#ifdef BOOST_REGEX_V3
|
||||
typedef Alloc alloc_type;
|
||||
#else
|
||||
typedef typename detail::rebind_allocator<boost::sub_match<iterator>, Alloc>::type alloc_type;
|
||||
#endif
|
||||
public:
|
||||
grep_test_predicate(iterator i, iterator j) : base(i), term(j) { match_id = 0; }
|
||||
~grep_test_predicate(){}
|
||||
bool operator()(const boost::match_results< iterator, alloc_type >& m);
|
||||
};
|
||||
|
||||
template <class iterator, class Alloc>
|
||||
bool grep_test_predicate<iterator, Alloc>::operator()(const boost::match_results< iterator, alloc_type >& m)
|
||||
{
|
||||
std::ptrdiff_t start, end;
|
||||
start = m[0].first - base;
|
||||
end = m[0].second - base;
|
||||
if((matches[match_id] != start) || (matches[match_id + 1] != end))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ grep match error: found [" << start << "," << end << "] expected [" << matches[match_id] << "," << matches[match_id+1] << "]" << endl;
|
||||
}
|
||||
|
||||
//
|
||||
// check $`:
|
||||
start = m[-1].first - base;
|
||||
end = m[-1].second - base;
|
||||
if(match_id &&
|
||||
( (end != matches[match_id]) || (start != matches[match_id - 1]) )
|
||||
)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ grep error in $`: found [" << start << "," << end << "] expected [" << matches[match_id-1] << "," << matches[match_id] << "]" << endl;
|
||||
}
|
||||
else if((!match_id) && ((start != 0) || (end != matches[0])))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ grep error in $`: found [" << start << "," << end << "] expected [" << 0 << "," << matches[0] << "]" << endl;
|
||||
}
|
||||
|
||||
//
|
||||
// check $':
|
||||
start = m[-2].first - base;
|
||||
end = m[-2].second - base;
|
||||
if((start != matches[match_id + 1]) || (end != (term-base)))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ grep error in $': found [" << start << "," << end << "] expected [" << matches[match_id + 1] << "," << (term-base) << "]" << endl;
|
||||
}
|
||||
|
||||
//
|
||||
// now check line()
|
||||
/* don't check this, it's not supported in the new algorithm....
|
||||
start = m.line();
|
||||
end = count_lines(base, iterator(m[0].first)) + 1;
|
||||
if(start != end)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ grep error in line(): found " << start << " expected " << end << endl;
|
||||
}
|
||||
*/
|
||||
//
|
||||
// now check line_start()
|
||||
/* don't check this, it's not supported in the new algorithm....
|
||||
start = m.line_start() - base;
|
||||
end = find_last_line(base, iterator(m[0].first)) - base;
|
||||
if(start != end)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ grep error in line_start(): found " << start << " expected " << end << endl;
|
||||
}
|
||||
*/
|
||||
match_id += 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <class C, class T, class A>
|
||||
void cpp_tests(const basic_regex<C, T, A>& e, bool recurse = true)
|
||||
{
|
||||
typedef typename basic_regex<C, T, A>::allocator_type base_allocator_type;
|
||||
#ifdef BOOST_REGEX_V3
|
||||
typedef base_allocator_type allocator_type;
|
||||
#else
|
||||
typedef typename detail::rebind_allocator<boost::sub_match<debug_iterator<string_type::iterator> >, base_allocator_type>::type allocator_type;
|
||||
#endif
|
||||
if(flags[4] & REG_MERGE)
|
||||
{
|
||||
//
|
||||
// test merge code:
|
||||
//
|
||||
string_type s;
|
||||
s = regex_merge(search_text, e, format_string.c_str(), static_cast<boost::match_flag_type>(flags[3]));
|
||||
if(s != merge_string)
|
||||
{
|
||||
begin_error();
|
||||
cout << "merge result mismatch: found \"" << make_narrow(s).c_str() << "\" expected \"" << make_narrow(merge_string.c_str()) << "\"" << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(recurse)
|
||||
{
|
||||
// copy and assign test:
|
||||
basic_regex<C, T, A> e2(e);
|
||||
cpp_tests(e2, false);
|
||||
e2 = e;
|
||||
cpp_tests(e2, false);
|
||||
basic_regex<C, T, A> e3;
|
||||
#ifndef BOOST_REGEX_V3
|
||||
e3.swap(e2);
|
||||
cpp_tests(e3, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(e.error_code())
|
||||
{
|
||||
// verify that we don't expect expression to compile
|
||||
if(search_text != BOOST_RE_STR("!"))
|
||||
{
|
||||
begin_error();
|
||||
cout << "Expression did not compile using regex++ API" << endl;
|
||||
}
|
||||
else if((recurse) && ((flags[3] & match_partial) == 0))
|
||||
cpp_eh_tests(e);
|
||||
}
|
||||
else if(flags[4] & REG_GREP)
|
||||
{
|
||||
// try to do grep:
|
||||
debug_iterator<string_type::iterator> x(search_text.begin(), search_text.begin(), search_text.end());
|
||||
debug_iterator<string_type::iterator> y(search_text.end(), search_text.begin(), search_text.end());
|
||||
grep_test_predicate<debug_iterator<string_type::iterator>, allocator_type> oi(x, y);
|
||||
regex_grep(oi, x, y, e, static_cast<boost::match_flag_type>(flags[3]));
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
if(!recurse)
|
||||
{
|
||||
unsigned len = search_text.size();
|
||||
const std::basic_string<char_t>& s = search_text;
|
||||
grep_test_predicate<std::basic_string<char_t>::const_iterator, base_allocator_type> oi2(s.begin(), s.end());
|
||||
regex_grep(oi2, s, e, static_cast<boost::match_flag_type>(flags[3]));
|
||||
grep_test_predicate<const char_t*, base_allocator_type> oi3(s.c_str(), s.c_str()+s.size());
|
||||
regex_grep(oi3, s.c_str(), e, static_cast<boost::match_flag_type>(flags[3]));
|
||||
assert(s.size() == len);
|
||||
assert(s.end() - s.begin() == (std::basic_string<char_t>::difference_type)len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// try to find match
|
||||
match_results< debug_iterator<string_type::iterator>, allocator_type> m;
|
||||
debug_iterator<string_type::iterator> x(search_text.begin(), search_text.begin(), search_text.end());
|
||||
debug_iterator<string_type::iterator> y(search_text.end(), search_text.begin(), search_text.end());
|
||||
if(regex_search(x, y, m, e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
// special case for partial matches:
|
||||
if(flags[4] & REG_PARTIAL_MATCH)
|
||||
{
|
||||
if(m[0].matched)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch, found full match when partial match was expected: found ("
|
||||
<< (m[0].first - x) << "," <<
|
||||
(m[0].second - x) << ")" << endl;
|
||||
}
|
||||
else if(((m[0].first - x) != matches[0]) || ((m[0].second - x) != matches[1]))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in sub-expression " << 0 <<
|
||||
", found (" << (m[0].first - x) << "," <<
|
||||
(m[0].second - x) << ") expected (" <<
|
||||
matches[0] << "," << matches[1] << ")" << endl;
|
||||
}
|
||||
return; // don't bother testing anything else for partial matches
|
||||
}
|
||||
// match found compare what matched with what we expect:
|
||||
int j = 0;
|
||||
for(unsigned int i = 0; i < m.size(); ++i, j += 2)
|
||||
{
|
||||
if(m[i].matched == false)
|
||||
{
|
||||
if(matches[j] != -1)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in sub-expression " << i <<
|
||||
", found (" << (m[i].first - x) << "," <<
|
||||
(m[i].second - x) << ") expected (" <<
|
||||
matches[j] << "," << matches[j+1] << ")" << endl;
|
||||
}
|
||||
}
|
||||
else if(((m[i].first - x) != matches[j]) || ((m[i].second - x) != matches[j+1]))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in sub-expression " << i <<
|
||||
", found (" << (m[i].first - x) << "," <<
|
||||
(m[i].second - x) << ") expected (" <<
|
||||
matches[j] << "," << matches[j+1] << ")" << endl;
|
||||
}
|
||||
}
|
||||
//
|
||||
// now check $` and $':
|
||||
//
|
||||
if((m[-1].first != x) || (m[-1].second != m[0].first))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in $` (match -1), found (" <<
|
||||
(m[-1].first - x) << "," << (m[-1].second - x) << ") expected (0" <<
|
||||
"," << matches[0] << ")" << endl;
|
||||
}
|
||||
if(((flags[3] & match_partial) == 0) && ((m[-2].first != m[0].second) || (m[-2].second != y)))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in $' (match -2), found (" <<
|
||||
(m[-2].first - x) << "," << (m[-2].second - x) << ") expected (" <<
|
||||
matches[1] << "," << (y-x) << ")" << endl;
|
||||
}
|
||||
#if !(defined(BOOST_MSVC) && (BOOST_MSVC <= 1300)) && !defined(BOOST_REGEX_V3)
|
||||
//
|
||||
// now try comparison operators:
|
||||
string_type s(m[0]);
|
||||
if((s != m[0]) || (m[0] != s)
|
||||
|| !(s == m[0]) || !(m[0] == s)
|
||||
|| (s < m[0]) || (m[0] < s)
|
||||
|| (s > m[0]) || (m[0] > s)
|
||||
|| !(s <= m[0]) || !(m[0] <= s)
|
||||
|| !(s >= m[0]) || !(m[0] >= s))
|
||||
{
|
||||
begin_error();
|
||||
cout << "string comparison failed for result" << std::endl;
|
||||
}
|
||||
if(s.find_first_of((string_type::value_type)0) == string_type::npos)
|
||||
{
|
||||
if((m[0] != s.c_str()) || (s.c_str() != m[0])
|
||||
|| !(m[0] == s.c_str()) || !(s.c_str() == m[0])
|
||||
|| (m[0] > s.c_str()) || (s.c_str() > m[0])
|
||||
|| (m[0] < s.c_str()) || (s.c_str() < m[0])
|
||||
|| !(m[0] >= s.c_str()) || !(s.c_str() >= m[0])
|
||||
|| !(m[0] <= s.c_str()) || !(s.c_str() <= m[0]))
|
||||
{
|
||||
begin_error();
|
||||
cout << "string comparison failed for result" << std::endl;
|
||||
}
|
||||
}
|
||||
//
|
||||
// now try addition operators:
|
||||
string_type sa(1, (string_type::value_type)'a');
|
||||
if(
|
||||
((m[0] + sa) != (s + sa))
|
||||
|| (sa + m[0]) != (sa + s)
|
||||
|| ((m[0] + m[0]) != (s + s))
|
||||
|| ((m[0] + m[0]) != (s + s))
|
||||
|| ((m[0] + sa[0]) != (s + sa[0]))
|
||||
|| ((sa[0] + m[0]) != (sa[0] + s))
|
||||
)
|
||||
{
|
||||
begin_error();
|
||||
cout << "string addition failed for result" << std::endl;
|
||||
}
|
||||
if(s.find_first_of((string_type::value_type)0) == string_type::npos)
|
||||
{
|
||||
if(
|
||||
((m[0] + sa.c_str()) != (s + sa))
|
||||
|| ((sa.c_str() + m[0]) != (sa + s))
|
||||
)
|
||||
{
|
||||
begin_error();
|
||||
cout << "string addition failed for result" << std::endl;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//
|
||||
// now try alternative forms of regex_search if available:
|
||||
#if !defined(BOOST_NO_FUNCTION_TEMPLATE_ORDERING)
|
||||
if(!recurse)
|
||||
{
|
||||
std::basic_string<char_t> s2(search_text.begin(), search_text.end());
|
||||
match_results<std::basic_string<char_t>::const_iterator> sm;
|
||||
if(regex_search(s2, sm, e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
if(compare_result(sm, m) == false)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_search(const std::string&, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_search(const std::string&, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
#ifndef BOOST_REGEX_V3
|
||||
if(!regex_search(s2, e, static_cast<boost::match_flag_type>(flags[3]))
|
||||
|| !regex_search(s2.begin(), s2.end(), e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_search(const std::string&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// partial match should give same result as full match
|
||||
// provided a full match is expected:
|
||||
//
|
||||
if(matches[0] > 0)
|
||||
{
|
||||
if(regex_search(x, y, m, e, static_cast<boost::match_flag_type>(flags[3]) | boost::match_partial))
|
||||
{
|
||||
if(compare_result(sm, m) == false)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_search when enabling match_partial" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result: match not found when match_partial specified" << endl;
|
||||
}
|
||||
}
|
||||
if(s2.find(char_t(0)) == std::basic_string<char_t>::npos)
|
||||
{
|
||||
match_results<const char_t*> ssm;
|
||||
if(regex_search(search_text.c_str(), ssm, e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
if(compare_result(ssm, m) == false)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_search(const char_t*, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_search(const char_t*, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
#ifndef BOOST_REGEX_V3
|
||||
if(!regex_search(search_text.c_str(), e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_search(const char_t*, const basic_regex&, int)" << endl;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if((false == recurse) && (matches[0] == 0) && (matches[1] == static_cast<int>(search_text.size())))
|
||||
{
|
||||
//
|
||||
// match expected on whole string, so all versions
|
||||
// of regex_match should also succeed:
|
||||
//
|
||||
match_results< debug_iterator<string_type::iterator>, allocator_type> m1;
|
||||
debug_iterator<string_type::iterator> x1(search_text.begin(), search_text.begin(), search_text.end());
|
||||
debug_iterator<string_type::iterator> y1(search_text.end(), search_text.begin(), search_text.end());
|
||||
if(regex_match(x1, y1, m1, e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
if(compare_result(m1, m) == false)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_match(iterator, iterator, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_match(iterator, iterator, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
std::basic_string<char_t> s3(search_text.begin(), search_text.end());
|
||||
match_results<std::basic_string<char_t>::const_iterator> sm;
|
||||
if(regex_match(s3, sm, e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
if(compare_result(sm, m) == false)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_match(const std::string&, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_match(const std::string&, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
if(s3.find(char_t(0)) == std::basic_string<char_t>::npos)
|
||||
{
|
||||
match_results<const char_t*> ssm;
|
||||
if(regex_match(search_text.c_str(), ssm, e, static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
if(compare_result(ssm, m) == false)
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_match(const char_t*, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_error();
|
||||
cout << "regex++ API result mismatch in regex_match(const char_t*, match_results&, const basic_regex&, int)" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// match not found
|
||||
if(matches[0] != -1)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Match expected but not found using regex++ API" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(TEST_UNICODE)
|
||||
|
||||
unsigned int hl_match_id;
|
||||
|
||||
bool
|
||||
#if (defined(__BORLANDC__) || defined(BOOST_MSVC)) && !defined(BOOST_DISABLE_WIN32)
|
||||
__cdecl
|
||||
#endif
|
||||
hl_grep_test_proc(const RegEx& e)
|
||||
{
|
||||
std::ptrdiff_t start, end;
|
||||
|
||||
start = e.Position(0);
|
||||
end = start + e.Length();
|
||||
if((matches[hl_match_id] != start) || (matches[hl_match_id + 1] != end))
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep match error: found [" << start << "," << end << "] expected [" << matches[hl_match_id] << "," << matches[hl_match_id+1] << "]" << endl;
|
||||
}
|
||||
if(0 == (flags[4] & REG_GREP))
|
||||
{
|
||||
for(unsigned int sub = 1; sub < e.Marks(); ++sub)
|
||||
{
|
||||
start = e.Position(sub);
|
||||
end = start + e.Length(sub);
|
||||
if((matches[2*sub] != start) || (matches[2*sub + 1] != end))
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep match error: found in sub " << sub << " [" << start << "," << end << "] expected [" << matches[2*sub] << "," << matches[2*sub+1] << "]" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check $`:
|
||||
start = e.Position(-1);
|
||||
end = start + e.Length(-1);
|
||||
if(start == -1)
|
||||
{
|
||||
if(hl_match_id &&
|
||||
( matches[hl_match_id] != matches[hl_match_id - 1] )
|
||||
)
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep error in $`: found [" << start << "," << end << "] expected [" << matches[hl_match_id-1] << "," << matches[hl_match_id] << "]" << endl;
|
||||
}
|
||||
else if((!hl_match_id) && (0 != matches[0]))
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep error in $`: found [" << start << "," << end << "] expected [" << 0 << "," << matches[0] << "]" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(hl_match_id &&
|
||||
( (end != matches[hl_match_id]) || (start != matches[hl_match_id - 1]) )
|
||||
)
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep error in $`: found [" << start << "," << end << "] expected [" << matches[hl_match_id-1] << "," << matches[hl_match_id] << "]" << endl;
|
||||
}
|
||||
else if((!hl_match_id) && ((start != 0) || (end != matches[0])))
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep error in $`: found [" << start << "," << end << "] expected [" << 0 << "," << matches[0] << "]" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// check $':
|
||||
start = e.Position(-2);
|
||||
end = start + e.Length(-2);
|
||||
if(start == -1)
|
||||
{
|
||||
if(matches[hl_match_id + 1] != (int)search_text.size())
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep error in $': found [" << start << "," << end << "] expected [" << matches[hl_match_id + 1] << "," << (search_text.size()) << "]" << endl;
|
||||
}
|
||||
}
|
||||
else if((start != matches[hl_match_id + 1]) || (end != (int)search_text.size()))
|
||||
{
|
||||
begin_error();
|
||||
cout << "class RegEx grep error in $': found [" << start << "," << end << "] expected [" << matches[hl_match_id + 1] << "," << (search_text.size()) << "]" << endl;
|
||||
}
|
||||
|
||||
hl_match_id += 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
void cpp_hl_tests(RegEx& e, bool recurse = true)
|
||||
{
|
||||
if(flags[4] & REG_MERGE)
|
||||
return;
|
||||
|
||||
if(e.error_code())
|
||||
{
|
||||
if(search_text != BOOST_RE_STR("!"))
|
||||
{
|
||||
begin_error();
|
||||
cout << "Expression did not compile with class RegEx" << endl;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(recurse)
|
||||
{
|
||||
// copy and assign test:
|
||||
RegEx e2(e);
|
||||
cpp_hl_tests(e2, false);
|
||||
e2 = e;
|
||||
cpp_hl_tests(e2, false);
|
||||
}
|
||||
|
||||
if(flags[4] & REG_GREP)
|
||||
{
|
||||
// try to do grep:
|
||||
hl_match_id = 0;
|
||||
GrepCallback cb = hl_grep_test_proc;
|
||||
e.Grep(cb, search_text.c_str(), static_cast<boost::match_flag_type>(flags[3]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(e.Search(search_text.c_str(), static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int j = 0;
|
||||
while(matches[j] != -2)
|
||||
{
|
||||
if( (matches[j] != (int)e.Position(i))
|
||||
|| ((matches[j] != -1) && ((matches[j+1] - matches[j] != (int)e.Length(i)))) )
|
||||
{
|
||||
begin_error();
|
||||
cout << "RegEx::Search error in subexpression " << i << ": found [" << e.Position(i) << "," << (e.Position(i) + e.Length(i)) << "] expected [" << matches[j] << "," << matches[j+1] << "]" << endl;
|
||||
}
|
||||
++i;
|
||||
j += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(matches[0] != -1)
|
||||
{
|
||||
begin_error();
|
||||
cout << "match expected but not found with RexEx::Search" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// test RegEx::Match only if we expect to match all of the input:
|
||||
//
|
||||
if((matches[0] == 0) && (matches[1] == (int)search_text.size()))
|
||||
{
|
||||
if(e.Match(search_text.c_str(), static_cast<boost::match_flag_type>(flags[3])))
|
||||
{
|
||||
unsigned int i = 0;
|
||||
unsigned int j = 0;
|
||||
while(matches[j] != -2)
|
||||
{
|
||||
if( (matches[j] != (int)e.Position(i))
|
||||
|| ((matches[j] != -1) && ((matches[j+1] - matches[j] != (int)e.Length(i)))) )
|
||||
{
|
||||
begin_error();
|
||||
cout << "RegEx::Match error in subexpression " << i << ": found [" << e.Position(i) << "," << (e.Position(i) + e.Length(i)) << "] expected [" << matches[j] << "," << matches[j+1] << "]" << endl;
|
||||
}
|
||||
++i;
|
||||
j += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
begin_error();
|
||||
cout << "Match expected but not found with RegEx::Match" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template <class iterator>
|
||||
bool has_nulls(iterator i, iterator j)
|
||||
{
|
||||
while(i != j)
|
||||
{
|
||||
if(*i == 0)
|
||||
return true;
|
||||
++i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef TEST_UNICODE
|
||||
#undef regcomp
|
||||
#undef regerror
|
||||
#undef regexec
|
||||
#undef regfree
|
||||
#undef regex_t
|
||||
#define regcomp regcompW
|
||||
#define regerror regerrorW
|
||||
#define regexec regexecW
|
||||
#define regfree regfreeW
|
||||
#define regex_t regex_tW
|
||||
#endif
|
||||
|
||||
|
||||
void run_tests()
|
||||
{
|
||||
#ifndef TEST_UNICODE
|
||||
if(flags[4] & REG_UNICODE_ONLY)
|
||||
return;
|
||||
#endif
|
||||
#ifndef NO_CPP_TEST
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
unsigned int f = flags[2] & ~regex::use_except;
|
||||
if(flags[0] & REG_ICASE)
|
||||
f |= regex::icase;
|
||||
re_type e(expression.c_str(), f);
|
||||
cpp_tests(e, true);
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
{
|
||||
//
|
||||
// this is only an error if the expression is expected to be valid:
|
||||
if(search_text != BOOST_RE_STR("!"))
|
||||
{
|
||||
begin_error();
|
||||
cout << "Unexpected exception thrown from C++ library: " << e.what() << endl;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Unexpected exception thrown from C++ library" << endl;
|
||||
}
|
||||
#endif // BOOST_NO_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
#if !defined(TEST_UNICODE)
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
if(((flags[3] & match_partial) == 0) && (flags[2] == regex::normal) && (has_nulls(search_text.begin(), search_text.end()) == false))
|
||||
{
|
||||
RegEx e;
|
||||
e.SetExpression(expression.c_str(), flags[0] & REG_ICASE);
|
||||
cpp_hl_tests(e, true);
|
||||
}
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
catch(const std::exception& )
|
||||
{
|
||||
if(search_text != BOOST_RE_STR("!"))
|
||||
{
|
||||
begin_error();
|
||||
cout << "Expression did not compile with class RegEx" << endl;
|
||||
}
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Unexpected exception thrown from RegEx::SetExpression" << endl;
|
||||
}
|
||||
#endif // BOOST_NO_EXCEPTIONS
|
||||
#endif
|
||||
|
||||
if(flags[4] & (REG_NO_POSIX_TEST | REG_GREP | REG_MERGE | REG_MERGE_COPY))
|
||||
return;
|
||||
regex_t posix_expression;
|
||||
regmatch_t m[MAX_MATCHES];
|
||||
if(regcomp(&posix_expression, expression.c_str(), flags[0]) == 0)
|
||||
{
|
||||
if(flags[1] & REG_STARTEND)
|
||||
{
|
||||
m[0].rm_so = 0;
|
||||
m[0].rm_eo = search_text.size();
|
||||
}
|
||||
if(regexec(&posix_expression, search_text.c_str(), MAX_MATCHES, m, flags[1]))
|
||||
{
|
||||
// match not found
|
||||
if(matches[0] != -1)
|
||||
{
|
||||
begin_error();
|
||||
cout << "Match expected but not found using POSIX API" << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// match found compare what matched with what we expect:
|
||||
int j = 0;
|
||||
for(unsigned int i = 0; i <= posix_expression.re_nsub; ++i, j += 2)
|
||||
{
|
||||
if((m[i].rm_so != matches[j]) || (m[i].rm_eo != matches[j+1]))
|
||||
{
|
||||
begin_error();
|
||||
cout << "POSIX API result mismatch in sub-expression " << i << ", found (" << m[i].rm_so << "," << m[i].rm_eo <<
|
||||
") expected (" << matches[j] << "," << matches[j+1] << ")" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
regfree(&posix_expression);
|
||||
}
|
||||
else
|
||||
{
|
||||
// expression did not compile
|
||||
if(search_text != BOOST_RE_STR("!"))
|
||||
{
|
||||
begin_error();
|
||||
cout << "Expression did not compile using POSIX API" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// error reporting:
|
||||
int last_line = 0;
|
||||
|
||||
void begin_error()
|
||||
{
|
||||
if(line != last_line)
|
||||
{
|
||||
cout << "Error in line " << line << " of file " << file << endl;
|
||||
cout << "Expression: " << make_narrow(expression).c_str() << endl;
|
||||
cout << "Search text: " << make_narrow(search_text).c_str() << endl;
|
||||
cout << "Flags: ";
|
||||
bool started = false;
|
||||
unsigned int id = 0;
|
||||
while(flag_data[id].len != 0)
|
||||
{
|
||||
if(flags[flag_data[id].id] & flag_data[id].value)
|
||||
{
|
||||
if(started)
|
||||
cout << " | ";
|
||||
cout << make_narrow(flag_data[id].name).c_str();
|
||||
started = true;
|
||||
}
|
||||
++id;
|
||||
}
|
||||
cout << endl;
|
||||
last_line = line;
|
||||
++error_count;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_error()
|
||||
{
|
||||
last_line = 0;
|
||||
}
|
||||
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) && (__BORLANDC__ <= 0x551) && !defined(_RWSTD_COMPILE_INSTANTIATE)
|
||||
//
|
||||
// this is an ugly hack to work around an ugly problem:
|
||||
// by default this file will produce unresolved externals during
|
||||
// linking unless _RWSTD_COMPILE_INSTANTIATE is defined (Borland bug).
|
||||
// However if _RWSTD_COMPILE_INSTANTIATE is defined then we get separate
|
||||
// copies of basic_string's static data in the RTL and this DLL, this messes
|
||||
// with basic_string's memory management and results in run-time crashes,
|
||||
// Oh sweet joy of Catch 22....
|
||||
//
|
||||
namespace std{
|
||||
template<> template<>
|
||||
basic_string<string_type::value_type>&
|
||||
basic_string<string_type::value_type>
|
||||
::replace<debug_iterator<string_type::iterator> >(
|
||||
string_type::iterator f1,
|
||||
string_type::iterator f2,
|
||||
debug_iterator<string_type::iterator> i1,
|
||||
debug_iterator<string_type::iterator> i2)
|
||||
{
|
||||
unsigned insert_pos = f1 - begin();
|
||||
unsigned remove_len = f2 - f1;
|
||||
unsigned insert_len = i2 - i1;
|
||||
unsigned org_size = size();
|
||||
if(insert_len > remove_len)
|
||||
{
|
||||
append(insert_len-remove_len, ' ');
|
||||
std::copy_backward(begin() + insert_pos + remove_len, begin() + org_size, end());
|
||||
std::copy(i1, i2, begin() + insert_pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::copy(begin() + insert_pos + remove_len, begin() + org_size, begin() + insert_pos + insert_len);
|
||||
std::copy(i1, i2, begin() + insert_pos);
|
||||
erase(size() + insert_len - remove_len);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 1998-2002
|
||||
* Dr 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 regex_test.cpp
|
||||
* VERSION see <boost/version.hpp>
|
||||
* DESCRIPTION: Builds regression test program with default
|
||||
* locale and wide character tests. Also
|
||||
* instantiates all the templates in the library
|
||||
* as a sanity check.
|
||||
*/
|
||||
|
||||
// disable automatic selection of support library:
|
||||
#define BOOST_REGEX_NO_LIB
|
||||
#define BOOST_REGEX_STATIC_LINK
|
||||
#define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
|
||||
|
||||
#if defined(_MSC_VER) && defined(__STL_DEBUG) && defined(_DLL)
|
||||
//
|
||||
// Ugly hack:
|
||||
// when this file is built with VC6 + STLPort 4 we get unresolved externals
|
||||
// from std::wstring if __STL_DEBUG is defined. As a workaround disable
|
||||
// STL debugging support in this case. This weakens the regression tests
|
||||
// but is still better than not being able to run them at all. This should be
|
||||
// removed once STLPort gets fixed.
|
||||
//
|
||||
#undef __STL_DEBUG
|
||||
#endif
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include <boost/regex/src.cpp>
|
||||
|
||||
#ifdef BOOST_NO_WREGEX
|
||||
#error The regex library is not configured for wide character support
|
||||
#endif
|
||||
|
||||
//
|
||||
// instantiate templates used:
|
||||
//
|
||||
namespace boost{
|
||||
|
||||
typedef const wchar_t* ra_it;
|
||||
typedef wchar_t char_type;
|
||||
typedef std::basic_string<char_type> test_string_type;
|
||||
|
||||
bool pred1(const match_results<ra_it>&)
|
||||
{ return true; }
|
||||
|
||||
typedef bool (*pred1_type)(const match_results<ra_it>&);
|
||||
typedef bool (*pred2_type)(const match_results<test_string_type::const_iterator>&);
|
||||
|
||||
//check that all the defined flags are available:
|
||||
wregex::flag_type f = wregex::escape_in_lists | wregex::char_classes | wregex::intervals | wregex::limited_ops
|
||||
| wregex::newline_alt | wregex::bk_plus_qm | wregex::bk_braces
|
||||
| wregex::bk_parens | wregex::bk_refs | wregex::bk_vbar | wregex::use_except
|
||||
| wregex::failbit | wregex::literal | wregex::icase | wregex::nocollate | wregex::basic
|
||||
| wregex::extended | wregex::normal | wregex::emacs | wregex::awk | wregex::grep | wregex::egrep | wregex::sed;
|
||||
|
||||
template class reg_expression<char_type>;
|
||||
template struct sub_match<ra_it>;
|
||||
template class match_results<ra_it>;
|
||||
|
||||
template bool regex_match(ra_it,
|
||||
ra_it,
|
||||
match_results<ra_it>& m,
|
||||
const reg_expression<char_type>& e,
|
||||
unsigned flags);
|
||||
template bool regex_match(ra_it,
|
||||
ra_it,
|
||||
const reg_expression<char_type>& e,
|
||||
unsigned flags);
|
||||
template bool regex_search(ra_it,
|
||||
ra_it,
|
||||
match_results<ra_it>& m,
|
||||
const reg_expression<char_type>& e,
|
||||
unsigned flags);
|
||||
template unsigned int regex_grep(pred1_type,
|
||||
ra_it,
|
||||
ra_it,
|
||||
const reg_expression<char_type>& e,
|
||||
unsigned flags);
|
||||
template char_type* regex_format(char_type*,
|
||||
const match_results<ra_it>& m,
|
||||
const char_type* fmt,
|
||||
unsigned flags);
|
||||
template char_type* regex_format(char_type*,
|
||||
const match_results<ra_it>& m,
|
||||
const test_string_type& fmt,
|
||||
unsigned flags);
|
||||
template char_type* regex_replace(char_type*,
|
||||
ra_it,
|
||||
ra_it,
|
||||
const reg_expression<char_type>&,
|
||||
const char_type*,
|
||||
unsigned int flags);
|
||||
template char_type* regex_replace(char_type*,
|
||||
ra_it,
|
||||
ra_it,
|
||||
const reg_expression<char_type>& e,
|
||||
const test_string_type&,
|
||||
unsigned int flags);
|
||||
template std::size_t regex_split(test_string_type*,
|
||||
test_string_type&,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags,
|
||||
std::size_t);
|
||||
template std::size_t regex_split(test_string_type*,
|
||||
test_string_type& s,
|
||||
const reg_expression<char_type>& e,
|
||||
unsigned flags);
|
||||
|
||||
template std::size_t regex_split(test_string_type*, test_string_type&);
|
||||
|
||||
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
|
||||
//
|
||||
// the following prototypes are only available if partial ordering
|
||||
// of template functions is supported:
|
||||
//
|
||||
template bool regex_match(const char_type*,
|
||||
match_results<const char_type*>& m,
|
||||
const reg_expression<char_type>& e,
|
||||
unsigned flags);
|
||||
template bool regex_match(const test_string_type&,
|
||||
match_results<test_string_type::const_iterator>&,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_match(const char_type*,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_match(const test_string_type&,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_search(const char_type*,
|
||||
match_results<const char_type*>&,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags);
|
||||
template bool regex_search(const test_string_type&,
|
||||
match_results<test_string_type::const_iterator>&,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags);
|
||||
template unsigned int regex_grep(pred1_type,
|
||||
const char_type*,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags);
|
||||
template unsigned int regex_grep(pred2_type,
|
||||
const test_string_type&,
|
||||
const reg_expression<char_type>&,
|
||||
unsigned flags);
|
||||
template test_string_type regex_format
|
||||
(const match_results<test_string_type::const_iterator>& m,
|
||||
const char_type*,
|
||||
unsigned flags);
|
||||
template test_string_type regex_format
|
||||
(const match_results<test_string_type::const_iterator>&,
|
||||
const test_string_type&,
|
||||
unsigned flags);
|
||||
template test_string_type regex_replace(const test_string_type&,
|
||||
const reg_expression<char_type>&,
|
||||
const char_type*,
|
||||
unsigned int flags);
|
||||
template test_string_type regex_replace(const test_string_type&,
|
||||
const reg_expression<char_type>&,
|
||||
const test_string_type&,
|
||||
unsigned int flags);
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace boost
|
||||
|
||||
//
|
||||
// include regression test source files:
|
||||
//
|
||||
#ifdef BOOST_REGEX_USE_WIN32_LOCALE
|
||||
#define BOOST_RE_TEST_LOCALE_W32
|
||||
#elif !defined(BOOST_REGEX_USE_C_LOCALE)
|
||||
#define BOOST_RE_TEST_LOCALE_CPP
|
||||
#endif
|
||||
#define TEST_UNICODE
|
||||
#include "tests.cpp"
|
||||
#include "parse.cpp"
|
||||
#include "regress.cpp"
|
||||
|
||||
//
|
||||
// Como goes into an infinite loop trying to link this,
|
||||
// just have it fail for now:
|
||||
//
|
||||
#if defined(__COMO__) && defined(_MSC_VER)
|
||||
#error "Comeau in VC6 mode goes into an infinite loop trying to link this program!!!"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2004
|
||||
* Dr 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 <iostream>
|
||||
#include <boost/regex/static_mutex.hpp>
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/timer.hpp>
|
||||
|
||||
//
|
||||
// we cannot use the regular Boost.Test in here: it is not thread safe
|
||||
// and calls to BOOST_TEST will eventually crash on some compilers
|
||||
// (Borland certainly) due to race conditions inside the Boost.Test lib.
|
||||
//
|
||||
#define BOOST_TEST(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_TEST(++has_lock == 1);
|
||||
BOOST_TEST(guard.locked());
|
||||
BOOST_TEST(guard);
|
||||
bool result = (--data > 0) ? true : false;
|
||||
BOOST_TEST(--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_TEST(0 == guard.locked());
|
||||
BOOST_TEST(!guard);
|
||||
guard.lock();
|
||||
BOOST_TEST(++has_lock == 1);
|
||||
BOOST_TEST(guard.locked());
|
||||
BOOST_TEST(guard);
|
||||
bool result = (--data > 0) ? true : false;
|
||||
BOOST_TEST(--has_lock == 0);
|
||||
guard.unlock();
|
||||
BOOST_TEST(0 == guard.locked());
|
||||
BOOST_TEST(!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_TEST(++has_lock == 1);
|
||||
BOOST_TEST(guard.locked());
|
||||
BOOST_TEST(guard);
|
||||
bool result = (--data > 0) ? true : false;
|
||||
BOOST_TEST(--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()
|
||||
{
|
||||
BOOST_TEST(0 != &up1);
|
||||
|
||||
boost::thread thrd1(&thread1_proc);
|
||||
boost::thread thrd2(&thread1_proc);
|
||||
boost::thread thrd3(&thread2_proc);
|
||||
boost::thread thrd4(&thread2_proc);
|
||||
boost::thread thrd5(&thread3_proc);
|
||||
boost::thread thrd6(&thread3_proc);
|
||||
|
||||
thrd1.join();
|
||||
thrd2.join();
|
||||
thrd3.join();
|
||||
thrd4.join();
|
||||
thrd5.join();
|
||||
thrd6.join();
|
||||
|
||||
return total_failures;
|
||||
}
|
||||
Reference in new issue
Block a user