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:
John Maddock
2004-03-12 13:22:44 +00:00
parent 99d5760d2b
commit 4d2d3a1450
65 changed files with 5155 additions and 7075 deletions

View File

@ -37,11 +37,21 @@ template msvc-stlport-tricky
<define>BOOST_ALL_NO_LIB=1
;
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 ;
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 : ../src/$(SOURCES).cpp <template>regex-options
lib boost_regex : ../src/$(SOURCES) <template>regex-options
:
common-variant-tag
:

View File

@ -172,7 +172,6 @@ using namespace boost;
void HandleFile(const char* wild)
{
using namespace boost;
jm_trace("Handling file " << wild);
file_iterator end;
file_iterator start(wild);
@ -193,14 +192,12 @@ void HandleFile(const char* wild)
std::strcat(buf, directory_iterator::separator());
std::strcat(buf, "*");
}
jm_trace("Enumerating directories: " << buf);
directory_iterator dstart(buf);
directory_iterator dend;
// now get the file mask bit of "wild":
const char* ptr = wild + rootlen;
if(*ptr) ++ptr;
jm_trace("File mask part is: " << ptr);
while(dstart != dend)
{
@ -217,7 +214,6 @@ int done = 0;
void HandleArg(const char* arg)
{
using namespace boost;
jm_trace("Handling argument: " << arg);
if(*arg == '-')
{
parse_switch(arg);

View File

@ -50,12 +50,16 @@
# include <iterator>
# include <iosfwd>
# include <vector>
# include <map>
# include <limits>
# include <boost/config.hpp>
# include <boost/assert.hpp>
# include <boost/cstdint.hpp>
# include <boost/detail/allocator.hpp>
# include <boost/regex/config/cstring.hpp>
# include <boost/throw_exception.hpp>
# include <boost/scoped_ptr.hpp>
# include <boost/shared_ptr.hpp>
# ifndef BOOST_NO_STD_LOCALE
# include <locale>
# endif
@ -117,6 +121,9 @@
#if defined(BOOST_DISABLE_WIN32) && !defined(BOOST_REGEX_NO_W32)
# define BOOST_REGEX_NO_W32
#endif
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
# include <windows.h>
#endif
// some versions of gcc can't merge template instances:
#if defined(__CYGWIN__)
@ -285,20 +292,6 @@ namespace boost{ typedef wchar_t regex_wchar_type; }
# define BOOST_REGEX_USE_C_LOCALE
#endif
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
# include <windows.h>
#endif
#ifdef MAXPATH
# define BOOST_REGEX_MAX_PATH MAXPATH
#elif defined(MAX_PATH)
# define BOOST_REGEX_MAX_PATH MAX_PATH
#elif defined(FILENAME_MAX)
# define BOOST_REGEX_MAX_PATH FILENAME_MAX
#else
# define BOOST_REGEX_MAX_PATH 200
#endif
#ifndef BOOST_REGEX_MAX_STATE_COUNT
# define BOOST_REGEX_MAX_STATE_COUNT 100000000
#endif
@ -331,63 +324,6 @@ if(0 == (x))\
# define BOOST_REGEX_NOEH_ASSERT(x)
#endif
/*****************************************************************************
*
* Debugging / tracing support:
*
****************************************************************************/
#if defined(BOOST_REGEX_DEBUG) && defined(__cplusplus)
# include <iostream>
using std::cout;
using std::cin;
using std::cerr;
using std::endl;
using std::hex;
using std::dec;
# ifndef jm_assert
# define jm_assert(x) assert(x)
# endif
# ifndef jm_trace
# define jm_trace(x) cerr << x << endl;
# endif
# ifndef jm_instrument
# define jm_instrument jm_trace(__FILE__<<"#"<<__LINE__)
# endif
namespace boost{
namespace re_detail{
class debug_guard
{
public:
char g1[32];
const char* pc;
char* pnc;
const char* file;
int line;
char g2[32];
debug_guard(const char* f, int l, const char* p1 = 0, char* p2 = 0);
~debug_guard();
};
# define BOOST_RE_GUARD_STACK boost::re_detail::debug_guard sg(__FILE__, __LINE__);
# define BOOST_RE_GUARD_GLOBAL(x) const char g1##x[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, }; char g2##x[32]; boost::debug_guard g3##x(__FILE__, __LINE__, g1##x, g2##x);
} // namespace re_detail
} // namespace boost
#else
# define jm_assert(x)
# define jm_trace(x)
# define BOOST_RE_GUARD_STACK
# define BOOST_RE_GUARD_GLOBAL(x)
# ifndef jm_instrument
# define jm_instrument
# endif
#endif
/*****************************************************************************
*
@ -430,13 +366,12 @@ BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page();
namespace boost{
namespace re_detail{
BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_regex_exception(const std::string& s);
template <class traits>
void raise_error(const traits& t, unsigned code)
{
(void)t; // warning suppression
raise_regex_exception(t.error_string(code));
std::runtime_error e(t.error_string(code));
throw_exception(e);
}
}

View File

@ -46,8 +46,16 @@ public:
class BOOST_REGEX_DECL bad_expression : public bad_pattern
{
public:
explicit bad_expression(const std::string& s) : bad_pattern(s) {}
explicit bad_expression(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos)
: bad_pattern(s), m_error_code(err), m_position(pos) {}
~bad_expression() throw();
regex_constants::error_type errorno()
{ return m_error_code; }
std::ptrdiff_t position()
{ return m_position; }
private:
regex_constants::error_type m_error_code;
std::ptrdiff_t m_position;
};
#ifdef BOOST_HAS_ABI_HEADERS

View File

@ -0,0 +1,179 @@
/*
*
* 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.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares static_mutex lock type, there are three different
* implementations: POSIX pthreads, WIN32 threads, and portable,
* these are described in more detail below.
*/
#ifndef BOOST_REGEX_STATIC_MUTEX_HPP
#define BOOST_REGEX_STATIC_MUTEX_HPP
#include <boost/config.hpp>
#ifdef BOOST_HAS_PTHREADS
#include <pthread.h>
#endif
#if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
//
// pthreads version:
// simple wrap around a pthread_mutex_t initialized with
// PTHREAD_MUTEX_INITIALIZER.
//
namespace boost{
class scoped_static_mutex_lock;
class static_mutex
{
public:
typedef scoped_static_mutex_lock scoped_lock;
pthread_mutex_t m_mutex;
};
#define BOOST_STATIC_MUTEX_INIT { PTHREAD_MUTEX_INITIALIZER, }
class scoped_static_mutex_lock
{
public:
scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
~scoped_static_mutex_lock();
operator void const*()const;
bool locked()const;
void lock();
void unlock();
private:
static_mutex& m_mutex;
bool m_have_lock;
};
inline scoped_static_mutex_lock::operator void const*()const
{
return locked() ? this : 0;
}
inline bool scoped_static_mutex_lock::locked()const
{
return m_have_lock;
}
} // namespace boost
#elif defined(BOOST_HAS_WINTHREADS)
//
// Win32 version:
// Use a 32-bit int as a lock, along with a test-and-set
// implementation using InterlockedCompareExchange.
//
#include <boost/cstdint.hpp>
namespace boost{
class scoped_static_mutex_lock;
class static_mutex
{
public:
typedef scoped_static_mutex_lock scoped_lock;
volatile boost::int32_t m_mutex;
};
#define BOOST_STATIC_MUTEX_INIT { 0, }
class scoped_static_mutex_lock
{
public:
scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
~scoped_static_mutex_lock();
operator void const*()const;
bool locked()const;
void lock();
void unlock();
private:
static_mutex& m_mutex;
bool m_have_lock;
scoped_static_mutex_lock(const scoped_static_mutex_lock&);
scoped_static_mutex_lock& operator=(const scoped_static_mutex_lock&);
};
inline scoped_static_mutex_lock::operator void const*()const
{
return locked() ? this : 0;
}
inline bool scoped_static_mutex_lock::locked()const
{
return m_have_lock;
}
} // namespace
#else
//
// Portable version of a static mutex based on Boost.Thread library:
// This has to use a single mutex shared by all instances of static_mutex
// because boost::call_once doesn't alow us to pass instance information
// down to the initialisation proceedure. In fact the initialisation routine
// may need to be called more than once - but only once per instance.
//
#include <boost/thread/once.hpp>
#include <boost/thread/recursive_mutex.hpp>
namespace boost{
class scoped_static_mutex_lock;
extern "C" void free_static_mutex();
class static_mutex
{
public:
typedef scoped_static_mutex_lock scoped_lock;
static void init();
static boost::recursive_mutex* m_pmutex;
static boost::once_flag m_once;
};
#define BOOST_STATIC_MUTEX_INIT { }
class scoped_static_mutex_lock
{
public:
scoped_static_mutex_lock(static_mutex& mut, bool lk = true);
~scoped_static_mutex_lock();
operator void const*()const;
bool locked()const;
void lock();
void unlock();
private:
boost::recursive_mutex::scoped_lock* m_plock;
bool m_have_lock;
};
inline scoped_static_mutex_lock::operator void const*()const
{
return locked() ? this : 0;
}
inline bool scoped_static_mutex_lock::locked()const
{
return m_have_lock;
}
} // namespace
#endif
#endif

View File

@ -1,6 +1,6 @@
/*
*
* Copyright (c) 1998-2002
* Copyright (c) 1998-2004
* Dr John Maddock
*
* Use, modification and distribution are subject to the
@ -13,8 +13,7 @@
* LOCATION: see http://www.boost.org for most recent version.
* FILE basic_regex.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares template class basic_regex (note that member function
* bodies are in regex_compile.hpp).
* DESCRIPTION: Declares template class basic_regex.
*/
#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP
@ -25,28 +24,155 @@
#endif
namespace boost{
//
// class reg_expression
// represents the compiled
// regular expression:
//
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable : 4251 4231 4660)
#endif
namespace re_detail{
//
// forward declaration, we will need this one later:
//
template <class charT, class traits>
class basic_regex_parser;
//
// class regex_data:
// represents the data we wish to expose to the matching algorithms.
//
template <class charT, class traits>
struct regex_data
{
typedef regex_constants::syntax_option_type flag_type;
typedef std::size_t size_type;
regex_data(const traits& t) : m_traits(t) {}
regex_data(){}
traits m_traits; // traits class instance
flag_type m_flags; // flags with which we were compiled
int m_status; // error code (0 implies OK).
const charT* m_expression; // the original expression
std::ptrdiff_t m_expression_len; // the length of the original expression
size_type m_mark_count; // the number of marked sub-expressions
re_detail::re_syntax_base* m_first_state; // the first state of the machine
unsigned m_restart_type; // search optimisation type
unsigned char m_startmap[1 << CHAR_BIT]; // which characters can start a match
unsigned int m_can_be_null; // whether we can match a null string
re_detail::raw_storage m_data; // the buffer in which our states are constructed
};
//
// class basic_regex_implementation
// pimpl implementation class for basic_regex.
//
template <class charT, class traits>
class basic_regex_implementation
: protected regex_data<charT, traits>
{
public:
typedef regex_constants::syntax_option_type flag_type;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
typedef typename traits::locale_type locale_type;
typedef const charT* const_iterator;
basic_regex_implementation(){}
basic_regex_implementation(const traits& t)
: regex_data<charT, traits>(t) {}
void assign(const charT* arg_first,
const charT* arg_last,
flag_type f)
{
regex_data<charT, traits>* pdat = this;
basic_regex_parser<charT, traits> parser(pdat);
parser.parse(arg_first, arg_last, f);
}
locale_type BOOST_REGEX_CALL imbue(locale_type l)
{
return this->m_traits.imbue(l);
}
locale_type BOOST_REGEX_CALL getloc()const
{
return this->m_traits.getloc();
}
std::basic_string<charT> BOOST_REGEX_CALL str()const
{
std::basic_string<charT> result;
if(this->m_status == 0)
result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
return result;
}
const_iterator BOOST_REGEX_CALL expression()const
{
return this->m_expression;
}
//
// begin, end:
const_iterator BOOST_REGEX_CALL begin()const
{
return (!this->m_status ? 0 : this->m_expression);
}
const_iterator BOOST_REGEX_CALL end()const
{
return (!this->m_status ? 0 : this->m_expression + this->m_expression_len);
}
flag_type BOOST_REGEX_CALL flags()const
{
return this->m_flags;
}
size_type BOOST_REGEX_CALL size()const
{
return this->m_expression_len;
}
int BOOST_REGEX_CALL status()const
{
return this->m_status;
}
size_type BOOST_REGEX_CALL mark_count()const
{
return this->m_mark_count;
}
const re_detail::re_syntax_base* get_first_state()const
{
return this->m_first_state;
}
unsigned get_restart_type()const
{
return this->m_restart_type;
}
const unsigned char* get_map()const
{
return this->m_startmap;
}
const traits& get_traits()const
{
return this->m_traits;
}
bool can_be_null()const
{
return this->m_can_be_null;
}
};
} // namespace re_detail
//
// class basic_regex:
// represents the compiled
// regular expression:
//
#ifdef BOOST_REGEX_NO_FWD
template <class charT, class traits = regex_traits<charT>, class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
template <class charT, class traits = regex_traits<charT> >
#else
template <class charT, class traits, class Allocator >
template <class charT, class traits >
#endif
class reg_expression : public regbase
class basic_regex : public regbase
{
public:
// typedefs:
typedef typename traits::size_type traits_size_type;
typedef typename traits::uchar_type traits_uchar_type;
typedef typename traits::string_type traits_string_type;
typedef charT char_type;
typedef traits traits_type;
@ -56,10 +182,8 @@ public:
typedef const charT& const_reference;
typedef const charT* const_iterator;
typedef const_iterator iterator;
typedef typename Allocator::difference_type difference_type;
typedef typename Allocator::size_type size_type;
typedef Allocator allocator_type;
typedef Allocator alloc_type;
typedef std::ptrdiff_t difference_type;
typedef std::size_t size_type;
typedef regex_constants::syntax_option_type flag_type;
// locale_type
// placeholder for actual locale type used by the
@ -67,321 +191,318 @@ public:
typedef typename traits::locale_type locale_type;
public:
explicit reg_expression(const Allocator& a = Allocator());
explicit reg_expression(const charT* p, flag_type f = regex_constants::normal, const Allocator& a = Allocator());
reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal, const Allocator& a = Allocator());
reg_expression(const charT* p, size_type len, flag_type f, const Allocator& a = Allocator());
reg_expression(const reg_expression&);
~reg_expression();
reg_expression& BOOST_REGEX_CALL operator=(const reg_expression&);
reg_expression& BOOST_REGEX_CALL operator=(const charT* ptr)
explicit basic_regex(){}
explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
{
set_expression(ptr, regex_constants::normal | regex_constants::use_except);
return *this;
assign(p, f);
}
basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
{
assign(p1, p2, f);
}
basic_regex(const charT* p, size_type len, flag_type f)
{
assign(p, len, f);
}
basic_regex(const basic_regex& that)
: m_pimpl(that.m_pimpl) {}
~basic_regex(){}
basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
{
return assign(that);
}
basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
{
return assign(ptr, regex_constants::normal);
}
//
// assign:
reg_expression& assign(const reg_expression& that)
{ return *this = that; }
reg_expression& assign(const charT* ptr, flag_type f = regex_constants::normal)
{
set_expression(ptr, f | regex_constants::use_except);
return *this;
basic_regex& assign(const basic_regex& that)
{
m_pimpl = that.m_pimpl;
return *this;
}
reg_expression& assign(const charT* ptr, size_type len, flag_type f)
basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
{
std::basic_string<charT> s(ptr, len);
set_expression(s.c_str(), f | regex_constants::use_except);
return *this;
return assign(p, p + traits::length(p), f);
}
basic_regex& assign(const charT* p, size_type len, flag_type f)
{
return assign(p, p + len, f);
}
reg_expression& assign(const charT* arg_first,
const charT* arg_last,
basic_regex& assign(const charT* p1,
const charT* p2,
flag_type f = regex_constants::normal)
{
set_expression(arg_first, arg_last, f | regex_constants::use_except);
cow();
m_pimpl->assign(p1, p2, f);
return *this;
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
template <class ST, class SA>
unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
{ return set_expression(p.data(), p.data() + p.size(), f); }
template <class ST, class SA>
explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
: data(a), pkmp(0), error_code_(REG_EMPTY), _expression(0) { set_expression(p, f | regex_constants::use_except); }
template <class InputIterator>
reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal, const Allocator& al = Allocator())
: data(al), pkmp(0), error_code_(REG_EMPTY), _expression(0)
{
std::basic_string<charT> a(arg_first, arg_last);
set_expression(a.data(), a.data() + a.size(), f | regex_constants::use_except);
{
return set_expression(p.data(), p.data() + p.size(), f);
}
template <class ST, class SA>
reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
{
set_expression(p.c_str(), p.c_str() + p.size(), regex_constants::normal | regex_constants::use_except);
return *this;
}
template <class string_traits, class A>
reg_expression& BOOST_REGEX_CALL assign(
const std::basic_string<charT, string_traits, A>& s,
flag_type f = regex_constants::normal)
{
set_expression(s.c_str(), s.c_str() + s.size(), f | regex_constants::use_except);
return *this;
explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
{
assign(p, f);
}
template <class InputIterator>
reg_expression& BOOST_REGEX_CALL assign(InputIterator arg_first,
InputIterator arg_last,
flag_type f = regex_constants::normal)
basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
{
std::basic_string<charT> a(arg_first, arg_last);
set_expression(a.data(), a.data() + a.size(), f | regex_constants::use_except);
return *this;
assign(a.data(), a.data() + a.size(), f);
}
#else
unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
{ return set_expression(p.data(), p.data() + p.size(), f | regex_constants::use_except); }
reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
: data(a), pkmp(0) { set_expression(p, f | regex_constants::use_except); }
reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
{
set_expression(p.c_str(), p.c_str() + p.size(), regex_constants::normal | regex_constants::use_except);
return *this;
}
reg_expression& BOOST_REGEX_CALL assign(
const std::basic_string<charT>& s,
flag_type f = regex_constants::normal)
{
set_expression(s.c_str(), s.c_str() + s.size(), f | regex_constants::use_except);
return *this;
}
#endif
//
// allocator access:
Allocator BOOST_REGEX_CALL get_allocator()const;
//
// locale:
locale_type BOOST_REGEX_CALL imbue(locale_type l){ return traits_inst.imbue(l); }
locale_type BOOST_REGEX_CALL getloc()const{ return traits_inst.getloc(); }
//
// getflags:
// retained for backwards compatibility only, the base class has "flags"
// member which is now the prefered name:
flag_type BOOST_REGEX_CALL getflags()const
{ return this->flags(); }
//
// str:
std::basic_string<charT> BOOST_REGEX_CALL str()const
{
std::basic_string<charT> result;
if(this->error_code() == 0)
result = std::basic_string<charT>(_expression, _expression_len);
return result;
}
//
// begin, end:
const_iterator BOOST_REGEX_CALL begin()const
{ return (this->error_code() ? 0 : _expression); }
const_iterator BOOST_REGEX_CALL end()const
{ return (this->error_code() ? 0 : _expression + _expression_len); }
//
// swap:
void BOOST_REGEX_CALL swap(reg_expression&)throw();
//
// size:
size_type BOOST_REGEX_CALL size()const
{ return (this->error_code() ? 0 : _expression_len); }
//
// max_size:
size_type BOOST_REGEX_CALL max_size()const
{ return UINT_MAX; }
//
// empty:
bool BOOST_REGEX_CALL empty()const
{ return 0 != this->error_code(); }
unsigned BOOST_REGEX_CALL mark_count()const { return (this->error_code() ? 0 : marks); }
int BOOST_REGEX_CALL compare(const reg_expression&) const;
bool BOOST_REGEX_CALL operator==(const reg_expression& e)const
{ return compare(e) == 0; }
bool operator != (const basic_regex<charT, traits, Allocator>& e)
{ return compare(e) != 0; }
bool BOOST_REGEX_CALL operator<(const reg_expression& e)const
{ return compare(e) < 0; }
bool BOOST_REGEX_CALL operator>(const reg_expression& e)const
{ return compare(e) > 0; }
bool BOOST_REGEX_CALL operator<=(const reg_expression& e)const
{ return compare(e) <= 0; }
bool BOOST_REGEX_CALL operator>=(const reg_expression& e)const
{ return compare(e) >= 0; }
//
// The following are deprecated as public interfaces
// but are available for compatibility with earlier versions.
allocator_type BOOST_REGEX_CALL allocator()const;
const charT* BOOST_REGEX_CALL expression()const { return (this->error_code() ? 0 : _expression); }
unsigned int BOOST_REGEX_CALL set_expression(const charT* p, const charT* end, flag_type f = regex_constants::normal);
unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal) { return set_expression(p, p + traits_type::length(p), f); }
//
// this should be private but template friends don't work:
const traits_type& get_traits()const { return traits_inst; }
unsigned int BOOST_REGEX_CALL error_code()const
{
return error_code_;
}
private:
traits_type traits_inst; // traits class in use
re_detail::raw_storage<Allocator> data; // our state machine
unsigned _restart_type; // search method to use
unsigned marks; // number of marked sub-expressions
int repeats; // number of repeats
unsigned char* startmap; // characters that can match the first state(s) in the machine
std::size_t _expression_len; // length of the expression
std::size_t _leading_len; // length of any leading literal
const charT* _leading_string; // leading literal string
std::size_t _leading_string_len; // and it's length
re_detail::kmp_info<charT>* pkmp; // pointer to Knuth Morris Pratt state machine when available
unsigned error_code_; // our current status
charT* _expression; // the expression we just compiled if any
void BOOST_REGEX_CALL compile_maps();
void BOOST_REGEX_CALL compile_map(re_detail::re_syntax_base* node, unsigned char* _map, unsigned int* pnull, unsigned char mask, re_detail::re_syntax_base* terminal = 0)const;
bool BOOST_REGEX_CALL probe_start(re_detail::re_syntax_base* node, charT c, re_detail::re_syntax_base* terminal)const;
bool BOOST_REGEX_CALL probe_start_null(re_detail::re_syntax_base* node, re_detail::re_syntax_base* terminal)const;
void BOOST_REGEX_CALL fixup_apply(re_detail::re_syntax_base* b, unsigned cbraces);
void BOOST_REGEX_CALL move_offsets(re_detail::re_syntax_base* j, unsigned size);
re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set(const charT*& first, const charT* last);
re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set_aux(re_detail::jstack<traits_string_type, Allocator>& singles, re_detail::jstack<traits_string_type, Allocator>& ranges, re_detail::jstack<boost::uint_fast32_t, Allocator>& classes, re_detail::jstack<traits_string_type, Allocator>& equivalents, bool isnot, const re_detail::_narrow_type&);
re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set_aux(re_detail::jstack<traits_string_type, Allocator>& singles, re_detail::jstack<traits_string_type, Allocator>& ranges, re_detail::jstack<boost::uint_fast32_t, Allocator>& classes, re_detail::jstack<traits_string_type, Allocator>& equivalents, bool isnot, const re_detail::_wide_type&);
re_detail::re_syntax_base* BOOST_REGEX_CALL compile_set_simple(re_detail::re_syntax_base* dat, unsigned long cls, bool isnot = false);
unsigned int BOOST_REGEX_CALL parse_inner_set(const charT*& first, const charT* last);
re_detail::re_syntax_base* BOOST_REGEX_CALL add_simple(re_detail::re_syntax_base* dat, re_detail::syntax_element_type type, unsigned int size = sizeof(re_detail::re_syntax_base));
re_detail::re_syntax_base* BOOST_REGEX_CALL add_literal(re_detail::re_syntax_base* dat, charT c);
charT BOOST_REGEX_CALL parse_escape(const charT*& first, const charT* last);
void BOOST_REGEX_CALL parse_range(const charT*& first, const charT* last, unsigned& min, unsigned& max);
bool BOOST_REGEX_CALL skip_space(const charT*& first, const charT* last);
unsigned int BOOST_REGEX_CALL probe_restart(re_detail::re_syntax_base* dat);
unsigned int BOOST_REGEX_CALL fixup_leading_rep(re_detail::re_syntax_base* dat, re_detail::re_syntax_base* end);
void BOOST_REGEX_CALL fail(unsigned int err);
protected:
static int BOOST_REGEX_CALL repeat_count(const reg_expression& e)
{ return e.repeats; }
static unsigned int BOOST_REGEX_CALL restart_type(const reg_expression& e)
{ return e._restart_type; }
static const re_detail::re_syntax_base* BOOST_REGEX_CALL first(const reg_expression& e)
{ return (const re_detail::re_syntax_base*)e.data.data(); }
static const unsigned char* BOOST_REGEX_CALL get_map(const reg_expression& e)
{ return e.startmap; }
static std::size_t BOOST_REGEX_CALL leading_length(const reg_expression& e)
{ return e._leading_len; }
static const re_detail::kmp_info<charT>* get_kmp(const reg_expression& e)
{ return e.pkmp; }
static bool BOOST_REGEX_CALL can_start(charT c, const unsigned char* _map, unsigned char mask, const re_detail::_wide_type&);
static bool BOOST_REGEX_CALL can_start(charT c, const unsigned char* _map, unsigned char mask, const re_detail::_narrow_type&);
};
template <class charT, class traits, class Allocator >
void swap(reg_expression<charT, traits, Allocator>& a, reg_expression<charT, traits, Allocator>& b)
{
a.swap(b);
}
#ifndef BOOST_NO_STD_LOCALE
template <class charT, class traits, class traits2, class Allocator>
std::basic_ostream<charT, traits>&
operator << (std::basic_ostream<charT, traits>& os,
const reg_expression<charT, traits2, Allocator>& e)
{
return (os << e.str());
}
#else
template <class traits, class Allocator>
std::ostream& operator << (std::ostream& os, const reg_expression<char, traits, Allocator>& e)
{
return (os << e.str());
}
#endif
//
// We want to rename reg_expression basic_regex but maintain
// backwards compatibility, so class basic_regex is just a thin
// wrapper around reg_expression:
//
#ifdef BOOST_REGEX_NO_FWD
template <class charT, class traits = regex_traits<charT>, class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
#else
template <class charT, class traits, class Allocator >
#endif
class basic_regex : public reg_expression<charT, traits, Allocator>
{
public:
typedef typename reg_expression<charT, traits, Allocator>::flag_type flag_type;
typedef typename reg_expression<charT, traits, Allocator>::size_type size_type;
explicit basic_regex(const Allocator& a = Allocator())
: reg_expression<charT, traits, Allocator>(a){}
explicit basic_regex(const charT* p, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
: reg_expression<charT, traits, Allocator>(p,f,a){}
basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
: reg_expression<charT, traits, Allocator>(p1,p2,f,a){}
basic_regex(const charT* p, size_type len, flag_type f, const Allocator& a = Allocator())
: reg_expression<charT, traits, Allocator>(p,len,f,a){}
basic_regex(const basic_regex& that)
: reg_expression<charT, traits, Allocator>(that){}
~basic_regex(){}
basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
{
this->assign(that);
return *this;
}
basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
{
this->assign(ptr);
return *this;
}
#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !(defined(__IBMCPP__) && (__IBMCPP__ <= 502))
template <class ST, class SA>
explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
: reg_expression<charT, traits, Allocator>(p,f,a){}
template <class I>
basic_regex(I arg_first, I arg_last, flag_type f = regex_constants::normal, const Allocator& al = Allocator())
: reg_expression<charT, traits, Allocator>(arg_first, arg_last, f, al){}
template <class ST, class SA>
basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
{
this->assign(p);
return *this;
return assign(p.data(), p.data() + p.size(), regex_constants::normal);
}
template <class string_traits, class A>
basic_regex& BOOST_REGEX_CALL assign(
const std::basic_string<charT, string_traits, A>& s,
flag_type f = regex_constants::normal)
{
return assign(s.data(), s.data() + s.size(), f);
}
template <class InputIterator>
basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,
InputIterator arg_last,
flag_type f = regex_constants::normal)
{
std::basic_string<charT> a(arg_first, arg_last);
return assign(a.data(), a.data() + a.size(), f);
}
#else
basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal, const Allocator& a = Allocator())
: reg_expression<charT, traits, Allocator>(p,f,a){}
unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
{
return set_expression(p.data(), p.data() + p.size(), f);
}
basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
{
assign(p, f);
}
basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
{
this->assign(p);
return *this;
return assign(p.data(), p.data() + p.size(), regex_constants::normal);
}
basic_regex& BOOST_REGEX_CALL assign(
const std::basic_string<charT>& s,
flag_type f = regex_constants::normal)
{
return assign(s.data(), s.data() + s.size(), f);
}
#endif
//
// locale:
locale_type BOOST_REGEX_CALL imbue(locale_type l)
{
cow();
return m_pimpl->imbue(l);
}
locale_type BOOST_REGEX_CALL getloc()const
{
return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
}
//
// getflags:
// retained for backwards compatibility only, "flags"
// is now the prefered name:
flag_type BOOST_REGEX_CALL getflags()const
{
return flags();
}
flag_type BOOST_REGEX_CALL flags()const
{
return m_pimpl.get() ? m_pimpl->flags() : 0;
}
//
// str:
std::basic_string<charT> BOOST_REGEX_CALL str()const
{
return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
}
//
// begin, end:
const_iterator BOOST_REGEX_CALL begin()const
{
return (m_pimpl.get() ? m_pimpl->begin() : 0);
}
const_iterator BOOST_REGEX_CALL end()const
{
return (m_pimpl.get() ? m_pimpl->end() : 0);
}
//
// swap:
void BOOST_REGEX_CALL swap(basic_regex& that)throw()
{
m_pimpl.swap(that.m_pimpl);
}
//
// size:
size_type BOOST_REGEX_CALL size()const
{
return (m_pimpl.get() ? m_pimpl->size() : 0);
}
//
// max_size:
size_type BOOST_REGEX_CALL max_size()const
{
return UINT_MAX;
}
//
// empty:
bool BOOST_REGEX_CALL empty()const
{
return (m_pimpl.get() ? 0 != m_pimpl->status() : 0);
}
size_type BOOST_REGEX_CALL mark_count()const
{
return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
}
int status()const
{
return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
}
int BOOST_REGEX_CALL compare(const basic_regex& that) const
{
if(m_pimpl.get() == that.m_pimpl.get())
return 0;
if(!m_pimpl.get())
return -1;
if(!that.m_pimpl.get())
return 1;
if(status() != that.status())
return status() - that.status();
if(flags() != that.flags())
return flags() - that.flags();
return str().compare(that.str());
}
bool BOOST_REGEX_CALL operator==(const basic_regex& e)const
{
return compare(e) == 0;
}
bool operator != (const basic_regex& e)
{
return compare(e) != 0;
}
bool BOOST_REGEX_CALL operator<(const basic_regex& e)const
{
return compare(e) < 0;
}
bool BOOST_REGEX_CALL operator>(const basic_regex& e)const
{
return compare(e) > 0;
}
bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const
{
return compare(e) <= 0;
}
bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const
{
return compare(e) >= 0;
}
//
// The following are deprecated as public interfaces
// but are available for compatibility with earlier versions.
const charT* BOOST_REGEX_CALL expression()const
{
return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
}
unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
{
assign(p1, p2, f | regex_constants::no_except);
return status();
}
unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)
{
assign(p, f | regex_constants::no_except);
return status();
}
unsigned int BOOST_REGEX_CALL error_code()const
{
return status();
}
//
// private access methods:
//
const re_detail::re_syntax_base* get_first_state()const
{
assert(m_pimpl.get());
return m_pimpl->get_first_state();
}
unsigned get_restart_type()const
{
assert(m_pimpl.get());
return m_pimpl->get_restart_type();
}
const unsigned char* get_map()const
{
assert(m_pimpl.get());
return m_pimpl->get_map();
}
const traits& get_traits()const
{
assert(m_pimpl.get());
return m_pimpl->get_traits();
}
bool can_be_null()const
{
assert(m_pimpl.get());
return m_pimpl->can_be_null();
}
private:
shared_ptr<re_detail::basic_regex_implementation<charT, traits> > m_pimpl;
void cow()
{
// copy-on-write
if(!m_pimpl.get())
{
m_pimpl = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
}
else if(!m_pimpl.unique())
{
m_pimpl = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->get_traits()));
}
}
};
#ifndef BOOST_NO_STD_LOCALE
template <class charT, class traits, class traits2>
std::basic_ostream<charT, traits>&
operator << (std::basic_ostream<charT, traits>& os,
const basic_regex<charT, traits2>& e)
{
return (os << e.str());
}
#else
template <class traits>
std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
{
return (os << e.str());
}
#endif
#ifdef BOOST_MSVC
#pragma warning (pop)
#endif

View File

@ -0,0 +1,435 @@
/*
*
* 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 basic_regex_creator.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares template class basic_regex_creator which fills in
* the data members of a regex_data object.
*/
#ifndef BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
#define BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost{
namespace re_detail{
template <class charT, class traits>
class basic_regex_creator
{
public:
basic_regex_creator(regex_data<charT, traits>* data);
std::ptrdiff_t getoffset(void* addr)
{
return getoffset(addr, m_pdata->m_data.data());
}
std::ptrdiff_t getoffset(void* addr, void* base)
{
return static_cast<const char*>(addr) - static_cast<const char*>(base);
}
re_syntax_base* getaddress(std::ptrdiff_t off)
{
return getaddress(off, m_pdata->m_data.data());
}
re_syntax_base* getaddress(std::ptrdiff_t off, void* base)
{
return static_cast<re_syntax_base*>(static_cast<void*>(static_cast<char*>(base) + off));
}
void init(unsigned flags)
{
m_pdata->m_flags = flags;
m_icase = flags & regex_constants::icase;
}
re_syntax_base* append_state(syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
re_syntax_base* insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s = sizeof(re_syntax_base));
re_literal* append_literal(charT c);
void finalize(const charT* p1, const charT* p2);
protected:
regex_data<charT, traits>* m_pdata; // pointer to the basic_regex_data struct we are filling in
const traits& m_traits; // convenience reference to traits class
re_syntax_base* m_last_state;// the last state we added
bool m_icase; // true for case insensitive matches
typename traits::char_class_type m_word_mask; // mask used to determine if a character is a word character
private:
basic_regex_creator& operator=(const basic_regex_creator&);
basic_regex_creator(const basic_regex_creator&);
void fixup_pointers(re_syntax_base* state);
void create_startmaps(re_syntax_base* state);
void create_startmap(re_syntax_base* state, unsigned char* map, unsigned int* pnull, unsigned char mask, re_syntax_base* terminal);
unsigned get_restart_type(re_syntax_base* state);
};
template <class charT, class traits>
basic_regex_creator<charT, traits>::basic_regex_creator(regex_data<charT, traits>* data)
: m_pdata(data), m_traits(data->m_traits), m_last_state(0)
{
m_pdata->m_data.clear();
static const charT w = 'w';
m_word_mask = m_traits.lookup_classname(&w, &w +1);
//BOOST_ASSERT(m_word_mask); // TODO!!
}
template <class charT, class traits>
re_syntax_base* basic_regex_creator<charT, traits>::append_state(syntax_element_type t, std::size_t s)
{
// append a new state, start by aligning our last one:
m_pdata->m_data.align();
// set the offset to the next state in our last one:
if(m_last_state)
m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
// now actually extent our data:
m_last_state = static_cast<re_syntax_base*>(m_pdata->m_data.extend(s));
// fill in boilerplate options in the new state:
m_last_state->next.i = 0;
m_last_state->type = t;
return m_last_state;
}
template <class charT, class traits>
re_syntax_base* basic_regex_creator<charT, traits>::insert_state(std::ptrdiff_t pos, syntax_element_type t, std::size_t s)
{
// append a new state, start by aligning our last one:
m_pdata->m_data.align();
// set the offset to the next state in our last one:
if(m_last_state)
m_last_state->next.i = m_pdata->m_data.size() - getoffset(m_last_state);
// remember the last state position:
std::ptrdiff_t off = getoffset(m_last_state) + s;
// now actually insert our data:
re_syntax_base* new_state = static_cast<re_syntax_base*>(m_pdata->m_data.insert(pos, s));
// fill in boilerplate options in the new state:
new_state->next.i = s;
new_state->type = t;
m_last_state = getaddress(off);
return new_state;
}
template <class charT, class traits>
re_literal* basic_regex_creator<charT, traits>::append_literal(charT c)
{
re_literal* result;
// start by seeing if we have an existing re_literal we can extend:
if((0 == m_last_state) || (m_last_state->type != syntax_element_literal))
{
// no existing re_literal, create a new one:
result = static_cast<re_literal*>(append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
result->length = 1;
*static_cast<charT*>(static_cast<void*>(result+1)) = m_traits.translate(c, m_icase);
}
else
{
// we have an existing re_literal, extend it:
std::ptrdiff_t off = getoffset(m_last_state);
m_pdata->m_data.extend(sizeof(charT));
m_last_state = result = static_cast<re_literal*>(getaddress(off));
charT* characters = static_cast<charT*>(static_cast<void*>(result+1));
characters[result->length] = m_traits.translate(c, m_icase);
++(result->length);
}
return result;
}
template <class charT, class traits>
void basic_regex_creator<charT, traits>::finalize(const charT* p1, const charT* p2)
{
// we've added all the states we need, now finish things off.
// start by adding a terminating state:
append_state(syntax_element_match);
// extend storage to store original expression:
std::ptrdiff_t len = p2 - p1;
m_pdata->m_expression_len = len;
charT* ps = static_cast<charT*>(m_pdata->m_data.extend(sizeof(charT) * (1 + (p2 - p1))));
m_pdata->m_expression = ps;
std::copy(p1, p2, ps);
ps[p2 - p1] = 0;
// fill in our other data...
// successful parsing implies a zero status:
m_pdata->m_status = 0;
// get the first state of the machine:
m_pdata->m_first_state = static_cast<re_syntax_base*>(m_pdata->m_data.data());
// fixup pointers in the machine:
fixup_pointers(m_pdata->m_first_state);
// create nested startmaps:
create_startmaps(m_pdata->m_first_state);
// create main startmap:
std::memset(m_pdata->m_startmap, 0, sizeof(m_pdata->m_startmap));
m_pdata->m_can_be_null = 0;
create_startmap(m_pdata->m_first_state, m_pdata->m_startmap, &(m_pdata->m_can_be_null), mask_all, 0);
// get the restart type:
m_pdata->m_restart_type = get_restart_type(m_pdata->m_first_state);
}
template <class charT, class traits>
void basic_regex_creator<charT, traits>::fixup_pointers(re_syntax_base* state)
{
while(state)
{
switch(state->type)
{
case syntax_element_alt:
case syntax_element_rep:
case syntax_element_dot_rep:
case syntax_element_char_rep:
case syntax_element_short_set_rep:
case syntax_element_long_set_rep:
std::memset(static_cast<re_alt*>(state)->_map, 0, sizeof(static_cast<re_alt*>(state)->_map));
static_cast<re_alt*>(state)->can_be_null = 0;
// fall through:
case syntax_element_jump:
static_cast<re_jump*>(state)->alt.p = getaddress(static_cast<re_jump*>(state)->alt.i, state);
// fall through again:
default:
if(state->next.i)
state->next.p = getaddress(state->next.i, state);
else
state->next.p = 0;
}
state = state->next.p;
}
}
template <class charT, class traits>
void basic_regex_creator<charT, traits>::create_startmaps(re_syntax_base* state)
{
// recursive implementation:
// create the last map in the machine first, so that earlier maps
// can make use of the result...
while(state)
{
switch(state->type)
{
case syntax_element_alt:
case syntax_element_rep:
case syntax_element_dot_rep:
case syntax_element_char_rep:
case syntax_element_short_set_rep:
case syntax_element_long_set_rep:
// create other startmaps *first*, since we can use the
// results from these when creating out own:
create_startmaps(state->next.p);
create_startmap(state->next.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_take, state);
create_startmap(static_cast<re_alt*>(state)->alt.p, static_cast<re_alt*>(state)->_map, &static_cast<re_alt*>(state)->can_be_null, mask_skip, state);
return;
default:
state = state->next.p;
}
}
}
template <class charT, class traits>
void basic_regex_creator<charT, traits>::create_startmap(re_syntax_base* state, unsigned char* map, unsigned int* pnull, unsigned char mask, re_syntax_base* terminal)
{
while(state && (state != terminal))
{
switch(state->type)
{
case syntax_element_literal:
{
// don't set anything in *pnull, set each element in map
// that could match the first character in the literal:
if(map)
{
map[0] |= mask_init;
charT first_char = *static_cast<charT*>(static_cast<void*>(static_cast<re_literal*>(state) + 1));
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
if(m_traits.translate(static_cast<charT>(i), m_icase) == first_char)
map[i] |= mask;
}
}
return;
}
case syntax_element_end_line:
{
// next character must be a line separator (if there is one):
if(map)
{
map[0] |= mask_init;
map['\n'] |= mask;
map['\r'] |= mask;
}
// now figure out if we can match a NULL string at this point:
if(pnull)
create_startmap(state->next.p, 0, pnull, mask, terminal);
return;
}
case syntax_element_backref:
case syntax_element_wild:
{
// can't be null, any character can match:
if(map)
{
map[0] |= mask_init;
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
map[i] |= mask;
}
}
return;
}
case syntax_element_match:
{
// must be null, any character can match:
if(map)
{
map[0] |= mask_init;
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
map[i] |= mask;
}
}
if(pnull)
*pnull |= mask;
return;
}
case syntax_element_word_start:
{
// recurse, then AND with all the word characters:
create_startmap(state->next.p, map, pnull, mask, terminal);
if(map)
{
map[0] |= mask_init;
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
if(!m_traits.is_class(static_cast<charT>(i), m_word_mask))
map[i] &= ~mask;
}
}
return;
}
case syntax_element_word_end:
{
// recurse, then AND with all the word characters:
create_startmap(state->next.p, map, pnull, mask, terminal);
if(map)
{
map[0] |= mask_init;
for(unsigned int i = 0; i < (1u << CHAR_BIT); ++i)
{
if(m_traits.is_class(static_cast<charT>(i), m_word_mask))
map[i] &= ~mask;
}
}
return;
}
case syntax_element_buffer_end:
{
// we *must be null* :
if(pnull)
*pnull |= mask;
return;
}
case syntax_element_long_set:
assert(0);
case syntax_element_set:
assert(0);
case syntax_element_jump:
// take the jump:
state = static_cast<re_alt*>(state)->alt.p;
break;;
case syntax_element_alt:
assert(0);
case syntax_element_rep:
case syntax_element_dot_rep:
case syntax_element_char_rep:
case syntax_element_short_set_rep:
case syntax_element_long_set_rep:
{
re_alt* rep = static_cast<re_repeat*>(state);
if(rep->_map[0] & mask_init)
{
if(map)
{
// copy previous results:
for(unsigned int i = 0; i <= UCHAR_MAX; ++i)
{
if(rep->_map[i] & mask_any)
map[i] |= mask;
}
}
if(pnull)
{
if(rep->can_be_null & mask_any)
*pnull |= mask;
}
}
else
{
// we haven't created a startmap for this alternative yet
// so take the union of the two options:
create_startmap(state->next.p, map, pnull, mask, state);
create_startmap(rep->alt.p, map, pnull, mask, state);
}
}
return;
case syntax_element_soft_buffer_end:
// match newline or null:
if(map)
{
map[0] |= mask_init;
map['\n'] |= mask;
map['\r'] |= mask;
}
if(pnull)
*pnull |= mask;
return;
default:
state = state->next.p;
}
}
}
template <class charT, class traits>
unsigned basic_regex_creator<charT, traits>::get_restart_type(re_syntax_base* state)
{
//
// find out how the machine starts, so we can optimise the search:
//
while(state)
{
switch(state->type)
{
case syntax_element_startmark:
case syntax_element_endmark:
state = state->next.p;
continue;
case syntax_element_start_line:
return regbase::restart_line;
case syntax_element_word_boundary:
case syntax_element_word_start:
return regbase::restart_line;
case syntax_element_buffer_start:
return regbase::restart_continue;
default:
state = 0;
continue;
}
}
return regbase::restart_any;
}
} // namespace re_detail
} // namespace boost
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif

View File

@ -0,0 +1,377 @@
/*
*
* 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 basic_regex_parser.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares template class basic_regex_parser.
*/
#ifndef BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
#define BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost{
namespace re_detail{
template <class charT, class traits>
class basic_regex_parser : public basic_regex_creator<charT, traits>
{
public:
basic_regex_parser(regex_data<charT, traits>* data);
void parse(const charT* p1, const charT* p2, unsigned flags);
void fail(regex_constants::error_type error_code, std::ptrdiff_t position);
bool parse_all();
bool parse_basic();
bool parse_extended();
bool parse_literal();
bool parse_open_paren();
bool parse_basic_escape();
bool parse_extended_escape();
bool parse_match_any();
bool parse_repeat(std::size_t low = 0, std::size_t high = (std::numeric_limits<std::size_t>::max)());
private:
typedef bool (basic_regex_parser::*parser_proc_type)();
parser_proc_type m_parser_proc; // the main parser to use
const charT* m_base; // the start of the string being parsed
const charT* m_end; // the end of the string being parsed
const charT* m_position; // our current parser position
unsigned m_mark_count; // how many sub-expressions we have
std::ptrdiff_t m_paren_start; // where the last seen ')' began (where repeats are inserted).
unsigned m_repeater_id; // the id of the next repeater
basic_regex_parser& operator=(const basic_regex_parser&);
basic_regex_parser(const basic_regex_parser&);
};
template <class charT, class traits>
basic_regex_parser<charT, traits>::basic_regex_parser(regex_data<charT, traits>* data)
: basic_regex_creator<charT, traits>(data), m_mark_count(0), m_paren_start(0), m_repeater_id(0)
{
}
template <class charT, class traits>
void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2, unsigned flags)
{
// empty strings are errors:
if(p1 == p2)
fail(REG_EMPTY, 0);
// pass flags on to base class:
this->init(flags);
// set up pointers:
m_position = m_base = p1;
m_end = p2;
// select which parser to use:
switch(flags & regbase::main_option_type)
{
case regbase::perl_syntax_group:
m_parser_proc = &basic_regex_parser<charT, traits>::parse_extended;
break;
case regbase::basic_syntax_group:
m_parser_proc = &basic_regex_parser<charT, traits>::parse_basic;
break;
case regbase::literal:
m_parser_proc = &basic_regex_parser<charT, traits>::parse_literal;
break;
}
// parse all our characters:
bool result = parse_all();
// if we haven't gobbled up all the characters then we must
// have had an unexpected ')' :
if(!result)
fail(regex_constants::error_paren, std::distance(m_base, m_position));
// fill in our sub-expression count:
this->m_pdata->m_mark_count = 1 + m_mark_count;
this->finalize(p1, p2);
}
template <class charT, class traits>
void basic_regex_parser<charT, traits>::fail(regex_constants::error_type error_code, std::ptrdiff_t position)
{
std::string message = this->m_pdata->m_traits.error_string(error_code);
boost::bad_expression e(message, error_code, position);
boost::throw_exception(e);
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_all()
{
bool result = true;
while(result && (m_position != m_end))
{
result = (this->*m_parser_proc)();
}
return result;
}
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4702)
#endif
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_basic()
{
switch(this->m_traits.syntax_type(*m_position))
{
case regex_constants::syntax_escape:
return parse_basic_escape();
case regex_constants::syntax_dot:
return parse_match_any();
case regex_constants::syntax_caret:
++m_position;
this->append_state(syntax_element_start_line);
break;
case regex_constants::syntax_dollar:
++m_position;
this->append_state(syntax_element_end_line);
break;
case regex_constants::syntax_star:
if(!(this->m_last_state) || (this->m_last_state->type == syntax_element_start_line))
return parse_literal();
else
{
++m_position;
return parse_repeat();
}
default:
return parse_literal();
}
return true;
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_extended()
{
switch(this->m_traits.syntax_type(*m_position))
{
case regex_constants::syntax_open_mark:
return parse_open_paren();
case regex_constants::syntax_close_mark:
return false;
case regex_constants::syntax_escape:
return parse_extended_escape();
case regex_constants::syntax_dot:
return parse_match_any();
case regex_constants::syntax_caret:
++m_position;
this->append_state(syntax_element_start_line);
break;
case regex_constants::syntax_dollar:
++m_position;
this->append_state(syntax_element_end_line);
break;
case regex_constants::syntax_star:
if(m_position == this->m_base)
fail(REG_BADRPT, 0);
++m_position;
return parse_repeat();
case regex_constants::syntax_question:
if(m_position == this->m_base)
fail(REG_BADRPT, 0);
++m_position;
return parse_repeat(0,1);
case regex_constants::syntax_plus:
if(m_position == this->m_base)
fail(REG_BADRPT, 0);
++m_position;
return parse_repeat(1);
default:
return parse_literal();
}
return true;
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_literal()
{
this->append_literal(*m_position);
++m_position;
return true;
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_open_paren()
{
//
// update our mark count, and append the required state:
//
unsigned markid = ++m_mark_count;
re_brace* pb = static_cast<re_brace*>(this->append_state(syntax_element_startmark, sizeof(re_brace)));
pb->index = markid;
++m_position;
std::ptrdiff_t last_paren_start = this->getoffset(pb);
//
// now recursively add more states, this will terminate when we get to a
// matching ')' :
//
parse_all();
//
// we either have a ')' or we have run out of characters prematurely:
//
if(m_position == m_end)
this->fail(REG_EPAREN, std::distance(m_base, m_end));
BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
++m_position;
//
// append closing parenthesis state:
//
pb = static_cast<re_brace*>(this->append_state(syntax_element_endmark, sizeof(re_brace)));
pb->index = markid;
this->m_paren_start = last_paren_start;
return true;
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_basic_escape()
{
++m_position;
switch(this->m_traits.escape_syntax_type(*m_position))
{
case regex_constants::syntax_open_mark:
return parse_open_paren();
case regex_constants::syntax_close_mark:
return false;
default:
return parse_literal();
}
return true;
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_extended_escape()
{
++m_position;
switch(this->m_traits.escape_syntax_type(*m_position))
{
case regex_constants::escape_type_left_word:
++m_position;
this->append_state(syntax_element_word_start);
break;
case regex_constants::escape_type_right_word:
++m_position;
this->append_state(syntax_element_word_end);
break;
default:
return parse_literal();
}
return true;
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_match_any()
{
//
// we have a '.' that can match any character:
//
++m_position;
this->append_state(syntax_element_wild);
return true;
}
template <class charT, class traits>
bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_t high)
{
bool greedy = true;
std::size_t insert_point;
//
// when we get to here we may have a non-greedy ? mark still to come:
//
if((m_position != m_end)
&& (0 == (this->m_pdata->m_flags & (regbase::main_option_type | regbase::no_perl_ex))))
{
// OK we have a perl regex, check for a '?':
if(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_question)
{
greedy = false;
++m_position;
}
}
if(this->m_last_state->type == syntax_element_endmark)
{
// insert a repeat before the '(' matching the last ')':
insert_point = this->m_paren_start;
}
else if((this->m_last_state->type == syntax_element_literal) && (static_cast<re_literal*>(this->m_last_state)->length > 1))
{
// the last state was a literal with more than one character, split it in two:
re_literal* lit = static_cast<re_literal*>(this->m_last_state);
charT c = (static_cast<charT*>(static_cast<void*>(lit+1)))[lit->length - 1];
--(lit->length);
// now append new state:
lit = static_cast<re_literal*>(this->append_state(syntax_element_literal, sizeof(re_literal) + sizeof(charT)));
lit->length = 1;
(static_cast<charT*>(static_cast<void*>(lit+1)))[0] = c;
insert_point = this->getoffset(this->m_last_state);
}
else
{
// repeat the last state whatever it was, need to add some error checking here:
switch(this->m_last_state->type)
{
case syntax_element_start_line:
case syntax_element_end_line:
case syntax_element_word_boundary:
case syntax_element_within_word:
case syntax_element_word_start:
case syntax_element_word_end:
case syntax_element_buffer_start:
case syntax_element_buffer_end:
case syntax_element_alt:
case syntax_element_soft_buffer_end:
case syntax_element_restart_continue:
// can't legally repeat any of the above:
fail(REG_BADRPT, m_position - m_base);
default:
// do nothing...
break;
}
insert_point = this->getoffset(this->m_last_state);
}
//
// OK we now know what to repeat, so insert the repeat around it:
//
re_repeat* rep = static_cast<re_repeat*>(this->insert_state(insert_point, syntax_element_rep, re_repeater_size));
rep->min = low;
rep->max = high;
rep->greedy = greedy;
rep->leading = false;
rep->id = m_repeater_id++;
// store our repeater position for later:
std::ptrdiff_t rep_off = this->getoffset(rep);
// and append a back jump to the repeat:
re_jump* jmp = static_cast<re_jump*>(this->append_state(syntax_element_jump, sizeof(re_jump)));
jmp->alt.i = rep_off - this->getoffset(jmp);
this->m_pdata->m_data.align();
// now fill in the alt jump for the repeat:
rep = static_cast<re_repeat*>(this->getaddress(rep_off));
rep->alt.i = this->m_pdata->m_data.size() - rep_off;
return true;
}
} // namespace re_detail
} // namespace boost
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif

View File

@ -42,10 +42,6 @@ public:
typedef unsigned int size_type;
typedef regex_traits<char> base_type;
char BOOST_REGEX_CALL translate(char c, bool)const
{
return static_cast<const regex_traits<char>*>(this)->translate(c, true);
}
};
#ifndef BOOST_NO_WREGEX
@ -58,17 +54,6 @@ public:
typedef unsigned int size_type;
typedef regex_traits<wchar_t> base_type;
wchar_t BOOST_REGEX_CALL translate(wchar_t c, bool)const
{
return static_cast<const regex_traits<wchar_t>*>(this)->translate(c, true);
}
boost::uint_fast32_t BOOST_REGEX_CALL lookup_classname(const wchar_t* first, const wchar_t* last)const
{
boost::uint_fast32_t result = static_cast<const regex_traits<wchar_t>*>(this)->lookup_classname(first, last);
if((result & base_type::char_class_upper) == base_type::char_class_upper)
result |= base_type::char_class_alpha;
return result;
}
};
#endif
} // namespace deprecated

View File

@ -0,0 +1,399 @@
/*
*
* 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 cpp_regex_traits.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression traits class cpp_regex_traits.
*/
#ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
#define BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
#include <boost/regex/v4/regex_traits_defaults.hpp>
#endif
#ifdef BOOST_HAS_THREADS
#include <boost/regex/static_mutex.hpp>
#endif
namespace boost{
//
// forward declaration is needed by some compilers:
//
template <class charT>
class cpp_regex_traits;
namespace re_detail{
//
// class cpp_regex_traits_base:
// acts as a container for locale and the facets we are using.
//
template <class charT>
struct cpp_regex_traits_base
{
cpp_regex_traits_base(const std::locale& l)
{ imbue(l); }
std::locale imbue(const std::locale& l);
std::locale m_locale;
std::ctype<charT> const* m_pctype;
std::messages<charT> const* m_pmessages;
std::collate<charT> const* m_pcollate;
};
template <class charT>
std::locale cpp_regex_traits_base<charT>::imbue(const std::locale& l)
{
std::locale result(m_locale);
m_locale = l;
m_pctype = &BOOST_USE_FACET(std::ctype<charT>, l);
m_pmessages = &BOOST_USE_FACET(std::messages<charT>, l);
m_pcollate = &BOOST_USE_FACET(std::collate<charT>, l);
return result;
}
//
// class cpp_regex_traits_char_layer:
// implements methods that require specialisation for narrow characters:
//
template <class charT>
class cpp_regex_traits_char_layer : public cpp_regex_traits_base<charT>
{
typedef std::basic_string<charT> string_type;
typedef std::map<charT, regex_constants::syntax_type> map_type;
typedef typename map_type::const_iterator map_iterator_type;
public:
cpp_regex_traits_char_layer(const std::locale& l);
regex_constants::syntax_type syntax_type(charT c)const
{
map_iterator_type i = m_char_map.find(c);
return ((i == m_char_map.end()) ? 0 : i->second);
}
regex_constants::escape_syntax_type escape_syntax_type(charT c) const
{
map_iterator_type i = m_char_map.find(c);
if(i == m_char_map.end())
{
if(this->m_pctype->is(std::ctype_base::lower, c)) return regex_constants::escape_type_class;
if(this->m_pctype->is(std::ctype_base::upper, c)) return regex_constants::escape_type_not_class;
return 0;
}
return i->second;
}
private:
string_type get_default_message(regex_constants::syntax_type);
// TODO: use a hash table when available!
map_type m_char_map;
};
template <class charT>
cpp_regex_traits_char_layer<charT>::cpp_regex_traits_char_layer(const std::locale& l)
: cpp_regex_traits_base<charT>(l)
{
// we need to start by initialising our syntax map so we know which
// character is used for which purpose:
#ifndef __IBMCPP__
typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
#else
typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
if(cat_name.size())
{
cat = this->m_pmessages->open(
cat_name,
this->m_locale);
if((int)cat < 0)
{
std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name);
boost::throw_exception(err);
}
}
//
// if we have a valid catalog then load our messages:
//
if((int)cat >= 0)
{
try{
for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
{
string_type mss = this->m_pmessages->get(cat, 0, i, get_default_message(i));
for(typename string_type::size_type j = 0; j < mss.size(); ++j)
{
m_char_map[mss[j]] = i;
}
}
this->m_pmessages->close(cat);
}
catch(...)
{
this->m_pmessages->close(cat);
throw;
}
}
else
{
for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
{
const char* ptr = get_default_syntax(i);
while(ptr && *ptr)
{
m_char_map[this->m_pctype->widen(*ptr)] = i;
++ptr;
}
}
}
}
template <class charT>
typename cpp_regex_traits_char_layer<charT>::string_type
cpp_regex_traits_char_layer<charT>::get_default_message(regex_constants::syntax_type i)
{
const char* ptr = get_default_syntax(i);
string_type result;
while(ptr && *ptr)
{
result.append(1, this->m_pctype->widen(*ptr));
++ptr;
}
return result;
}
//
// specialised version for narrow characters:
//
template <>
class cpp_regex_traits_char_layer<char> : public cpp_regex_traits_base<char>
{
typedef std::string string_type;
public:
cpp_regex_traits_char_layer(const std::locale& l)
: cpp_regex_traits_base<char>(l)
{
init();
}
regex_constants::syntax_type syntax_type(char c)const
{
return m_char_map[static_cast<unsigned char>(c)];
}
regex_constants::escape_syntax_type escape_syntax_type(char c) const
{
return m_char_map[static_cast<unsigned char>(c)];
}
private:
regex_constants::syntax_type m_char_map[1u << CHAR_BIT];
void init();
};
//
// class cpp_regex_traits_implementation:
// provides pimpl implementation for cpp_regex_traits.
//
template <class charT>
class cpp_regex_traits_implementation : public cpp_regex_traits_char_layer<charT>
{
public:
cpp_regex_traits_implementation();
cpp_regex_traits_implementation(const std::locale& l) : cpp_regex_traits_char_layer<charT>(l){}
std::string error_string(regex_constants::error_type n) const
{
if(!m_error_strings.empty())
{
std::map<int, std::string>::const_iterator p = m_error_strings.find(n);
return (p == m_error_strings.end()) ? std::string(get_default_error_string(n)) : p->second;
}
return get_default_error_string(n);
}
private:
std::map<int, std::string> m_error_strings;
};
template <class charT>
cpp_regex_traits_implementation<charT>::cpp_regex_traits_implementation()
{
#ifndef __IBMCPP__
typename std::messages<charT>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
#else
typename std::messages<charT>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
std::string cat_name(cpp_regex_traits<charT>::get_catalog_name());
if(cat_name.size())
{
cat = this->m_pmessages->open(
cat_name,
this->m_locale);
if((int)cat < 0)
{
std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name);
boost::throw_exception(err);
}
}
//
// if we have a valid catalog then load our messages:
//
if((int)cat >= 0)
{
for(int i = 0; i <= boost::regex_constants::error_unknown; ++i)
{
std::string s = this->m_pmessages->get(cat, 0, i+200, get_default_error_string(i));
m_error_strings[i] = s;
}
}
}
template <class charT>
boost::shared_ptr<cpp_regex_traits_implementation<charT> > create_cpp_regex_traits(const std::locale& l)
{
// TODO: create a cache for previously constructed objects.
return boost::shared_ptr<cpp_regex_traits_implementation<charT> >(new cpp_regex_traits_implementation<charT>(l));
}
} // re_detail
template <class charT>
class cpp_regex_traits
{
private:
typedef std::ctype<charT> ctype_type;
public:
typedef charT char_type;
typedef std::size_t size_type;
typedef std::basic_string<char_type> string_type;
typedef std::locale locale_type;
typedef typename ctype_type::mask char_class_type;
cpp_regex_traits()
: m_pimpl(re_detail::create_cpp_regex_traits<charT>(std::locale()))
{ }
static size_type length(const char_type* p)
{
return std::char_traits<charT>::length(p);
}
regex_constants::syntax_type syntax_type(charT c)const
{
return m_pimpl->syntax_type(c);
}
regex_constants::escape_syntax_type escape_syntax_type(charT c) const
{
return m_pimpl->escape_syntax_type(c);
}
charT translate(charT c, bool icase) const
{
return icase ? m_pimpl->m_pctype->tolower(c) : c;
}
string_type transform(const charT* p1, const charT* p2) const
{
return m_pimpl->m_pcollate->transform(p1, p2);
}
string_type transform_primary(const charT* , const charT* ) const
{
return string_type();
}
char_class_type lookup_classname(const charT* p1, const charT* p2) const
{
return 0;
}
string_type lookup_collatename(const charT* p1, const charT* p2) const
{
return string_type();
}
bool is_class(charT c, char_class_type f) const
{
return false;
}
int value(charT) const
{
return -1;
}
locale_type imbue(locale_type l)
{
std::locale result(getloc());
m_pimpl = re_detail::create_cpp_regex_traits<charT>(l);
return result;
}
locale_type getloc()const
{
return m_pimpl->m_locale;
}
std::string error_string(regex_constants::error_type n) const
{
return m_pimpl->error_string(n);
}
//
// extension:
// set the name of the message catalog in use (defaults to "boost_regex").
//
static std::string catalog_name(const std::string& name);
static std::string get_catalog_name();
private:
boost::shared_ptr<re_detail::cpp_regex_traits_implementation<charT> > m_pimpl;
//
// catalog name handler:
//
static std::string& get_catalog_name_inst();
#ifdef BOOST_HAS_THREADS
static static_mutex& get_mutex_inst();
#endif
};
template <class charT>
std::string cpp_regex_traits<charT>::catalog_name(const std::string& name)
{
#ifdef BOOST_HAS_THREADS
static_mutex::scoped_lock lk(get_mutex_inst());
#endif
std::string result(get_catalog_name_inst());
get_catalog_name_inst() = name;
return result;
}
template <class charT>
std::string& cpp_regex_traits<charT>::get_catalog_name_inst()
{
static std::string s_name;
return s_name;
}
template <class charT>
std::string cpp_regex_traits<charT>::get_catalog_name()
{
#ifdef BOOST_HAS_THREADS
static_mutex::scoped_lock lk(get_mutex_inst());
#endif
std::string result(get_catalog_name_inst());
return result;
}
#ifdef BOOST_HAS_THREADS
template <class charT>
static_mutex& cpp_regex_traits<charT>::get_mutex_inst()
{
static static_mutex s_mutex = BOOST_STATIC_MUTEX_INIT;
return s_mutex;
}
#endif
} // boost
#endif

View File

@ -24,6 +24,7 @@
#include <boost/regex/config.hpp>
#endif
#include <boost/regex/v4/match_flags.hpp>
#include <boost/regex/v4/error_type.hpp>
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@ -46,8 +47,8 @@ typedef size_t regsize_t;
typedef struct
{
unsigned int re_magic;
unsigned int re_nsub; /* number of parenthesized subexpressions */
const char* re_endp; /* end pointer for REG_PEND */
std::size_t re_nsub; /* number of parenthesized subexpressions */
const char* re_endp; /* end pointer for REG_PEND */
void* guts; /* none of your business :-) */
match_flag_type eflags; /* none of your business :-) */
} regex_tA;
@ -56,7 +57,7 @@ typedef struct
typedef struct
{
unsigned int re_magic;
unsigned int re_nsub; /* number of parenthesized subexpressions */
std::size_t re_nsub; /* number of parenthesized subexpressions */
const wchar_t* re_endp; /* end pointer for REG_PEND */
void* guts; /* none of your business :-) */
match_flag_type eflags; /* none of your business :-) */
@ -128,34 +129,6 @@ BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW*);
#define regex_t regex_tA
#endif
/* regerror() flags */
typedef enum
{
REG_NOERROR = 0, /* Success. */
REG_NOMATCH = 1, /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
REG_BADPAT = 2, /* Invalid pattern. */
REG_ECOLLATE = 3, /* Undefined collating element. */
REG_ECTYPE = 4, /* Invalid character class name. */
REG_EESCAPE = 5, /* Trailing backslash. */
REG_ESUBREG = 6, /* Invalid back reference. */
REG_EBRACK = 7, /* Unmatched left bracket. */
REG_EPAREN = 8, /* Parenthesis imbalance. */
REG_EBRACE = 9, /* Unmatched \{. */
REG_BADBR = 10, /* Invalid contents of \{\}. */
REG_ERANGE = 11, /* Invalid range end. */
REG_ESPACE = 12, /* Ran out of memory. */
REG_BADRPT = 13, /* No preceding re for repetition op. */
REG_EEND = 14, /* unexpected end of expression */
REG_ESIZE = 15, /* expression too big */
REG_ERPAREN = 16, /* unmatched right parenthesis */
REG_EMPTY = 17, /* empty expression */
REG_E_MEMORY = REG_ESIZE, /* out of memory */
REG_E_UNKNOWN = 18 /* unknown error */
} reg_errcode_t;
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
@ -248,7 +221,7 @@ public:
std::size_t Position(int i = 0)const;
std::size_t Length(int i = 0)const;
bool Matched(int i = 0)const;
unsigned int Marks()const;
std::size_t Marks()const;
std::string What(int i = 0)const;
std::string operator[](int i)const { return What(i); }

View File

@ -0,0 +1,84 @@
/*
*
* Copyright (c) 2003
* Dr John Maddock
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Dr John Maddock makes no representations
* about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE escape_syntax_type.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression escape synatx type enumerator.
*/
#ifndef BOOST_REGEX_ERROR_TYPE_HPP
#define BOOST_REGEX_ERROR_TYPE_HPP
namespace boost{
//
// start with the POSIX API versions of these:
//
typedef unsigned reg_error_t;
static const reg_error_t REG_NOERROR = 0; /* Success. */
static const reg_error_t REG_NOMATCH = 1; /* Didn't find a match (for regexec). */
/* POSIX regcomp return error codes. (In the order listed in the
standard.) */
static const reg_error_t REG_BADPAT = 2; /* Invalid pattern. */
static const reg_error_t REG_ECOLLATE = 3; /* Undefined collating element. */
static const reg_error_t REG_ECTYPE = 4; /* Invalid character class name. */
static const reg_error_t REG_EESCAPE = 5; /* Trailing backslash. */
static const reg_error_t REG_ESUBREG = 6; /* Invalid back reference. */
static const reg_error_t REG_EBRACK = 7; /* Unmatched left bracket. */
static const reg_error_t REG_EPAREN = 8; /* Parenthesis imbalance. */
static const reg_error_t REG_EBRACE = 9; /* Unmatched \{. */
static const reg_error_t REG_BADBR = 10; /* Invalid contents of \{\}. */
static const reg_error_t REG_ERANGE = 11; /* Invalid range end. */
static const reg_error_t REG_ESPACE = 12; /* Ran out of memory. */
static const reg_error_t REG_BADRPT = 13; /* No preceding re for repetition op. */
static const reg_error_t REG_EEND = 14; /* unexpected end of expression */
static const reg_error_t REG_ESIZE = 15; /* expression too big */
static const reg_error_t REG_ERPAREN = REG_EPAREN; /* unmatched right parenthesis */
static const reg_error_t REG_EMPTY = 17; /* empty expression */
static const reg_error_t REG_E_MEMORY = REG_ESIZE; /* out of memory */
static const reg_error_t REG_ECOMPLEXITY = 18; /* complexity too high */
static const reg_error_t REG_ESTACK = 19; /* out of stack space */
static const reg_error_t REG_E_UNKNOWN = 20; /* unknown error */
static const reg_error_t REG_ENOSYS = REG_E_UNKNOWN; /* Reserved. */
namespace regex_constants{
typedef ::boost::reg_error_t error_type;
static const error_type error_collate = REG_ECOLLATE;
static const error_type error_ctype = REG_ECTYPE;
static const error_type error_escape = REG_EESCAPE;
static const error_type error_subreg = REG_ESUBREG;
static const error_type error_brack = REG_EBRACK;
static const error_type error_paren = REG_EPAREN;
static const error_type error_brace = REG_EBRACE;
static const error_type error_badbrace = REG_BADBR;
static const error_type error_range = REG_ERANGE;
static const error_type error_space = REG_ESPACE;
static const error_type error_badrepeat = REG_BADRPT;
static const error_type error_size = REG_ESIZE;
static const error_type error_empty = REG_EMPTY;
static const error_type error_complexity = REG_ECOMPLEXITY;
static const error_type error_stack = REG_ESTACK;
static const error_type error_unknown = REG_E_UNKNOWN;
}
}
#endif

View File

@ -47,7 +47,7 @@ namespace boost{
# pragma option push -Jgx
# endif
template class BOOST_REGEX_DECL reg_expression< BOOST_REGEX_CHAR_T >;
template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >;
# ifndef BOOST_REGEX_INSTANTIATE
# pragma option pop
@ -68,7 +68,7 @@ template class BOOST_REGEX_DECL reg_expression< BOOST_REGEX_CHAR_T >;
# pragma warning(disable : 4251 4231 4660)
# endif
template class BOOST_REGEX_DECL reg_expression< BOOST_REGEX_CHAR_T >;
template class BOOST_REGEX_DECL basic_regex< BOOST_REGEX_CHAR_T >;
# ifdef BOOST_MSVC
# pragma warning(pop)

View File

@ -25,9 +25,7 @@
namespace boost{
template <class BidiIterator
, class Allocator = BOOST_DEFAULT_ALLOCATOR(sub_match<BidiIterator> )
>
template <class BidiIterator, class Allocator>
class match_results
{
private:

View File

@ -19,7 +19,9 @@
#define BOOST_REGEX_V4_MEM_BLOCK_CACHE_HPP
#include <new>
#include <boost/regex/v4/regex_synch.hpp>
#ifdef BOOST_HAS_THREADS
#include <boost/regex/static_mutex.hpp>
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
@ -38,6 +40,9 @@ struct mem_block_cache
// this member has to be statically initialsed:
mem_block_node* next;
unsigned cached_blocks;
#ifdef BOOST_HAS_THREADS
boost::static_mutex mut;
#endif
~mem_block_cache()
{
@ -51,7 +56,7 @@ struct mem_block_cache
void* get()
{
#ifdef BOOST_HAS_THREADS
re_detail::cs_guard g(*re_detail::p_re_lock);
boost::static_mutex::scoped_lock g(mut);
#endif
if(next)
{
@ -65,7 +70,7 @@ struct mem_block_cache
void put(void* p)
{
#ifdef BOOST_HAS_THREADS
re_detail::cs_guard g(*re_detail::p_re_lock);
boost::static_mutex::scoped_lock g(mut);
#endif
if(cached_blocks >= BOOST_REGEX_MAX_CACHE_BLOCKS)
{

View File

@ -25,6 +25,36 @@ namespace re_detail{
// error checking API:
//
BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex::flag_type ef, match_flag_type mf);
//
// function can_start:
//
template <class charT>
bool can_start(charT c, const unsigned char* map, unsigned char mask)
{
return ((c < 0) ? true : ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask));
}
inline bool can_start(char c, const unsigned char* map, unsigned char mask)
{
return map[(unsigned char)c] & mask;
}
inline bool can_start(signed char c, const unsigned char* map, unsigned char mask)
{
return map[(unsigned char)c] & mask;
}
inline bool can_start(unsigned char c, const unsigned char* map, unsigned char mask)
{
return map[c] & mask;
}
inline bool can_start(unsigned short c, const unsigned char* map, unsigned char mask)
{
return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);
}
#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
inline bool can_start(wchar_t c, const unsigned char* map, unsigned char mask)
{
return ((c >= (1 << CHAR_BIT)) ? true : map[c] & mask);
}
#endif
//
@ -57,11 +87,11 @@ inline const charT* re_skip_past_null(const charT* p)
return ++p;
}
template <class iterator, class charT, class traits_type, class Allocator>
template <class iterator, class charT, class traits_type>
iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
iterator last,
const re_set_long* set_,
const reg_expression<charT, traits_type, Allocator>& e)
const re_set_long<typename traits_type::char_class_type>* set_,
const basic_regex<charT, traits_type>& e)
{
const charT* p = reinterpret_cast<const charT*>(set_+1);
iterator ptr;
@ -114,16 +144,15 @@ iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
if(set_->cranges || set_->cequivalents)
{
traits_string_type s2(1, col);
traits_string_type s1;
//
// try and match a range, NB only a single character can match
if(set_->cranges)
{
if((e.flags() & regex_constants::collate) == 0)
s1 = s2;
s1.assign(1, col);
else
traits_inst.transform(s1, s2);
s1 = traits_inst.transform(&col, &col + 1);
for(i = 0; i < set_->cranges; ++i)
{
if(STR_COMP(s1, p) <= 0)
@ -148,7 +177,7 @@ iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
// try and match an equivalence class, NB only a single character can match
if(set_->cequivalents)
{
traits_inst.transform_primary(s1, s2);
s1 = traits_inst.transform_primary(&col, &col +1);
for(i = 0; i < set_->cequivalents; ++i)
{
if(STR_COMP(s1, p) == 0)
@ -164,42 +193,14 @@ iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
return set_->isnot ? ++next : next;
}
template <class charT, class traits, class Allocator>
struct access_t : public reg_expression<charT, traits, Allocator>
{
typedef typename is_byte<charT>::width_type width_type;
typedef reg_expression<charT, traits, Allocator> base_type;
typedef charT char_type;
typedef traits traits_type;
typedef Allocator alloc_type;
static int repeat_count(const base_type& b)
{ return base_type::repeat_count(b); }
static unsigned int restart_type(const base_type& b)
{ return base_type::restart_type(b); }
static const re_syntax_base* first(const base_type& b)
{ return base_type::first(b); }
static const unsigned char* get_map(const base_type& b)
{ return base_type::get_map(b); }
static std::size_t leading_length(const base_type& b)
{ return base_type::leading_length(b); }
static const kmp_info<charT>* get_kmp(const base_type& b)
{ return base_type::get_kmp(b); }
static bool can_start(char_type c, const unsigned char* _map, unsigned char mask)
{
return reg_expression<char_type, traits_type, alloc_type>::can_start(c, _map, mask, width_type());
}
};
template <class BidiIterator>
class repeater_count
{
repeater_count** stack;
repeater_count* next;
int id;
unsigned count; // the number of iterations so far
BidiIterator start_pos; // where the last repeat started
std::size_t count; // the number of iterations so far
BidiIterator start_pos; // where the last repeat started
public:
repeater_count(repeater_count** s)
{
@ -230,10 +231,10 @@ public:
{
*stack = next;
}
unsigned get_count() { return count; }
std::size_t get_count() { return count; }
int get_id() { return id; }
int operator++() { return ++count; }
bool check_null_repeat(const BidiIterator& pos, unsigned max)
bool check_null_repeat(const BidiIterator& pos, std::size_t max)
{
// this is called when we are about to start a new repeat,
// if the last one was NULL move our count to max,
@ -268,22 +269,20 @@ enum saved_state_type
saved_state_count = 14
};
template <class BidiIterator, class Allocator, class traits, class Allocator2>
template <class BidiIterator, class Allocator, class traits>
class perl_matcher
{
public:
typedef typename traits::char_type char_type;
typedef perl_matcher<BidiIterator, Allocator, traits, Allocator2> self_type;
typedef perl_matcher<BidiIterator, Allocator, traits> self_type;
typedef bool (self_type::*matcher_proc_type)(void);
typedef access_t<char_type, traits, Allocator2> access;
typedef typename traits::size_type traits_size_type;
typedef typename traits::uchar_type traits_uchar_type;
typedef typename is_byte<char_type>::width_type width_type;
typedef typename regex_iterator_traits<BidiIterator>::difference_type difference_type;
perl_matcher(BidiIterator first, BidiIterator end,
match_results<BidiIterator, Allocator>& what,
const reg_expression<char_type, traits, Allocator2>& e,
const basic_regex<char_type, traits>& e,
match_flag_type f);
bool match();
@ -361,7 +360,7 @@ private:
// where the current search started from, acts as base for $` during grep:
BidiIterator search_base;
// the expression being examined:
const reg_expression<char_type, traits, Allocator2>& re;
const basic_regex<char_type, traits>& re;
// the expression's traits class:
const traits& traits_inst;
// the next state in the machine being matched:
@ -382,6 +381,8 @@ private:
repeater_count<BidiIterator>* next_count;
// the first repeat being examined (top of linked list):
repeater_count<BidiIterator> rep_obj;
// the mask to pass when matching word boundaries:
typename traits::char_class_type m_word_mask;
#ifdef BOOST_REGEX_NON_RECURSIVE
//

View File

@ -31,10 +31,10 @@
namespace boost{
namespace re_detail{
template <class BidiIterator, class Allocator, class traits, class Allocator2>
perl_matcher<BidiIterator, Allocator, traits, Allocator2>::perl_matcher(BidiIterator first, BidiIterator end,
template <class BidiIterator, class Allocator, class traits>
perl_matcher<BidiIterator, Allocator, traits>::perl_matcher(BidiIterator first, BidiIterator end,
match_results<BidiIterator, Allocator>& what,
const reg_expression<char_type, traits, Allocator2>& e,
const basic_regex<char_type, traits>& e,
match_flag_type f)
: m_result(what), base(first), last(end),
position(first), re(e), traits_inst(e.get_traits()),
@ -54,7 +54,7 @@ perl_matcher<BidiIterator, Allocator, traits, Allocator2>::perl_matcher(BidiIter
estimate_max_state_count(static_cast<category*>(0));
if(!(m_match_flags & (match_perl|match_posix)))
{
if(re.flags() & regex_constants::perlex)
if((re.flags() & regbase::no_perl_ex) == 0)
m_match_flags |= match_perl;
else
m_match_flags |= match_posix;
@ -70,30 +70,33 @@ perl_matcher<BidiIterator, Allocator, traits, Allocator2>::perl_matcher(BidiIter
m_stack_base = 0;
m_backup_state = 0;
#endif
// find the value to use for matching word boundaries:
const char_type w = static_cast<char_type>('w');
m_word_mask = traits_inst.lookup_classname(&w, &w+1);
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::estimate_max_state_count(std::random_access_iterator_tag*)
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(std::random_access_iterator_tag*)
{
difference_type dist = boost::re_detail::distance(base, last);
traits_size_type states = static_cast<traits_size_type>(re.size());
states *= states;
difference_type lim = std::numeric_limits<difference_type>::max() - 1000 - states;
difference_type lim = (std::numeric_limits<difference_type>::max)() - 1000 - states;
if(dist > (difference_type)(lim / states))
max_state_count = lim;
else
max_state_count = 1000 + states * dist;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::estimate_max_state_count(void*)
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::estimate_max_state_count(void*)
{
// we don't know how long the sequence is:
max_state_count = BOOST_REGEX_MAX_STATE_COUNT;
}
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::protected_call(
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(
protected_proc_type proc)
{
__try{
@ -109,18 +112,18 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::protected_call(
}
#endif
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match()
{
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
return protected_call(&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_imp);
return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::match_imp);
#else
return match_imp();
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_imp()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_imp()
{
// initialise our stack if we are non-recursive:
#ifdef BOOST_REGEX_NON_RECURSIVE
@ -158,28 +161,28 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_imp()
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find()
{
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
return protected_call(&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_imp);
return protected_call(&perl_matcher<BidiIterator, Allocator, traits>::find_imp);
#else
return find_imp();
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_imp()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_imp()
{
static matcher_proc_type const s_find_vtable[7] =
{
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_any,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_word,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_line,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_buf,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_prefix,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_lit,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_lit,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_any,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_word,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_line,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf,
&perl_matcher<BidiIterator, Allocator, traits>::match_prefix,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
&perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit,
};
// initialise our stack if we are non-recursive:
@ -197,7 +200,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_imp()
// reset our state machine:
position = base;
search_base = base;
pstate = access::first(re);
pstate = re.get_first_state();
m_presult->set_size((m_match_flags & match_nosubs) ? 1 : re.mark_count(), base, last);
m_presult->set_base(base);
m_match_flags |= regex_constants::match_init;
@ -230,7 +233,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_imp()
// find out what kind of expression we have:
unsigned type = (m_match_flags & match_continuous) ?
static_cast<unsigned int>(regbase::restart_continue)
: static_cast<unsigned int>(access::restart_type(re));
: static_cast<unsigned int>(re.get_restart_type());
// call the appropriate search routine:
matcher_proc_type proc = s_find_vtable[type];
@ -249,12 +252,12 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_imp()
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_prefix()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_prefix()
{
m_has_partial_match = false;
m_has_found_match = false;
pstate = access::first(re);
pstate = re.get_first_state();
m_presult->set_first(position);
restart = position;
match_all_states();
@ -282,8 +285,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_prefix()
return m_has_found_match;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_endmark()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_endmark()
{
int index = static_cast<const re_brace*>(pstate)->index;
if(index > 0)
@ -301,8 +304,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_endmark()
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_literal()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_literal()
{
unsigned int len = static_cast<const re_literal*>(pstate)->length;
const char_type* what = reinterpret_cast<const char_type*>(static_cast<const re_literal*>(pstate) + 1);
@ -318,8 +321,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_literal()
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_start_line()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_start_line()
{
if(position == base)
{
@ -341,13 +344,13 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_start_line
--t;
if(position != last)
{
if(traits_inst.is_separator(*t) && !((*t == '\r') && (*position == '\n')) )
if(is_separator(*t) && !((*t == '\r') && (*position == '\n')) )
{
pstate = pstate->next.p;
return true;
}
}
else if(traits_inst.is_separator(*t))
else if(is_separator(*t))
{
pstate = pstate->next.p;
return true;
@ -355,15 +358,15 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_start_line
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_end_line()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_end_line()
{
if(position != last)
{
if(m_match_flags & match_single_line)
return false;
// we're not yet at the end so *first is always valid:
if(traits_inst.is_separator(*position))
if(is_separator(*position))
{
if((position != base) || (m_match_flags & match_prev_avail))
{
@ -387,12 +390,12 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_end_line()
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_wild()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_wild()
{
if(position == last)
return false;
if(traits_inst.is_separator(*position) && (m_match_flags & match_not_dot_newline))
if(is_separator(*position) && (m_match_flags & match_not_dot_newline))
return false;
if((*position == char_type(0)) && (m_match_flags & match_not_dot_null))
return false;
@ -401,8 +404,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_wild()
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_match()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_match()
{
if((m_match_flags & match_not_null) && (position == (*m_presult)[0].first))
return false;
@ -429,17 +432,17 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_match()
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_boundary()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary()
{
bool b; // indcates whether next character is a word character
if(position != last)
{
// prev and this character must be opposites:
#if defined(BOOST_REGEX_USE_C_LOCALE) && defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ < 95)
b = traits::is_class(*position, traits::char_class_word);
b = traits::is_class(*position, m_word_mask);
#else
b = traits_inst.is_class(*position, traits::char_class_word);
b = traits_inst.is_class(*position, m_word_mask);
#endif
}
else
@ -456,7 +459,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_bound
else
{
--position;
b ^= traits_inst.is_class(*position, traits::char_class_word);
b ^= traits_inst.is_class(*position, m_word_mask);
++position;
}
if(b)
@ -467,13 +470,13 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_bound
return false; // no match if we get to here...
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_within_word()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_within_word()
{
if(position == last)
return false;
// both prev and this character must be traits::char_class_word:
if(traits_inst.is_class(*position, traits::char_class_word))
// both prev and this character must be m_word_mask:
if(traits_inst.is_class(*position, m_word_mask))
{
bool b;
if((position == base) && ((m_match_flags & match_prev_avail) == 0))
@ -481,7 +484,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_within_wor
else
{
--position;
b = traits_inst.is_class(*position, traits::char_class_word);
b = traits_inst.is_class(*position, m_word_mask);
++position;
}
if(b)
@ -493,12 +496,12 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_within_wor
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_start()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_start()
{
if(position == last)
return false; // can't be starting a word if we're already at the end of input
if(!traits_inst.is_class(*position, traits::char_class_word))
if(!traits_inst.is_class(*position, m_word_mask))
return false; // next character isn't a word character
if((position == base) && ((m_match_flags & match_prev_avail) == 0))
{
@ -510,7 +513,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_start
// otherwise inside buffer:
BidiIterator t(position);
--t;
if(traits_inst.is_class(*t, traits::char_class_word))
if(traits_inst.is_class(*t, m_word_mask))
return false; // previous character not non-word
}
// OK we have a match:
@ -518,14 +521,14 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_start
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_end()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_word_end()
{
if((position == base) && ((m_match_flags & match_prev_avail) == 0))
return false; // start of buffer can't be end of word
BidiIterator t(position);
--t;
if(traits_inst.is_class(*t, traits::char_class_word) == false)
if(traits_inst.is_class(*t, m_word_mask) == false)
return false; // previous character wasn't a word character
if(position == last)
@ -536,15 +539,15 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_end()
else
{
// otherwise inside buffer:
if(traits_inst.is_class(*position, traits::char_class_word))
if(traits_inst.is_class(*position, m_word_mask))
return false; // next character is a word character
}
pstate = pstate->next.p;
return true; // if we fall through to here then we've succeeded
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_start()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start()
{
if((position != base) || (m_match_flags & match_not_bob))
return false;
@ -553,8 +556,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_sta
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_end()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end()
{
if((position != last) || (m_match_flags & match_not_eob))
return false;
@ -563,8 +566,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_end
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_backref()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_backref()
{
// compare with what we previously matched:
BidiIterator i = (*m_presult)[static_cast<const re_brace*>(pstate)->index].first;
@ -580,13 +583,13 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_backref()
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set()
{
// let the traits class do the work:
if(position == last)
return false;
BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long*>(pstate), re);
BidiIterator t = re_is_set_member(position, last, static_cast<const re_set_long<typename traits::char_class_type>*>(pstate), re);
if(t != position)
{
pstate = pstate->next.p;
@ -596,12 +599,12 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set()
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_set()
{
if(position == last)
return false;
if(static_cast<const re_set*>(pstate)->_map[(traits_uchar_type)traits_inst.translate(*position, icase)])
if(static_cast<const re_set*>(pstate)->_map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
pstate = pstate->next.p;
++position;
@ -610,42 +613,42 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set()
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_jump()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_jump()
{
pstate = static_cast<const re_jump*>(pstate)->alt.p;
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_combining()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_combining()
{
if(position == last)
return false;
if(traits_inst.is_combining(traits_inst.translate(*position, icase)))
if(is_combining(traits_inst.translate(*position, icase)))
return false;
++position;
while((position != last) && traits_inst.is_combining(traits_inst.translate(*position, icase)))
while((position != last) && is_combining(traits_inst.translate(*position, icase)))
++position;
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_soft_buffer_end()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end()
{
if(m_match_flags & match_not_eob)
return false;
BidiIterator p(position);
while((p != last) && traits_inst.is_separator(traits_inst.translate(*p, icase)))++p;
while((p != last) && is_separator(traits_inst.translate(*p, icase)))++p;
if(p != last)
return false;
pstate = pstate->next.p;
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_restart_continue()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
{
if(position == search_base)
{
@ -655,23 +658,23 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_restart_co
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_any()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_any()
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
const unsigned char* _map = access::get_map(re);
const unsigned char* _map = re.get_map();
while(true)
{
// skip everything we can't match:
while((position != last) && !access::can_start(*position, _map, (unsigned char)mask_any) )
while((position != last) && !can_start(*position, _map, (unsigned char)mask_any) )
++position;
if(position == last)
{
// run out of characters, try a null match if possible:
if(access::first(re)->can_be_null)
if(re.can_be_null())
return match_prefix();
break;
}
@ -688,29 +691,29 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_any
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_word()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_word()
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
// do search optimised for word starts:
const unsigned char* _map = access::get_map(re);
const unsigned char* _map = re.get_map();
if((m_match_flags & match_prev_avail) || (position != base))
--position;
else if(match_prefix())
return true;
do
{
while((position != last) && traits_inst.is_class(*position, traits::char_class_word))
while((position != last) && traits_inst.is_class(*position, m_word_mask))
++position;
while((position != last) && !traits_inst.is_class(*position, traits::char_class_word))
while((position != last) && !traits_inst.is_class(*position, m_word_mask))
++position;
if(position == last)
break;
if(access::can_start(*position, _map, (unsigned char)mask_any) )
if(can_start(*position, _map, (unsigned char)mask_any) )
{
if(match_prefix())
return true;
@ -724,11 +727,11 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_wor
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_line()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_line()
{
// do search optimised for line starts:
const unsigned char* _map = access::get_map(re);
const unsigned char* _map = re.get_map();
if(match_prefix())
return true;
while(position != last)
@ -740,12 +743,12 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_lin
++position;
if(position == last)
{
if((access::first(re)->can_be_null) && match_prefix())
if(re.can_be_null() && match_prefix())
return true;
return false;
}
if( access::can_start(*position, _map, (unsigned char)mask_any) )
if( can_start(*position, _map, (unsigned char)mask_any) )
{
if(match_prefix())
return true;
@ -757,23 +760,24 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_lin
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_buf()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_buf()
{
if((position == base) && ((m_match_flags & match_not_bob) == 0))
return match_prefix();
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_lit()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::find_restart_lit()
{
#if 0
if(position == last)
return false; // can't possibly match if we're at the end already
unsigned type = (m_match_flags & match_continuous) ?
static_cast<unsigned int>(regbase::restart_continue)
: static_cast<unsigned int>(access::restart_type(re));
: static_cast<unsigned int>(re.get_restart_type());
const kmp_info<char_type>* info = access::get_kmp(re);
int len = info->len;
@ -822,6 +826,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::find_restart_lit
std::advance(position, -j);
return match_prefix();
}
#endif
return false;
}

View File

@ -110,37 +110,37 @@ struct saved_single_repeat : public saved_state
: saved_state(arg_id), count(c), rep(r), last_position(lp){}
};
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_all_states()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
{
static matcher_proc_type const s_match_vtable[26] =
{
(&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_endmark,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_literal,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_start_line,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_end_line,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_wild,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_match,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_boundary,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_within_word,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_start,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_end,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_start,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_backref,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_jump,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_combining,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_soft_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_restart_continue,
(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_slow),
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_repeat,
(&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
&perl_matcher<BidiIterator, Allocator, traits>::match_literal,
&perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
&perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
&perl_matcher<BidiIterator, Allocator, traits>::match_wild,
&perl_matcher<BidiIterator, Allocator, traits>::match_match,
&perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
&perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
&perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
&perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
&perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
&perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits>::match_backref,
&perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
&perl_matcher<BidiIterator, Allocator, traits>::match_set,
&perl_matcher<BidiIterator, Allocator, traits>::match_jump,
&perl_matcher<BidiIterator, Allocator, traits>::match_alt,
&perl_matcher<BidiIterator, Allocator, traits>::match_rep,
&perl_matcher<BidiIterator, Allocator, traits>::match_combining,
&perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
&perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
};
push_recursion_stopper();
@ -163,8 +163,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_all_states
return m_recursive_result;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::extend_stack()
template <class BidiIterator, class Allocator, class traits>
void perl_matcher<BidiIterator, Allocator, traits>::extend_stack()
{
if(used_block_count)
{
@ -183,8 +183,8 @@ void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::extend_stack()
raise_error(traits_inst, REG_E_MEMORY);
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_matched_paren(int index, const sub_match<BidiIterator>& sub)
{
assert(index);
saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
@ -199,8 +199,8 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_matc
m_backup_state = pmp;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_recursion_stopper()
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_recursion_stopper()
{
saved_state* pmp = m_backup_state;
--pmp;
@ -214,8 +214,8 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_recu
m_backup_state = pmp;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_assertion(const re_syntax_base* ps, bool positive)
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_assertion(const re_syntax_base* ps, bool positive)
{
saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
--pmp;
@ -229,8 +229,8 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_asse
m_backup_state = pmp;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_alt(const re_syntax_base* ps)
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_alt(const re_syntax_base* ps)
{
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
--pmp;
@ -244,8 +244,8 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_alt(
m_backup_state = pmp;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_non_greedy_repeat(const re_syntax_base* ps)
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_non_greedy_repeat(const re_syntax_base* ps)
{
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
--pmp;
@ -259,8 +259,8 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_non_
m_backup_state = pmp;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_repeater_count(int i, repeater_count<BidiIterator>** s)
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_repeater_count(int i, repeater_count<BidiIterator>** s)
{
saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
--pmp;
@ -274,8 +274,8 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_repe
m_backup_state = pmp;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_single_repeat(unsigned c, const re_repeat* r, BidiIterator last_position, int id)
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::push_single_repeat(unsigned c, const re_repeat* r, BidiIterator last_position, int id)
{
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
--pmp;
@ -289,8 +289,8 @@ inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::push_sing
m_backup_state = pmp;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_startmark()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
{
int index = static_cast<const re_brace*>(pstate)->index;
switch(index)
@ -358,11 +358,11 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_startmark(
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
{
bool take_first, take_second;
const re_jump* jmp = static_cast<const re_jump*>(pstate);
const re_alt* jmp = static_cast<const re_alt*>(pstate);
// find out which of these two alternatives we need to take:
if(position == last)
@ -372,8 +372,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt()
}
else
{
take_first = access::can_start(*position, jmp->_map, (unsigned char)mask_take);
take_second = access::can_start(*position, jmp->_map, (unsigned char)mask_skip);
take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
}
if(take_first)
@ -395,8 +395,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt()
return false; // neither option is possible
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -416,8 +416,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep()
}
else
{
take_first = access::can_start(*position, rep->_map, (unsigned char)mask_take);
take_second = access::can_start(*position, rep->_map, (unsigned char)mask_skip);
take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
}
if(take_first || (next_count->get_id() != rep->id))
@ -495,8 +495,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep()
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_slow()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
{
unsigned count = 0;
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
@ -535,18 +535,18 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat
if(count < rep->max)
push_single_repeat(count, rep, position, saved_state_rep_slow_dot);
pstate = rep->alt.p;
return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
}
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_fast()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
{
if(m_match_flags & (match_not_dot_newline | match_not_dot_null))
return match_dot_repeat_slow();
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
unsigned count = std::min(static_cast<unsigned>(re_detail::distance(position, last)), static_cast<unsigned>(rep->greedy ? rep->max : rep->min));
unsigned count = (std::min)(static_cast<unsigned>(re_detail::distance(position, last)), static_cast<unsigned>(rep->greedy ? rep->max : rep->min));
if(rep->min > count)
return false; // not enough text left to match
std::advance(position, count);
@ -568,12 +568,12 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat
if(count < rep->max)
push_single_repeat(count, rep, position, saved_state_rep_fast_dot);
pstate = rep->alt.p;
return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
}
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repeat()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -593,7 +593,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repea
if(::boost::is_random_access_iterator<BidiIterator>::value)
{
BidiIterator end = position;
std::advance(end, std::min((unsigned)re_detail::distance(position, last), desired));
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (traits_inst.translate(*position, icase) == what))
{
@ -630,7 +630,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repea
if(count < rep->max)
push_single_repeat(count, rep, position, saved_state_rep_char);
pstate = rep->alt.p;
return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
}
#ifdef __BORLANDC__
#pragma option pop
@ -640,8 +640,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repea
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -660,9 +660,9 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
if(::boost::is_random_access_iterator<BidiIterator>::value)
{
BidiIterator end = position;
std::advance(end, std::min((unsigned)re_detail::distance(position, last), desired));
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && map[(traits_uchar_type)traits_inst.translate(*position, icase)])
while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
}
@ -670,7 +670,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
}
else
{
while((count < desired) && (position != last) && map[(traits_uchar_type)traits_inst.translate(*position, icase)])
while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
++count;
@ -697,7 +697,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
if(count < rep->max)
push_single_repeat(count, rep, position, saved_state_rep_short_set);
pstate = rep->alt.p;
return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
}
#ifdef __BORLANDC__
#pragma option pop
@ -707,8 +707,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_repeat()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -718,7 +718,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_r
#pragma option push -w-8008 -w-8066 -w-8004
#endif
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
const re_set_long* set = static_cast<const re_set_long*>(pstate->next.p);
const re_set_long<typename traits::char_class_type>* set = static_cast<const re_set_long<typename traits::char_class_type>*>(pstate->next.p);
unsigned count = 0;
//
// start by working out how much we can skip:
@ -727,7 +727,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_r
if(::boost::is_random_access_iterator<BidiIterator>::value)
{
BidiIterator end = position;
std::advance(end, std::min((unsigned)re_detail::distance(position, last), desired));
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (position != re_is_set_member(position, last, set, re)))
{
@ -764,7 +764,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_r
if(count < rep->max)
push_single_repeat(count, rep, position, saved_state_rep_long_set);
pstate = rep->alt.p;
return (position == last) ? (rep->can_be_null & mask_skip) : access::can_start(*position, rep->_map, mask_skip);
return (position == last) ? (rep->can_be_null & mask_skip) : can_start(*position, rep->_map, mask_skip);
}
#ifdef __BORLANDC__
#pragma option pop
@ -781,25 +781,25 @@ unwinding does in the recursive implementation.
****************************************************************************/
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind(bool have_match)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind(bool have_match)
{
static unwind_proc_type const s_unwind_table[14] =
{
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_end,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_paren,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_recursion_stopper,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_assertion,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_alt,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_repeater_counter,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_extra_block,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_greedy_single_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_slow_dot_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_fast_dot_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_char_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_non_greedy_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_end,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_paren,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_alt,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat,
};
m_recursive_result = have_match;
@ -819,15 +819,15 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind(bool have
return pstate ? true : false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_end(bool)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_end(bool)
{
pstate = 0; // nothing left to search
return false; // end of stack nothing more to search
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_paren(bool have_match)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_paren(bool have_match)
{
saved_matched_paren<BidiIterator>* pmp = static_cast<saved_matched_paren<BidiIterator>*>(m_backup_state);
// restore previous values if no match was found:
@ -849,16 +849,16 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_paren(boo
return true; // keep looking
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_recursion_stopper(bool)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_recursion_stopper(bool)
{
boost::re_detail::inplace_destroy(m_backup_state++);
pstate = 0; // nothing left to search
return false; // end of stack nothing more to search
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_assertion(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_assertion(bool r)
{
saved_assertion<BidiIterator>* pmp = static_cast<saved_assertion<BidiIterator>*>(m_backup_state);
pstate = pmp->pstate;
@ -870,8 +870,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_assertion
return !result; // return false if the assertion was matched to stop search.
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_alt(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_alt(bool r)
{
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
if(!r)
@ -884,8 +884,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_alt(bool
return r;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_repeater_counter(bool)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_repeater_counter(bool)
{
saved_repeater<BidiIterator>* pmp = static_cast<saved_repeater<BidiIterator>*>(m_backup_state);
boost::re_detail::inplace_destroy(pmp++);
@ -893,8 +893,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_repeater_
return true; // keep looking
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_extra_block(bool)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_extra_block(bool)
{
saved_extra_block* pmp = static_cast<saved_extra_block*>(m_backup_state);
void* condemmed = m_stack_base;
@ -905,16 +905,16 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_extra_blo
return true; // keep looking
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
inline void perl_matcher<BidiIterator, Allocator, traits, Allocator2>::destroy_single_repeat()
template <class BidiIterator, class Allocator, class traits>
inline void perl_matcher<BidiIterator, Allocator, traits>::destroy_single_repeat()
{
saved_single_repeat<BidiIterator>* p = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
boost::re_detail::inplace_destroy(p++);
m_backup_state = p;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_greedy_single_repeat(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_greedy_single_repeat(bool r)
{
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
@ -944,13 +944,13 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_greedy_si
--position;
--count;
++state_count;
}while(count && !access::can_start(*position, rep->_map, mask_skip));
}while(count && !can_start(*position, rep->_map, mask_skip));
// if we've hit base, destroy this state:
if(count == 0)
{
destroy_single_repeat();
if(!access::can_start(*position, rep->_map, mask_skip))
if(!can_start(*position, rep->_map, mask_skip))
return true;
}
else
@ -962,8 +962,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_greedy_si
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_slow_dot_repeat(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_slow_dot_repeat(bool r)
{
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
@ -999,7 +999,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_slow_dot_
++count;
++state_count;
pstate = rep->next.p;
}while((count < rep->max) && (position != last) && !access::can_start(*position, rep->_map, mask_skip));
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
}
if(position == last)
{
@ -1012,7 +1012,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_slow_dot_
{
// can't repeat any more, remove the pushed state:
destroy_single_repeat();
if(!access::can_start(*position, rep->_map, mask_skip))
if(!can_start(*position, rep->_map, mask_skip))
return true;
}
else
@ -1024,8 +1024,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_slow_dot_
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_fast_dot_repeat(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_fast_dot_repeat(bool r)
{
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
@ -1050,7 +1050,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_fast_dot_
++position;
++count;
++state_count;
}while((count < rep->max) && (position != last) && !access::can_start(*position, rep->_map, mask_skip));
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
}
if(position == last)
@ -1064,7 +1064,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_fast_dot_
{
// can't repeat any more, remove the pushed state:
destroy_single_repeat();
if(!access::can_start(*position, rep->_map, mask_skip))
if(!can_start(*position, rep->_map, mask_skip))
return true;
}
else
@ -1076,8 +1076,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_fast_dot_
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_char_repeat(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_char_repeat(bool r)
{
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
@ -1115,7 +1115,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_char_repe
++ position;
++state_count;
pstate = rep->next.p;
}while((count < rep->max) && (position != last) && !access::can_start(*position, rep->_map, mask_skip));
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
}
if(position == last)
{
@ -1128,7 +1128,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_char_repe
{
// can't repeat any more, remove the pushed state:
destroy_single_repeat();
if(!access::can_start(*position, rep->_map, mask_skip))
if(!can_start(*position, rep->_map, mask_skip))
return true;
}
else
@ -1140,8 +1140,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_char_repe
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set_repeat(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_short_set_repeat(bool r)
{
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
@ -1169,7 +1169,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set
// wind forward until we can skip out of the repeat:
do
{
if(!map[(traits_uchar_type)traits_inst.translate(*position, icase)])
if(!map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
// failed repeat match, discard this state and look for another:
destroy_single_repeat();
@ -1179,7 +1179,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set
++ position;
++state_count;
pstate = rep->next.p;
}while((count < rep->max) && (position != last) && !access::can_start(*position, rep->_map, mask_skip));
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
}
if(position == last)
{
@ -1192,7 +1192,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set
{
// can't repeat any more, remove the pushed state:
destroy_single_repeat();
if(!access::can_start(*position, rep->_map, mask_skip))
if(!can_start(*position, rep->_map, mask_skip))
return true;
}
else
@ -1204,8 +1204,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_short_set
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_repeat(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_long_set_repeat(bool r)
{
saved_single_repeat<BidiIterator>* pmp = static_cast<saved_single_repeat<BidiIterator>*>(m_backup_state);
@ -1219,7 +1219,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_
const re_repeat* rep = pmp->rep;
unsigned count = pmp->count;
pstate = rep->next.p;
const re_set_long* set = static_cast<const re_set_long*>(pstate);
const re_set_long<typename traits::char_class_type>* set = static_cast<const re_set_long<typename traits::char_class_type>*>(pstate);
position = pmp->last_position;
assert(rep->type == syntax_element_long_set_rep);
@ -1244,7 +1244,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_
++count;
++state_count;
pstate = rep->next.p;
}while((count < rep->max) && (position != last) && !access::can_start(*position, rep->_map, mask_skip));
}while((count < rep->max) && (position != last) && !can_start(*position, rep->_map, mask_skip));
}
if(position == last)
{
@ -1257,7 +1257,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_
{
// can't repeat any more, remove the pushed state:
destroy_single_repeat();
if(!access::can_start(*position, rep->_map, mask_skip))
if(!can_start(*position, rep->_map, mask_skip))
return true;
}
else
@ -1269,8 +1269,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_long_set_
return false;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::unwind_non_greedy_repeat(bool r)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::unwind_non_greedy_repeat(bool r)
{
saved_position<BidiIterator>* pmp = static_cast<saved_position<BidiIterator>*>(m_backup_state);
if(!r)

View File

@ -45,37 +45,37 @@ public:
const sub_match<BidiIterator>& get() { return sub; }
};
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_all_states()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_all_states()
{
static matcher_proc_type const s_match_vtable[26] =
{
(&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_endmark,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_literal,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_start_line,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_end_line,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_wild,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_match,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_boundary,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_within_word,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_start,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_word_end,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_start,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_backref,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_jump,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_combining,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_soft_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_restart_continue,
(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_slow),
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_repeat,
(&perl_matcher<BidiIterator, Allocator, traits>::match_startmark),
&perl_matcher<BidiIterator, Allocator, traits>::match_endmark,
&perl_matcher<BidiIterator, Allocator, traits>::match_literal,
&perl_matcher<BidiIterator, Allocator, traits>::match_start_line,
&perl_matcher<BidiIterator, Allocator, traits>::match_end_line,
&perl_matcher<BidiIterator, Allocator, traits>::match_wild,
&perl_matcher<BidiIterator, Allocator, traits>::match_match,
&perl_matcher<BidiIterator, Allocator, traits>::match_word_boundary,
&perl_matcher<BidiIterator, Allocator, traits>::match_within_word,
&perl_matcher<BidiIterator, Allocator, traits>::match_word_start,
&perl_matcher<BidiIterator, Allocator, traits>::match_word_end,
&perl_matcher<BidiIterator, Allocator, traits>::match_buffer_start,
&perl_matcher<BidiIterator, Allocator, traits>::match_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits>::match_backref,
&perl_matcher<BidiIterator, Allocator, traits>::match_long_set,
&perl_matcher<BidiIterator, Allocator, traits>::match_set,
&perl_matcher<BidiIterator, Allocator, traits>::match_jump,
&perl_matcher<BidiIterator, Allocator, traits>::match_alt,
&perl_matcher<BidiIterator, Allocator, traits>::match_rep,
&perl_matcher<BidiIterator, Allocator, traits>::match_combining,
&perl_matcher<BidiIterator, Allocator, traits>::match_soft_buffer_end,
&perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue,
(::boost::is_random_access_iterator<BidiIterator>::value ? &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast : &perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow),
&perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat,
&perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat,
};
if(state_count > max_state_count)
@ -94,8 +94,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_all_states
return true;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_startmark()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_startmark()
{
int index = static_cast<const re_brace*>(pstate)->index;
bool r = true;
@ -185,11 +185,11 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_startmark(
return r;
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_alt()
{
bool take_first, take_second;
const re_jump* jmp = static_cast<const re_jump*>(pstate);
const re_alt* jmp = static_cast<const re_alt*>(pstate);
// find out which of these two alternatives we need to take:
if(position == last)
@ -199,8 +199,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt()
}
else
{
take_first = access::can_start(*position, jmp->_map, (unsigned char)mask_take);
take_second = access::can_start(*position, jmp->_map, (unsigned char)mask_skip);
take_first = can_start(*position, jmp->_map, (unsigned char)mask_take);
take_second = can_start(*position, jmp->_map, (unsigned char)mask_skip);
}
if(take_first)
@ -230,8 +230,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_alt()
return false; // neither option is possible
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_rep()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -261,8 +261,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep()
}
else
{
take_first = access::can_start(*position, rep->_map, (unsigned char)mask_take);
take_second = access::can_start(*position, rep->_map, (unsigned char)mask_skip);
take_first = can_start(*position, rep->_map, (unsigned char)mask_take);
take_second = can_start(*position, rep->_map, (unsigned char)mask_skip);
}
if(next_count->get_count() < rep->min)
@ -327,8 +327,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_rep()
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_slow()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_slow()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -387,8 +387,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat_fast()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -400,7 +400,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat
// start by working out how much we can skip:
//
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
unsigned count = std::min(static_cast<unsigned>(re_detail::distance(position, last)), (rep->greedy ? rep->max : rep->min));
unsigned count = (std::min)(static_cast<unsigned>(re_detail::distance(position, last)), (rep->greedy ? rep->max : rep->min));
if(rep->min > count)
return false; // not enough text left to match
std::advance(position, count);
@ -413,7 +413,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat
BidiIterator save_pos;
do
{
while((position != last) && (count < rep->max) && !access::can_start(*position, rep->_map, mask_skip))
while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
{
++position;
++count;
@ -437,8 +437,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_dot_repeat
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repeat()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_char_repeat()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -454,11 +454,11 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repea
//
// start by working out how much we can skip:
//
unsigned desired = rep->greedy ? rep->max : rep->min;
std::size_t desired = rep->greedy ? rep->max : rep->min;
if(::boost::is_random_access_iterator<BidiIterator>::value)
{
BidiIterator end = position;
std::advance(end, std::min((unsigned)re_detail::distance(position, last), desired));
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (traits_inst.translate(*position, icase) == what))
{
@ -486,7 +486,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repea
BidiIterator save_pos;
do
{
while((position != last) && (count < rep->max) && !access::can_start(*position, rep->_map, mask_skip))
while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
{
if((traits_inst.translate(*position, icase) == what))
{
@ -507,8 +507,16 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repea
return false;
if(position == last)
return false;
position = ++save_pos;
++count;
position = save_pos;
if(traits_inst.translate(*position, icase) == what)
{
++position;
++count;
}
else
{
return false;
}
}while(true);
#ifdef __BORLANDC__
#pragma option pop
@ -518,8 +526,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_char_repea
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_set_repeat()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -534,13 +542,13 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
//
// start by working out how much we can skip:
//
unsigned desired = rep->greedy ? rep->max : rep->min;
std::size_t desired = rep->greedy ? rep->max : rep->min;
if(::boost::is_random_access_iterator<BidiIterator>::value)
{
BidiIterator end = position;
std::advance(end, std::min((unsigned)re_detail::distance(position, last), desired));
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && map[(traits_uchar_type)traits_inst.translate(*position, icase)])
while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
}
@ -548,7 +556,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
}
else
{
while((count < desired) && (position != last) && map[(traits_uchar_type)traits_inst.translate(*position, icase)])
while((count < desired) && (position != last) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
++count;
@ -566,9 +574,9 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
BidiIterator save_pos;
do
{
while((position != last) && (count < rep->max) && !access::can_start(*position, rep->_map, mask_skip))
while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
{
if(map[(traits_uchar_type)traits_inst.translate(*position, icase)])
if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
++count;
@ -587,8 +595,16 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
return false;
if(position == last)
return false;
position = ++save_pos;
++count;
position = save_pos;
if(map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
++count;
}
else
{
return false;
}
}while(true);
#ifdef __BORLANDC__
#pragma option pop
@ -598,8 +614,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_set_repeat
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_repeat()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_long_set_repeat()
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -609,16 +625,16 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_r
#pragma option push -w-8008 -w-8066 -w-8004
#endif
const re_repeat* rep = static_cast<const re_repeat*>(pstate);
const re_set_long* set = static_cast<const re_set_long*>(pstate->next.p);
const re_set_long<typename traits::char_class_type>* set = static_cast<const re_set_long<typename traits::char_class_type>*>(pstate->next.p);
unsigned count = 0;
//
// start by working out how much we can skip:
//
unsigned desired = rep->greedy ? rep->max : rep->min;
std::size_t desired = rep->greedy ? rep->max : rep->min;
if(::boost::is_random_access_iterator<BidiIterator>::value)
{
BidiIterator end = position;
std::advance(end, std::min((unsigned)re_detail::distance(position, last), desired));
std::advance(end, (std::min)((unsigned)re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (position != re_is_set_member(position, last, set, re)))
{
@ -646,7 +662,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_r
BidiIterator save_pos;
do
{
while((position != last) && (count < rep->max) && !access::can_start(*position, rep->_map, mask_skip))
while((position != last) && (count < rep->max) && !can_start(*position, rep->_map, mask_skip))
{
if(position != re_is_set_member(position, last, set, re))
{
@ -667,8 +683,16 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_r
return false;
if(position == last)
return false;
position = ++save_pos;
++count;
position = save_pos;
if(position != re_is_set_member(position, last, set, re))
{
++position;
++count;
}
else
{
return false;
}
}while(true);
#ifdef __BORLANDC__
#pragma option pop
@ -678,8 +702,8 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::match_long_set_r
#endif
}
template <class BidiIterator, class Allocator, class traits, class Allocator2>
bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::backtrack_till_match(unsigned count)
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::backtrack_till_match(unsigned count)
{
#ifdef BOOST_MSVC
#pragma warning(push)
@ -708,7 +732,7 @@ bool perl_matcher<BidiIterator, Allocator, traits, Allocator2>::backtrack_till_m
}
do
{
while(count && !access::can_start(*position, rep->_map, mask_skip))
while(count && !can_start(*position, rep->_map, mask_skip))
{
--position;
--count;

View File

@ -33,32 +33,53 @@ class BOOST_REGEX_DECL regbase
public:
enum flag_type_
{
escape_in_lists = 1, // '\' special inside [...]
char_classes = escape_in_lists << 1, // [[:CLASS:]] allowed
intervals = char_classes << 1, // {x,y} allowed
limited_ops = intervals << 1, // all of + ? and | are normal characters
newline_alt = limited_ops << 1, // \n is the same as |
bk_plus_qm = newline_alt << 1, // uses \+ and \?
bk_braces = bk_plus_qm << 1, // uses \{ and \}
bk_parens = bk_braces << 1, // uses \( and \)
bk_refs = bk_parens << 1, // \d allowed
bk_vbar = bk_refs << 1, // uses \|
//
// Divide the flags up into logical groups:
// bits 0-7 indicate main synatx type.
// bits 8-15 indicate syntax subtype.
// bits 16-31 indicate options that are common to all
// regex syntaxes.
// In all cases the default is 0.
//
// Main synatx group:
//
perl_syntax_group = 0, // default
basic_syntax_group = 1, // POSIX basic
literal = 2, // all characters are literals
main_option_type = literal | basic_syntax_group | perl_syntax_group, // everything!
//
// options specific to perl group:
//
no_bk_refs = 1 << 8, // \d not allowed
no_perl_ex = 1 << 9, // disable perl extensions
use_except = bk_vbar << 1, // exception on error
failbit = use_except << 1, // error flag
literal = failbit << 1, // all characters are literals
icase = literal << 1, // characters are matched regardless of case
nocollate = 0, // don't use locale specific collation (deprecated)
collate = icase << 1, // use locale specific collation
perlex = collate << 1, // perl extensions
nosubs = perlex << 1, // don't mark sub-expressions
optimize = 0, // not really supported
//
// options specific to basic group:
//
no_char_classes = 1 << 8, // [[:CLASS:]] not allowed
no_intervals = 1 << 9, // {x,y} not allowed
bk_plus_qm = 1 << 10, // uses \+ and \?
basic = char_classes | intervals | limited_ops | bk_braces | bk_parens | bk_refs | collate,
extended = char_classes | intervals | bk_refs | collate,
normal = perlex | escape_in_lists | char_classes | intervals | bk_refs | nocollate,
emacs = bk_braces | bk_parens | bk_refs | bk_vbar,
awk = extended | escape_in_lists,
//
// options common to all groups:
//
no_escape_in_lists = 1 << 16, // '\' not special inside [...]
newline_alt = 1 << 17, // \n is the same as |
no_except = 1 << 18, // no exception on error
failbit = 1 << 19, // error flag
icase = 1 << 20, // characters are matched regardless of case
nocollate = 0, // don't use locale specific collation (deprecated)
collate = 1 << 21, // use locale specific collation
nosubs = 1 << 22, // don't mark sub-expressions
optimize = 0, // not really supported
basic = basic_syntax_group | collate,
extended = no_bk_refs | collate | no_perl_ex | no_escape_in_lists,
normal = 0,
emacs = basic | no_char_classes | no_intervals,
awk = no_bk_refs | collate | no_perl_ex,
grep = basic | newline_alt,
egrep = extended | newline_alt,
sed = basic,
@ -80,18 +101,6 @@ public:
restart_fixed_lit = 6,
restart_count = 7
};
flag_type BOOST_REGEX_CALL flags()const
{
return _flags;
}
regbase();
regbase(const regbase& b);
void swap(regbase& that)
{ std::swap(_flags, that._flags); }
protected:
flag_type _flags;
};
//
@ -101,24 +110,13 @@ namespace regex_constants{
enum flag_type_
{
escape_in_lists = ::boost::regbase::escape_in_lists,
char_classes = ::boost::regbase::char_classes,
intervals = ::boost::regbase::intervals,
limited_ops = ::boost::regbase::limited_ops,
newline_alt = ::boost::regbase::newline_alt,
bk_plus_qm = ::boost::regbase::bk_plus_qm,
bk_braces = ::boost::regbase::bk_braces,
bk_parens = ::boost::regbase::bk_parens,
bk_refs = ::boost::regbase::bk_refs,
bk_vbar = ::boost::regbase::bk_vbar,
use_except = ::boost::regbase::use_except,
no_except = ::boost::regbase::no_except,
failbit = ::boost::regbase::failbit,
literal = ::boost::regbase::literal,
icase = ::boost::regbase::icase,
nocollate = ::boost::regbase::nocollate,
collate = ::boost::regbase::collate,
perlex = ::boost::regbase::perlex,
nosubs = ::boost::regbase::nosubs,
optimize = ::boost::regbase::optimize,

View File

@ -13,7 +13,7 @@
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares boost::reg_expression<> and associated
* DESCRIPTION: Declares boost::basic_regex<> and associated
* functions and classes. This header is the main
* entry point for the template regex code.
*/
@ -76,6 +76,12 @@
#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP
#include <boost/regex/v4/basic_regex.hpp>
#endif
#ifndef BOOST_REGEX_V4_BASIC_REGEX_CREATOR_HPP
#include <boost/regex/v4/basic_regex_creator.hpp>
#endif
#ifndef BOOST_REGEX_V4_BASIC_REGEX_PARSER_HPP
#include <boost/regex/v4/basic_regex_parser.hpp>
#endif
#ifndef BOOST_REGEX_V4_SUB_MATCH_HPP
#include <boost/regex/v4/sub_match.hpp>
#endif
@ -85,9 +91,6 @@
#ifndef BOOST_REGEX_V4_MATCH_RESULTS_HPP
#include <boost/regex/v4/match_results.hpp>
#endif
#ifndef BOOST_REGEX_COMPILE_HPP
#include <boost/regex/v4/regex_compile.hpp>
#endif
//
// template instances:
@ -96,7 +99,7 @@
#ifdef BOOST_REGEX_NARROW_INSTANTIATE
# define BOOST_REGEX_INSTANTIATE
#endif
#include <boost/regex/v4/instances.hpp>
//#include <boost/regex/v4/instances.hpp>
#undef BOOST_REGEX_CHAR_T
#ifdef BOOST_REGEX_INSTANTIATE
# undef BOOST_REGEX_INSTANTIATE
@ -107,7 +110,7 @@
#ifdef BOOST_REGEX_WIDE_INSTANTIATE
# define BOOST_REGEX_INSTANTIATE
#endif
#include <boost/regex/v4/instances.hpp>
//#include <boost/regex/v4/instances.hpp>
#undef BOOST_REGEX_CHAR_T
#ifdef BOOST_REGEX_INSTANTIATE
# undef BOOST_REGEX_INSTANTIATE
@ -117,9 +120,9 @@
namespace boost{
#ifdef BOOST_REGEX_NO_FWD
typedef reg_expression<char, regex_traits<char>, BOOST_DEFAULT_ALLOCATOR(char)> regex;
typedef basic_regex<char, regex_traits<char> > regex;
#ifndef BOOST_NO_WREGEX
typedef reg_expression<wchar_t, regex_traits<wchar_t>, BOOST_DEFAULT_ALLOCATOR(wchar_t)> wregex;
typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
#endif
#endif
@ -131,6 +134,9 @@ typedef match_results<std::wstring::const_iterator> wsmatch;
#endif
} // namespace boost
#ifndef BOOST_REGEX_MATCHER_HPP
#include <boost/regex/v4/perl_matcher.hpp>
#endif
#ifndef BOOST_REGEX_MATCH_HPP
#include <boost/regex/v4/regex_match.hpp>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -31,7 +31,7 @@ namespace boost{
//
// Forward declaration:
//
template <class RandomAccessIterator, class Allocator>
template <class BidiIterator, class Allocator = BOOST_DEFAULT_ALLOCATOR(sub_match<BidiIterator> ) >
class match_results;
namespace re_detail{
@ -55,20 +55,19 @@ void BOOST_REGEX_CALL re_skip_format(const charT*& fmt, const traits_type& trait
(void)traits_inst;
typedef typename traits_type::size_type traits_size_type;
typedef typename traits_type::uchar_type traits_uchar_type;
typedef typename traits_type::string_type traits_string_type;
unsigned int parens = 0;
unsigned int c;
while(*fmt)
{
c = traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt));
if((c == traits_type::syntax_colon) && (parens == 0))
c = traits_inst.syntax_type(*fmt);
if((c == regex_constants::syntax_colon) && (parens == 0))
{
++fmt;
return;
}
else if(c == traits_type::syntax_close_bracket)
else if(c == regex_constants::syntax_close_mark)
{
if(parens == 0)
{
@ -77,9 +76,9 @@ void BOOST_REGEX_CALL re_skip_format(const charT*& fmt, const traits_type& trait
}
--parens;
}
else if(c == traits_type::syntax_open_bracket)
else if(c == regex_constants::syntax_open_mark)
++parens;
else if(c == traits_type::syntax_slash)
else if(c == regex_constants::syntax_escape)
{
++fmt;
if(*fmt == 0)
@ -133,9 +132,9 @@ namespace{
// is sent to an OutputIterator,
// _reg_format_aux does the actual work:
//
template <class OutputIterator, class Iterator, class Allocator, class charT, class traits_type>
template <class OutputIterator, class Iterator, class charT, class traits_type>
OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
const match_results<Iterator, Allocator>& m,
const match_results<Iterator>& m,
const charT*& fmt,
match_flag_type flags, const traits_type& traits_inst)
{
@ -146,14 +145,13 @@ OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
while(*fmt_end) ++ fmt_end;
typedef typename traits_type::size_type traits_size_type;
typedef typename traits_type::uchar_type traits_uchar_type;
typedef typename traits_type::string_type traits_string_type;
while(*fmt)
{
switch(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)))
switch(traits_inst.syntax_type(*fmt))
{
case traits_type::syntax_dollar:
case regex_constants::syntax_dollar:
if(flags & format_sed)
{
// no perl style replacement,
@ -168,20 +166,20 @@ OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
++out;
return out;
}
switch(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)))
switch(traits_inst.syntax_type(*fmt))
{
case traits_type::syntax_start_buffer:
case regex_constants::escape_type_start_buffer:
oi_assign(&out, re_copy_out(out, Iterator(m[-1].first), Iterator(m[-1].second)));
++fmt;
continue;
case traits_type::syntax_end_buffer:
case regex_constants::escape_type_end_buffer:
oi_assign(&out, re_copy_out(out, Iterator(m[-2].first), Iterator(m[-2].second)));
++fmt;
continue;
case traits_type::syntax_digit:
case regex_constants::syntax_digit:
{
expand_sub:
unsigned int index = traits_inst.toi(fmt, fmt_end, 10);
unsigned int index = parse_value(fmt, fmt_end, traits_inst, 10);
if(index < m.size())
oi_assign(&out, re_copy_out(out, Iterator(m[index].first), Iterator(m[index].second)));
continue;
@ -202,7 +200,7 @@ expand_sub:
++fmt;
}
continue;
case traits_type::syntax_slash:
case regex_constants::syntax_escape:
{
// escape sequence:
++fmt;
@ -215,33 +213,33 @@ expand_sub:
++fmt;
return out;
}
switch(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)))
switch(traits_inst.syntax_type(*fmt))
{
case traits_type::syntax_a:
case regex_constants::escape_type_control_a:
c = '\a';
++fmt;
break;
case traits_type::syntax_f:
case regex_constants::escape_type_control_f:
c = '\f';
++fmt;
break;
case traits_type::syntax_n:
case regex_constants::escape_type_control_n:
c = '\n';
++fmt;
break;
case traits_type::syntax_r:
case regex_constants::escape_type_control_r:
c = '\r';
++fmt;
break;
case traits_type::syntax_t:
case regex_constants::escape_type_control_t:
c = '\t';
++fmt;
break;
case traits_type::syntax_v:
case regex_constants::escape_type_control_v:
c = '\v';
++fmt;
break;
case traits_type::syntax_x:
case regex_constants::escape_type_hex:
++fmt;
if(fmt == fmt_end)
{
@ -250,7 +248,7 @@ expand_sub:
return out;
}
// maybe have \x{ddd}
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)) == traits_type::syntax_open_brace)
if(traits_inst.syntax_type(*fmt) == regex_constants::syntax_open_brace)
{
++fmt;
if(fmt == fmt_end)
@ -261,7 +259,8 @@ expand_sub:
++fmt;
continue;
}
if(traits_inst.is_class(*fmt, traits_type::char_class_xdigit) == false)
int val = parse_value(fmt, fmt_end, traits_inst, 16);
if(val < 0)
{
fmt -= 2;
*out = *fmt;
@ -269,10 +268,10 @@ expand_sub:
++fmt;
continue;
}
c = (charT)traits_inst.toi(fmt, fmt_end, -16);
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)) != traits_type::syntax_close_brace)
c = static_cast<charT>(val);
if(traits_inst.syntax_type(*fmt) != regex_constants::syntax_close_brace)
{
while(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)) != traits_type::syntax_slash)
while(traits_inst.syntax_type(*fmt) != regex_constants::syntax_escape)
--fmt;
++fmt;
*out = *fmt;
@ -285,7 +284,8 @@ expand_sub:
}
else
{
if(traits_inst.is_class(*fmt, traits_type::char_class_xdigit) == false)
int val = parse_value(fmt, fmt_end, traits_inst, 16);
if(val < 0)
{
--fmt;
*out = *fmt;
@ -293,10 +293,10 @@ expand_sub:
++fmt;
continue;
}
c = (charT)traits_inst.toi(fmt, fmt_end, -16);
c = static_cast<charT>(val);
}
break;
case traits_type::syntax_c:
case regex_constants::escape_type_ascii_control:
++fmt;
if(fmt == fmt_end)
{
@ -305,8 +305,7 @@ expand_sub:
++out;
return out;
}
if(((typename traits_type::uchar_type)(*fmt) < (typename traits_type::uchar_type)'@')
|| ((typename traits_type::uchar_type)(*fmt) > (typename traits_type::uchar_type)127) )
if( (*fmt < static_cast<charT>('@')) || (*fmt > static_cast<charT>('z')) )
{
--fmt;
*out = *fmt;
@ -314,18 +313,18 @@ expand_sub:
++fmt;
break;
}
c = (charT)((typename traits_type::uchar_type)(*fmt) - (typename traits_type::uchar_type)'@');
c = static_cast<charT>(*fmt - static_cast<charT>('@'));
++fmt;
break;
case traits_type::syntax_e:
case regex_constants::escape_type_e:
c = (charT)27;
++fmt;
break;
case traits_type::syntax_digit:
case regex_constants::syntax_digit:
if(flags & format_sed)
goto expand_sub;
else
c = (charT)traits_inst.toi(fmt, fmt_end, -8);
c = static_cast<charT>(parse_value(fmt, fmt_end, traits_inst, 8));
break;
default:
//c = *fmt;
@ -335,7 +334,7 @@ expand_sub:
++out;
continue;
}
case traits_type::syntax_open_bracket:
case regex_constants::syntax_open_mark:
if(0 == (flags & format_all))
{
*out = *fmt;
@ -349,7 +348,7 @@ expand_sub:
oi_assign(&out, _reg_format_aux(out, m, fmt, flags, traits_inst));
continue;
}
case traits_type::syntax_close_bracket:
case regex_constants::syntax_close_mark:
if(0 == (flags & format_all))
{
*out = *fmt;
@ -362,7 +361,7 @@ expand_sub:
++fmt; // return from recursion
return out;
}
case traits_type::syntax_colon:
case regex_constants::syntax_colon:
if(flags & regex_constants::format_is_if)
{
++fmt;
@ -372,7 +371,7 @@ expand_sub:
++out;
++fmt;
continue;
case traits_type::syntax_question:
case regex_constants::syntax_question:
{
if(0 == (flags & format_all))
{
@ -392,17 +391,17 @@ expand_sub:
++fmt;
return out;
}
unsigned int id = traits_inst.toi(fmt, fmt_end, 10);
unsigned int id = parse_value(fmt, fmt_end, traits_inst, 10);
if(m[id].matched)
{
oi_assign(&out, _reg_format_aux(out, m, fmt, flags | regex_constants::format_is_if, traits_inst));
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*(fmt-1))) == traits_type::syntax_colon)
if(traits_inst.syntax_type(*(fmt-1)) == regex_constants::syntax_colon)
re_skip_format(fmt, traits_inst);
}
else
{
re_skip_format(fmt, traits_inst);
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*(fmt-1))) == traits_type::syntax_colon)
if(traits_inst.syntax_type(*(fmt-1)) == regex_constants::syntax_colon)
oi_assign(&out, _reg_format_aux(out, m, fmt, flags | regex_constants::format_is_if, traits_inst));
}
return out;
@ -448,7 +447,7 @@ public:
}
};
template <class OutputIterator, class Iterator, class charT, class Allocator, class traits_type>
template <class OutputIterator, class Iterator, class charT, class traits_type>
class merge_out_predicate
{
OutputIterator* out;
@ -456,15 +455,13 @@ class merge_out_predicate
const charT* fmt;
match_flag_type flags;
const traits_type* pt;
// rebind allocator to correct type:
typedef typename detail::rebind_allocator<sub_match<Iterator>, Allocator>::type alloc_type;
public:
merge_out_predicate(OutputIterator& o, Iterator& pi, const charT* f, match_flag_type format_flags, const traits_type& p)
: out(&o), last(&pi), fmt(f), flags(format_flags), pt(&p){}
~merge_out_predicate() {}
bool BOOST_REGEX_CALL operator()(const boost::match_results<Iterator, alloc_type>& m)
bool BOOST_REGEX_CALL operator()(const boost::match_results<Iterator>& m)
{
const charT* f = fmt;
if(0 == (flags & format_no_copy))
@ -477,9 +474,9 @@ public:
} // namespace re_detail
template <class OutputIterator, class Iterator, class Allocator, class charT>
template <class OutputIterator, class Iterator, class charT>
OutputIterator regex_format(OutputIterator out,
const match_results<Iterator, Allocator>& m,
const match_results<Iterator>& m,
const charT* fmt,
match_flag_type flags = format_all
)
@ -488,9 +485,9 @@ OutputIterator regex_format(OutputIterator out,
return re_detail::_reg_format_aux(out, m, fmt, flags, t);
}
template <class OutputIterator, class Iterator, class Allocator, class charT>
template <class OutputIterator, class Iterator, class charT>
OutputIterator regex_format(OutputIterator out,
const match_results<Iterator, Allocator>& m,
const match_results<Iterator>& m,
const std::basic_string<charT>& fmt,
match_flag_type flags = format_all
)
@ -500,8 +497,8 @@ OutputIterator regex_format(OutputIterator out,
return re_detail::_reg_format_aux(out, m, start, flags, t);
}
template <class Iterator, class Allocator, class charT>
std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>& m,
template <class Iterator, class charT>
std::basic_string<charT> regex_format(const match_results<Iterator>& m,
const charT* fmt,
match_flag_type flags = format_all)
{
@ -511,8 +508,8 @@ std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>&
return result;
}
template <class Iterator, class Allocator, class charT>
std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>& m,
template <class Iterator, class charT>
std::basic_string<charT> regex_format(const match_results<Iterator>& m,
const std::basic_string<charT>& fmt,
match_flag_type flags = format_all)
{

View File

@ -13,7 +13,7 @@
* LOCATION: see http://www.boost.org for most recent version.
* FILE regex_fwd.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Forward declares boost::reg_expression<> and
* DESCRIPTION: Forward declares boost::basic_regex<> and
* associated typedefs.
*/
@ -23,7 +23,6 @@
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/config.hpp>
#endif
#include <boost/detail/allocator.hpp>
//
// define BOOST_REGEX_NO_FWD if this
@ -46,16 +45,17 @@
namespace boost{
template <class charT>
class regex_traits;
class cpp_regex_traits;
template <class charT, class traits = regex_traits<charT>, class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
class reg_expression;
template <class charT, class traits = regex_traits<charT>, class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
template <class charT, class implementationT = cpp_regex_traits<charT> >
struct regex_traits;
template <class charT, class traits = regex_traits<charT> >
class basic_regex;
typedef basic_regex<char, regex_traits<char>, BOOST_DEFAULT_ALLOCATOR(char) > regex;
typedef basic_regex<char, regex_traits<char> > regex;
#ifndef BOOST_NO_WREGEX
typedef basic_regex<wchar_t, regex_traits<wchar_t>, BOOST_DEFAULT_ALLOCATOR(wchar_t) > wregex;
typedef basic_regex<wchar_t, regex_traits<wchar_t> > wregex;
#endif
} // namespace boost

View File

@ -30,21 +30,20 @@ namespace boost{
// regex_grep:
// find all non-overlapping matches within the sequence first last:
//
template <class Predicate, class BidiIterator, class charT, class traits, class Allocator>
template <class Predicate, class BidiIterator, class charT, class traits>
inline unsigned int regex_grep(Predicate foo,
BidiIterator first,
BidiIterator last,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
if(e.flags() & regex_constants::failbit)
return false;
typedef detail::rebind_allocator<sub_match<BidiIterator>, Allocator> binder;
typedef typename binder::type match_allocator_type;
//typedef Allocator match_allocator_type;
match_results<BidiIterator, match_allocator_type> m;
re_detail::perl_matcher<BidiIterator, match_allocator_type, traits, Allocator> matcher(first, last, m, e, flags);
typedef typename match_results<BidiIterator>::allocator_type match_allocator_type;
match_results<BidiIterator> m;
re_detail::perl_matcher<BidiIterator, match_allocator_type, traits> matcher(first, last, m, e, flags);
unsigned int count = 0;
while(matcher.find())
{
@ -86,17 +85,17 @@ inline unsigned int regex_grep(Predicate foo,
// this isn't really a partial specialisation, but template function
// overloading - if the compiler doesn't support partial specialisation
// then it really won't support this either:
template <class Predicate, class charT, class Allocator, class traits>
template <class Predicate, class charT, class traits>
inline unsigned int regex_grep(Predicate foo, const charT* str,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_grep(foo, str, str + traits::length(str), e, flags);
}
template <class Predicate, class ST, class SA, class Allocator, class charT, class traits>
template <class Predicate, class ST, class SA, class charT, class traits>
inline unsigned int regex_grep(Predicate foo, const std::basic_string<charT, ST, SA>& s,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_grep(foo, s.begin(), s.end(), e, flags);

View File

@ -29,11 +29,10 @@ namespace boost{
template <class BidirectionalIterator,
class charT,
class traits,
class Allocator>
class traits>
class regex_iterator_implementation
{
typedef basic_regex<charT, traits, Allocator> regex_type;
typedef basic_regex<charT, traits> regex_type;
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator base; // start of sequence
@ -73,15 +72,22 @@ public:
template <class BidirectionalIterator,
class charT = BOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
class traits = regex_traits<charT>,
class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
class traits = regex_traits<charT> >
class regex_iterator
#ifndef BOOST_NO_STD_ITERATOR
: public std::iterator<
std::forward_iterator_tag,
match_results<BidirectionalIterator>,
typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
const match_results<BidirectionalIterator>*,
const match_results<BidirectionalIterator>& >
#endif
{
private:
typedef regex_iterator_implementation<BidirectionalIterator, charT, traits, Allocator> impl;
typedef regex_iterator_implementation<BidirectionalIterator, charT, traits> impl;
typedef shared_ptr<impl> pimpl;
public:
typedef basic_regex<charT, traits, Allocator> regex_type;
typedef basic_regex<charT, traits> regex_type;
typedef match_results<BidirectionalIterator> value_type;
typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type
difference_type;

View File

@ -22,14 +22,6 @@
#ifndef BOOST_REGEX_MATCH_HPP
#define BOOST_REGEX_MATCH_HPP
#ifndef BOOST_REGEX_MAX_STATE_COUNT
# define BOOST_REGEX_MAX_STATE_COUNT 100000000
#endif
#include <boost/limits.hpp>
#include <boost/regex/v4/perl_matcher.hpp>
namespace boost{
#ifdef BOOST_HAS_ABI_HEADERS
@ -41,18 +33,18 @@ namespace boost{
// returns true if the specified regular expression matches
// the whole of the input. Fills in what matched in m.
//
template <class BidiIterator, class Allocator, class charT, class traits, class Allocator2>
template <class BidiIterator, class Allocator, class charT, class traits>
bool regex_match(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
re_detail::perl_matcher<BidiIterator, Allocator, traits, Allocator2> matcher(first, last, m, e, flags);
re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags);
return matcher.match();
}
template <class iterator, class charT, class traits, class Allocator2>
template <class iterator, class charT, class traits>
bool regex_match(iterator first, iterator last,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
match_results<iterator> m;
@ -65,35 +57,35 @@ bool regex_match(iterator first, iterator last,
// this isn't really a partial specialisation, but template function
// overloading - if the compiler doesn't support partial specialisation
// then it really won't support this either:
template <class charT, class Allocator, class traits, class Allocator2>
template <class charT, class Allocator, class traits>
inline bool regex_match(const charT* str,
match_results<const charT*, Allocator>& m,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_match(str, str + traits::length(str), m, e, flags);
}
template <class ST, class SA, class Allocator, class charT, class traits, class Allocator2>
template <class ST, class SA, class Allocator, class charT, class traits>
inline bool regex_match(const std::basic_string<charT, ST, SA>& s,
match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_match(s.begin(), s.end(), m, e, flags);
}
template <class charT, class traits, class Allocator2>
template <class charT, class traits>
inline bool regex_match(const charT* str,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
match_results<const charT*> m;
return regex_match(str, str + traits::length(str), m, e, flags);
}
template <class ST, class SA, class charT, class traits, class Allocator2>
template <class ST, class SA, class charT, class traits>
inline bool regex_match(const std::basic_string<charT, ST, SA>& s,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
typedef typename std::basic_string<charT, ST, SA>::const_iterator iterator;
@ -142,7 +134,7 @@ inline bool regex_match(const std::string& s,
const regex& e,
match_flag_type flags = match_default)
{
match_results<std::string::const_iterator, regex::allocator_type> m;
match_results<std::string::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
#if !defined(BOOST_NO_WREGEX)
@ -157,7 +149,7 @@ inline bool regex_match(const std::basic_string<wchar_t>& s,
const wregex& e,
match_flag_type flags = match_default)
{
match_results<std::basic_string<wchar_t>::const_iterator, wregex::allocator_type> m;
match_results<std::basic_string<wchar_t>::const_iterator> m;
return regex_match(s.begin(), s.end(), m, e, flags);
}
#endif

View File

@ -28,40 +28,40 @@ namespace boost{
# include BOOST_ABI_PREFIX
#endif
template <class OutputIterator, class Iterator, class traits, class Allocator, class charT>
template <class OutputIterator, class Iterator, class traits, class charT>
inline OutputIterator regex_merge(OutputIterator out,
Iterator first,
Iterator last,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const charT* fmt,
match_flag_type flags = match_default)
{
return regex_replace(out, first, last, e, fmt, flags);
}
template <class OutputIterator, class Iterator, class traits, class Allocator, class charT>
template <class OutputIterator, class Iterator, class traits, class charT>
inline OutputIterator regex_merge(OutputIterator out,
Iterator first,
Iterator last,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const std::basic_string<charT>& fmt,
match_flag_type flags = match_default)
{
return regex_merge(out, first, last, e, fmt.c_str(), flags);
}
template <class traits, class Allocator, class charT>
template <class traits, class charT>
inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const charT* fmt,
match_flag_type flags = match_default)
{
return regex_replace(s, e, fmt, flags);
}
template <class traits, class Allocator, class charT>
template <class traits, class charT>
inline std::basic_string<charT> regex_merge(const std::basic_string<charT>& s,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const std::basic_string<charT>& fmt,
match_flag_type flags = match_default)
{

View File

@ -93,43 +93,33 @@ enum{
//
// class raw_storage
// basically this is a simplified vector<unsigned char>
// this is used by reg_expression for expression storage
// this is used by basic_regex for expression storage
//
template <class Allocator>
class raw_storage
{
public:
typedef Allocator allocator_type;
typedef typename boost::detail::rebind_allocator<unsigned char, allocator_type>::type alloc_inst_type;
typedef typename alloc_inst_type::size_type size_type;
typedef typename alloc_inst_type::pointer pointer;
typedef std::size_t size_type;
typedef unsigned char* pointer;
private:
//
// empty member optimisation:
struct alloc_data : public alloc_inst_type
{
typename alloc_inst_type::pointer last;
alloc_data(const Allocator& a) : alloc_inst_type(a){}
} alloc_inst;
pointer start, end;
pointer last, start, end;
public:
raw_storage(const Allocator& a = Allocator());
raw_storage(size_type n, const Allocator& a = Allocator());
raw_storage();
raw_storage(size_type n);
~raw_storage()
{
alloc_inst.deallocate(start, (alloc_inst.last - start));
::operator delete(start);
}
void BOOST_REGEX_CALL resize(size_type n);
void* BOOST_REGEX_CALL extend(size_type n)
{
if(size_type(alloc_inst.last - end) < n)
if(size_type(last - end) < n)
resize(n + (end - start));
register void* result = end;
register pointer result = end;
end += n;
return result;
}
@ -143,7 +133,7 @@ public:
size_type BOOST_REGEX_CALL capacity()
{
return alloc_inst.last - start;
return last - start;
}
void* BOOST_REGEX_CALL data()const
@ -153,7 +143,7 @@ public:
size_type BOOST_REGEX_CALL index(void* ptr)
{
return reinterpret_cast<unsigned char*>(ptr) - reinterpret_cast<unsigned char*>(data());
return static_cast<pointer>(ptr) - static_cast<pointer>(data());
}
void BOOST_REGEX_CALL clear()
@ -164,78 +154,28 @@ public:
void BOOST_REGEX_CALL align()
{
// move end up to a boundary:
end = reinterpret_cast<unsigned char*>(start) + (((reinterpret_cast<unsigned char*>(end) - reinterpret_cast<unsigned char*>(start)) + padding_mask) & ~padding_mask);
end = start + (((end - start) + padding_mask) & ~padding_mask);
}
Allocator BOOST_REGEX_CALL allocator()const;
void swap(raw_storage& that)
{
std::swap(start, that.start);
std::swap(end, that.end);
std::swap(alloc_inst.last, that.alloc_inst.last);
std::swap(static_cast<alloc_inst_type&>(alloc_inst), static_cast<alloc_inst_type&>(that.alloc_inst));
std::swap(last, that.last);
}
};
template <class Allocator>
raw_storage<Allocator>::raw_storage(const Allocator& a)
: alloc_inst(a)
inline raw_storage::raw_storage()
{
start = end = alloc_inst.allocate(1024);
BOOST_REGEX_NOEH_ASSERT(start)
alloc_inst.last = start + 1024;
last = start = end = 0;
}
template <class Allocator>
raw_storage<Allocator>::raw_storage(size_type n, const Allocator& a)
: alloc_inst(a)
inline raw_storage::raw_storage(size_type n)
{
start = end = alloc_inst.allocate(n);
BOOST_REGEX_NOEH_ASSERT(start)
alloc_inst.last = start + n;
start = end = static_cast<pointer>(::operator new(n));
BOOST_REGEX_NOEH_ASSERT(start)
last = start + n;
}
template <class Allocator>
Allocator BOOST_REGEX_CALL raw_storage<Allocator>::allocator()const
{
return alloc_inst;
}
template <class Allocator>
void BOOST_REGEX_CALL raw_storage<Allocator>::resize(size_type n)
{
register size_type newsize = (alloc_inst.last - start) * 2;
register size_type datasize = end - start;
if(newsize < n)
newsize = n;
// extend newsize to WORD/DWORD boundary:
newsize = (newsize + padding_mask) & ~(padding_mask);
// allocate and copy data:
register unsigned char* ptr = alloc_inst.allocate(newsize);
BOOST_REGEX_NOEH_ASSERT(ptr)
std::memcpy(ptr, start, datasize);
// get rid of old buffer:
alloc_inst.deallocate(start, (alloc_inst.last - start));
// and set up pointers:
start = ptr;
end = ptr + datasize;
alloc_inst.last = ptr + newsize;
}
template <class Allocator>
void* BOOST_REGEX_CALL raw_storage<Allocator>::insert(size_type pos, size_type n)
{
jm_assert(pos <= size_type(end - start));
if(size_type(alloc_inst.last - end) < n)
resize(n + (end - start));
register void* result = start + pos;
std::memmove(start + pos + n, start + pos, (end - start) - pos);
end += n;
return result;
}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX

View File

@ -28,34 +28,34 @@ namespace boost{
# include BOOST_ABI_PREFIX
#endif
template <class OutputIterator, class Iterator, class traits, class Allocator, class charT>
template <class OutputIterator, class Iterator, class traits, class charT>
OutputIterator regex_replace(OutputIterator out,
Iterator first,
Iterator last,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const charT* fmt,
match_flag_type flags = match_default)
{
Iterator l = first;
re_detail::merge_out_predicate<OutputIterator, Iterator, charT, Allocator, traits> oi(out, l, fmt, flags, e.get_traits());
re_detail::merge_out_predicate<OutputIterator, Iterator, charT, traits> oi(out, l, fmt, flags, e.get_traits());
regex_grep(oi, first, last, e, flags);
return (flags & format_no_copy) ? out : re_detail::re_copy_out(out, l, last);
}
template <class OutputIterator, class Iterator, class traits, class Allocator, class charT>
template <class OutputIterator, class Iterator, class traits, class charT>
inline OutputIterator regex_replace(OutputIterator out,
Iterator first,
Iterator last,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const std::basic_string<charT>& fmt,
match_flag_type flags = match_default)
{
return regex_replace(out, first, last, e, fmt.c_str(), flags);
}
template <class traits, class Allocator, class charT>
template <class traits, class charT>
std::basic_string<charT> regex_replace(const std::basic_string<charT>& s,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const charT* fmt,
match_flag_type flags = match_default)
{
@ -65,9 +65,9 @@ std::basic_string<charT> regex_replace(const std::basic_string<charT>& s,
return result;
}
template <class traits, class Allocator, class charT>
template <class traits, class charT>
std::basic_string<charT> regex_replace(const std::basic_string<charT>& s,
const reg_expression<charT, traits, Allocator>& e,
const basic_regex<charT, traits>& e,
const std::basic_string<charT>& fmt,
match_flag_type flags = match_default)
{

View File

@ -26,16 +26,16 @@ namespace boost{
# include BOOST_ABI_PREFIX
#endif
template <class BidiIterator, class Allocator, class charT, class traits, class Allocator2>
template <class BidiIterator, class Allocator, class charT, class traits>
bool regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator, Allocator>& m,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
if(e.flags() & regex_constants::failbit)
return false;
re_detail::perl_matcher<BidiIterator, Allocator, traits, Allocator2> matcher(first, last, m, e, flags);
re_detail::perl_matcher<BidiIterator, Allocator, traits> matcher(first, last, m, e, flags);
return matcher.find();
}
@ -46,19 +46,19 @@ bool regex_search(BidiIterator first, BidiIterator last,
// this isn't really a partial specialisation, but template function
// overloading - if the compiler doesn't support partial specialisation
// then it really won't support this either:
template <class charT, class Allocator, class traits, class Allocator2>
template <class charT, class Allocator, class traits>
inline bool regex_search(const charT* str,
match_results<const charT*, Allocator>& m,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(str, str + traits::length(str), m, e, flags);
}
template <class ST, class SA, class Allocator, class charT, class traits, class Allocator2>
template <class ST, class SA, class Allocator, class charT, class traits>
inline bool regex_search(const std::basic_string<charT, ST, SA>& s,
match_results<typename std::basic_string<charT, ST, SA>::const_iterator, Allocator>& m,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(s.begin(), s.end(), m, e, flags);
@ -99,9 +99,9 @@ inline bool regex_search(const std::basic_string<wchar_t>& s,
#endif
template <class BidiIterator, class charT, class traits, class Allocator2>
template <class BidiIterator, class charT, class traits>
bool regex_search(BidiIterator first, BidiIterator last,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
if(e.flags() & regex_constants::failbit)
@ -109,23 +109,23 @@ bool regex_search(BidiIterator first, BidiIterator last,
match_results<BidiIterator> m;
typedef typename match_results<BidiIterator>::allocator_type match_alloc_type;
re_detail::perl_matcher<BidiIterator, match_alloc_type, traits, Allocator2> matcher(first, last, m, e, flags);
re_detail::perl_matcher<BidiIterator, match_alloc_type, traits> matcher(first, last, m, e, flags);
return matcher.find();
}
#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
template <class charT, class traits, class Allocator2>
template <class charT, class traits>
inline bool regex_search(const charT* str,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(str, str + traits::length(str), e, flags);
}
template <class ST, class SA, class charT, class traits, class Allocator2>
template <class ST, class SA, class charT, class traits>
inline bool regex_search(const std::basic_string<charT, ST, SA>& s,
const reg_expression<charT, traits, Allocator2>& e,
const basic_regex<charT, traits>& e,
match_flag_type flags = match_default)
{
return regex_search(s.begin(), s.end(), e, flags);

View File

@ -30,14 +30,14 @@ namespace boost{
namespace re_detail{
template <class charT>
const reg_expression<charT>& get_default_expression(charT)
const basic_regex<charT>& get_default_expression(charT)
{
static const charT expression_text[4] = { '\\', 's', '+', '\00', };
static const reg_expression<charT> e(expression_text);
static const basic_regex<charT> e(expression_text);
return e;
}
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
template <class OutputIterator, class charT, class Traits1, class Alloc1>
class split_pred
{
typedef std::basic_string<charT, Traits1, Alloc1> string_type;
@ -50,12 +50,12 @@ public:
split_pred(iterator_type* a, OutputIterator* b, std::size_t* c)
: p_last(a), p_out(b), p_max(c), initial_max(*c) {}
bool operator()(const match_results<iterator_type, Alloc2>& what);
bool operator()(const match_results<iterator_type>& what);
};
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Alloc2>
bool split_pred<OutputIterator, charT, Traits1, Alloc1, Alloc2>::operator()
(const match_results<iterator_type, Alloc2>& what)
template <class OutputIterator, class charT, class Traits1, class Alloc1>
bool split_pred<OutputIterator, charT, Traits1, Alloc1>::operator()
(const match_results<iterator_type>& what)
{
*p_last = what[0].second;
if(what.size() > 1)
@ -87,18 +87,18 @@ bool split_pred<OutputIterator, charT, Traits1, Alloc1, Alloc2>::operator()
} // namespace re_detail
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
std::size_t regex_split(OutputIterator out,
std::basic_string<charT, Traits1, Alloc1>& s,
const reg_expression<charT, Traits2, Alloc2>& e,
const basic_regex<charT, Traits2>& e,
match_flag_type flags,
std::size_t max_split)
{
typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
typedef typename detail::rebind_allocator<sub_match<ci_t>, Alloc2>::type match_allocator;
typedef typename std::basic_string<charT, Traits1, Alloc1>::const_iterator ci_t;
typedef typename match_results<ci_t>::allocator_type match_allocator;
ci_t last = s.begin();
std::size_t init_size = max_split;
re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1, match_allocator> pred(&last, &out, &max_split);
re_detail::split_pred<OutputIterator, charT, Traits1, Alloc1> pred(&last, &out, &max_split);
ci_t i, j;
i = s.begin();
j = s.end();
@ -122,10 +122,10 @@ std::size_t regex_split(OutputIterator out,
return init_size - max_split;
}
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2, class Alloc2>
template <class OutputIterator, class charT, class Traits1, class Alloc1, class Traits2>
inline std::size_t regex_split(OutputIterator out,
std::basic_string<charT, Traits1, Alloc1>& s,
const reg_expression<charT, Traits2, Alloc2>& e,
const basic_regex<charT, Traits2>& e,
match_flag_type flags = match_default)
{
return regex_split(out, s, e, flags, UINT_MAX);

View File

@ -177,7 +177,7 @@ void BOOST_REGEX_CALL jstack<T, Allocator>::pop_aux()const
{
// make sure that we have a valid item
// on TOS:
jm_assert(m_stack->next);
BOOST_ASSERT(m_stack->next);
register node* p = m_stack;
m_stack = p->next;
p->next = unused;

View File

@ -1,210 +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_synch.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Thread synchronisation for regex code.
* Note this is an internal header file included
* by regex.hpp, do not include on its own.
*/
#ifndef BOOST_REGEX_SYNCH_HPP
#define BOOST_REGEX_SYNCH_HPP
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#if defined(BOOST_HAS_THREADS)
# if defined(BOOST_HAS_WINTHREADS)
# include <windows.h>
# elif defined(BOOST_HAS_BETHREADS)
# include <OS.h>
# include <cassert>
# elif defined(BOOST_HAS_PTHREADS)
# include <pthread.h>
# else
# error "Unknown threading API"
# endif
#endif
namespace boost{
namespace re_detail{
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
void BOOST_REGEX_CALL re_init_threads();
void BOOST_REGEX_CALL re_free_threads();
#ifdef BOOST_HAS_THREADS
# ifdef BOOST_HAS_BETHREADS
typedef sem_id CRITICAL_SECTION;
inline void BOOST_REGEX_CALL InitializeCriticalSection(CRITICAL_SECTION* ps)
{
*ps = create_sem(1, "regex++");
assert(*ps > 0);
}
inline void BOOST_REGEX_CALL DeleteCriticalSection(CRITICAL_SECTION* ps)
{
int t = delete_sem(*ps);
assert(t == B_NO_ERROR);
}
inline void BOOST_REGEX_CALL EnterCriticalSection(CRITICAL_SECTION* ps)
{
status_t t = acquire_sem(*ps);
assert(t == B_NO_ERROR);
}
inline void BOOST_REGEX_CALL LeaveCriticalSection(CRITICAL_SECTION* ps)
{
status_t t = release_sem(*ps);
assert(t == B_NO_ERROR);
}
# elif defined(BOOST_HAS_PTHREADS)
typedef pthread_mutex_t CRITICAL_SECTION;
inline void BOOST_REGEX_CALL InitializeCriticalSection(CRITICAL_SECTION* ps)
{
pthread_mutex_init(ps, 0);
}
inline void BOOST_REGEX_CALL DeleteCriticalSection(CRITICAL_SECTION* ps)
{
pthread_mutex_destroy(ps);
}
inline void BOOST_REGEX_CALL EnterCriticalSection(CRITICAL_SECTION* ps)
{
pthread_mutex_lock(ps);
}
inline void BOOST_REGEX_CALL LeaveCriticalSection(CRITICAL_SECTION* ps)
{
pthread_mutex_unlock(ps);
}
# elif !defined(BOOST_HAS_WINTHREADS)
# error "Unknown threading API"
# endif
template <class Lock>
class lock_guard
{
typedef Lock lock_type;
public:
lock_guard(lock_type& m, bool aq = true)
: mut(m), owned(false){ acquire(aq); }
~lock_guard()
{ acquire(false); }
void BOOST_REGEX_CALL acquire(bool aq = true)
{
if(aq && !owned)
{
mut.acquire(true);
owned = true;
}
else if(!aq && owned)
{
mut.acquire(false);
owned = false;
}
}
private:
lock_type& mut;
bool owned;
// VC6 warning suppression:
lock_guard& operator=(const lock_guard&);
};
class critical_section
{
public:
critical_section()
{ InitializeCriticalSection(&hmutex);}
critical_section(const critical_section&)
{ InitializeCriticalSection(&hmutex);}
const critical_section& BOOST_REGEX_CALL operator=(const critical_section&)
{return *this;}
~critical_section()
{DeleteCriticalSection(&hmutex);}
private:
void BOOST_REGEX_CALL acquire(bool aq)
{ if(aq) EnterCriticalSection(&hmutex);
else LeaveCriticalSection(&hmutex);
}
CRITICAL_SECTION hmutex;
public:
typedef lock_guard<critical_section> ro_guard;
typedef lock_guard<critical_section> rw_guard;
friend class lock_guard<critical_section>;
};
inline bool BOOST_REGEX_CALL operator==(const critical_section&, const critical_section&)
{
return false;
}
inline bool BOOST_REGEX_CALL operator<(const critical_section&, const critical_section&)
{
return true;
}
typedef lock_guard<critical_section> cs_guard;
BOOST_REGEX_DECL extern critical_section* p_re_lock;
BOOST_REGEX_DECL extern unsigned int re_lock_count;
#define BOOST_REGEX_GUARD(inst) boost::re_detail::critical_section::rw_guard g(inst);
#else // BOOST_HAS_THREADS
#define BOOST_REGEX_GUARD(inst)
#endif // BOOST_HAS_THREADS
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
} // namespace re_detail
} // namespace boost
#endif // sentry

View File

@ -46,16 +46,11 @@ namespace boost{
template <class BidirectionalIterator,
class charT,
class traits,
class Allocator>
class traits>
class regex_token_iterator_implementation
{
typedef basic_regex<charT, traits, Allocator> regex_type;
#if 1
typedef basic_regex<charT, traits> regex_type;
typedef sub_match<BidirectionalIterator> value_type;
#else
typedef std::basic_string<charT> value_type;
#endif
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator end; // end of search area
@ -160,15 +155,22 @@ public:
template <class BidirectionalIterator,
class charT = BOOST_DEDUCED_TYPENAME re_detail::regex_iterator_traits<BidirectionalIterator>::value_type,
class traits = regex_traits<charT>,
class Allocator = BOOST_DEFAULT_ALLOCATOR(charT) >
class traits = regex_traits<charT> >
class regex_token_iterator
#ifndef BOOST_NO_STD_ITERATOR
: public std::iterator<
std::forward_iterator_tag,
sub_match<BidirectionalIterator>,
typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type,
const sub_match<BidirectionalIterator>*,
const sub_match<BidirectionalIterator>& >
#endif
{
private:
typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits, Allocator> impl;
typedef regex_token_iterator_implementation<BidirectionalIterator, charT, traits> impl;
typedef shared_ptr<impl> pimpl;
public:
typedef basic_regex<charT, traits, Allocator> regex_type;
typedef basic_regex<charT, traits> regex_type;
typedef sub_match<BidirectionalIterator> value_type;
typedef typename re_detail::regex_iterator_traits<BidirectionalIterator>::difference_type
difference_type;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,100 @@
/*
*
* 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 regex_traits_defaults.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares API's for access to regex_traits default properties.
*/
#ifndef BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
#define BOOST_REGEX_TRAITS_DEFAULTS_HPP_INCLUDED
namespace boost{ namespace re_detail{
const char* get_default_syntax(regex_constants::syntax_type n);
const char* get_default_error_string(regex_constants::error_type n);
// is charT c a combining character?
bool is_combining_implementation(uint_least16_t s);
template <class charT>
inline bool is_combining(charT c)
{
return (c < 0) ? false : ((c > (std::numeric_limits<uint_least16_t>::max)()) ? false : is_combining_implementation(static_cast<unsigned short>(c)));
}
template <>
inline bool is_combining<char>(char)
{
return false;
}
template <>
inline bool is_combining<signed char>(signed char)
{
return false;
}
template <>
inline bool is_combining<unsigned char>(unsigned char)
{
return false;
}
#if defined(WCHAR_MIN) && (WCHAR_MIN == 0) && !defined(BOOST_NO_INTRINSIC_WCHAR_T)
#if defined(WCHAR_MAX) && (WCHAR_MAX <= USHRT_MAX)
template<>
inline bool is_combining<wchar_t>(wchar_t c)
{
return is_combining_implementation(static_cast<unsigned short>(c));
}
#else
template<>
inline bool is_combining<wchar_t>(wchar_t c)
{
return (c > std::numeric_limits<uint_least16_t>::max()) ? false : is_combining_implementation(static_cast<unsigned short>(c));
}
#endif
#endif
//
// is a charT c a line separator?
//
template <class charT>
inline bool is_separator(charT c)
{
return BOOST_REGEX_MAKE_BOOL((c == '\n') || (c == '\r'));
}
//
// parse_value:
// covert a character sequence into a value, return -1 if no digits found:
//
template <class ForwardIterator, class traits>
int parse_value(ForwardIterator& p1, ForwardIterator p2, const traits& traits_inst, int radix = 10)
{
int value = 0;
if(traits_inst.value(*p1) < 0)
return -1;
while(p1 != p2)
{
int v2 = traits_inst.value(*p1);
if(v2 < 0) break;
value *= radix;
value += v2;
++p1;
}
return value;
}
} // re_detail
} // boost
#endif

View File

@ -36,6 +36,7 @@ enum mask_type
{
mask_take = 1,
mask_skip = 2,
mask_init = 4,
mask_any = mask_skip | mask_take,
mask_all = mask_any
};
@ -123,7 +124,7 @@ execution of the machine.
union offset_type
{
re_syntax_base* p;
std::size_t i;
std::ptrdiff_t i;
};
/*** struct re_syntax_base ********************************************
@ -133,7 +134,6 @@ struct re_syntax_base
{
syntax_element_type type; // what kind of state this is
offset_type next; // next state in the machine
unsigned int can_be_null; // true if we match a NULL string
};
/*** struct re_brace **************************************************
@ -162,10 +162,11 @@ First csingles null-terminated strings
Then 2 * cranges NULL terminated strings
Then cequivalents NULL terminated strings
***********************************************************************/
template <class mask_type>
struct re_set_long : public re_syntax_base
{
unsigned int csingles, cranges, cequivalents;
boost::uint_fast32_t cclasses;
mask_type cclasses;
bool isnot;
bool singleton;
};
@ -175,7 +176,7 @@ A set of narrow-characters, matches any of _map which is none-zero
***********************************************************************/
struct re_set : public re_syntax_base
{
unsigned char _map[256];
unsigned char _map[1 << CHAR_BIT];
};
/*** struct re_jump ***************************************************
@ -183,19 +184,27 @@ Jump to a new location in the machine (not next).
***********************************************************************/
struct re_jump : public re_syntax_base
{
offset_type alt; // location to jump to
unsigned char _map[256]; // which characters can take the jump
offset_type alt; // location to jump to
};
/*** struct re_alt ***************************************************
Jump to a new location in the machine (possibly next).
***********************************************************************/
struct re_alt : public re_jump
{
unsigned char _map[1 << CHAR_BIT]; // which characters can take the jump
unsigned int can_be_null; // true if we match a NULL string
};
/*** struct re_repeat *************************************************
Repeat a section of the machine
***********************************************************************/
struct re_repeat : public re_jump
struct re_repeat : public re_alt
{
unsigned min, max; // min and max allowable repeats
int id; // Unique identifier for this repeat
bool leading; // True if this repeat is at the start of the machine (lets us optimize some searches)
bool greedy; // True if this is a greedy repeat
std::size_t min, max; // min and max allowable repeats
int id; // Unique identifier for this repeat
bool leading; // True if this repeat is at the start of the machine (lets us optimize some searches)
bool greedy; // True if this is a greedy repeat
};
/*** enum re_jump_size_type *******************************************
@ -212,11 +221,11 @@ enum re_jump_size_type
/*** proc re_is_set_member *********************************************
Forward declaration: we'll need this one later...
***********************************************************************/
template <class iterator, class charT, class traits_type, class Allocator>
template <class iterator, class charT, class traits_type>
iterator BOOST_REGEX_CALL re_is_set_member(iterator next,
iterator last,
const re_set_long* set_,
const reg_expression<charT, traits_type, Allocator>& e);
const re_set_long<typename traits_type::char_class_type>* set_,
const basic_regex<charT, traits_type>& e);
} // namespace re_detail

View File

@ -0,0 +1,98 @@
/*
*
* Copyright (c) 2003
* 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 syntax_type.hpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares regular expression synatx type enumerator.
*/
#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
#define BOOST_REGEX_SYNTAX_TYPE_HPP
namespace boost{
namespace regex_constants{
typedef unsigned char syntax_type;
//
// values chosen are binary compatible with previous version:
//
static const syntax_type syntax_char = 0;
static const syntax_type syntax_open_mark = 1;
static const syntax_type syntax_close_mark = 2;
static const syntax_type syntax_dollar = 3;
static const syntax_type syntax_caret = 4;
static const syntax_type syntax_dot = 5;
static const syntax_type syntax_star = 6;
static const syntax_type syntax_plus = 7;
static const syntax_type syntax_question = 8;
static const syntax_type syntax_open_set = 9;
static const syntax_type syntax_close_set = 10;
static const syntax_type syntax_or = 11;
static const syntax_type syntax_escape = 12;
static const syntax_type syntax_dash = 14;
static const syntax_type syntax_open_brace = 15;
static const syntax_type syntax_close_brace = 16;
static const syntax_type syntax_digit = 17;
static const syntax_type syntax_comma = 27;
static const syntax_type syntax_equal = 37;
static const syntax_type syntax_colon = 36;
static const syntax_type syntax_not = 53;
// extensions:
static const syntax_type syntax_hash = 13;
static const syntax_type syntax_newline = 26;
// escapes:
typedef syntax_type escape_syntax_type;
static const escape_syntax_type escape_type_word_assert = 18;
static const escape_syntax_type escape_type_not_word_assert = 19;
static const escape_syntax_type escape_type_control_f = 29;
static const escape_syntax_type escape_type_control_n = 30;
static const escape_syntax_type escape_type_control_r = 31;
static const escape_syntax_type escape_type_control_t = 32;
static const escape_syntax_type escape_type_control_v = 33;
static const escape_syntax_type escape_type_ascii_control = 35;
static const escape_syntax_type escape_type_hex = 34;
static const escape_syntax_type escape_type_unicode = 0; // not used
static const escape_syntax_type escape_type_identity = 0; // not used
static const escape_syntax_type escape_type_backref = syntax_digit;
static const escape_syntax_type escape_type_decimal = syntax_digit; // not used
static const escape_syntax_type escape_type_class = 22;
static const escape_syntax_type escape_type_not_class = 23;
// extensions:
static const escape_syntax_type escape_type_left_word = 20;
static const escape_syntax_type escape_type_right_word = 21;
static const escape_syntax_type escape_type_start_buffer = 24; // for \`
static const escape_syntax_type escape_type_end_buffer = 25; // for \'
static const escape_syntax_type escape_type_control_a = 28; // for \a
static const escape_syntax_type escape_type_e = 38; // for \e
static const escape_syntax_type escape_type_E = 47; // for \Q\E
static const escape_syntax_type escape_type_Q = 48; // for \Q\E
static const escape_syntax_type escape_type_X = 49; // for \X
static const escape_syntax_type escape_type_C = 50; // for \C
static const escape_syntax_type escape_type_Z = 51; // for \Z
static const escape_syntax_type escape_type_G = 52; // for \G
static const escape_syntax_type syntax_max = 54;
}
}
#endif

97
src/cpp_regex_traits.cpp Normal file
View File

@ -0,0 +1,97 @@
/*
*
* 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 cpp_regex_traits.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Implements cpp_regex_traits<char> (and associated helper classes).
*/
#include <boost/regex/regex_traits.hpp>
namespace boost{ namespace re_detail{
void cpp_regex_traits_char_layer<char>::init()
{
// we need to start by initialising our syntax map so we know which
// character is used for which purpose:
std::memset(m_char_map, 0, sizeof(m_char_map));
#ifndef __IBMCPP__
std::messages<char>::catalog cat = static_cast<std::messages<char>::catalog>(-1);
#else
std::messages<char>::catalog cat = reinterpret_cast<std::messages<char>::catalog>(-1);
#endif
std::string cat_name(cpp_regex_traits<char>::get_catalog_name());
if(cat_name.size())
{
cat = this->m_pmessages->open(
cat_name,
this->m_locale);
if((int)cat < 0)
{
std::string m("Unable to open message catalog: ");
std::runtime_error err(m + cat_name);
boost::throw_exception(err);
}
}
//
// if we have a valid catalog then load our messages:
//
if((int)cat >= 0)
{
try{
for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
{
string_type mss = this->m_pmessages->get(cat, 0, i, get_default_syntax(i));
for(string_type::size_type j = 0; j < mss.size(); ++j)
{
m_char_map[static_cast<unsigned char>(mss[j])] = i;
}
}
this->m_pmessages->close(cat);
}
catch(...)
{
this->m_pmessages->close(cat);
throw;
}
}
else
{
for(regex_constants::syntax_type i = 1; i < regex_constants::syntax_max; ++i)
{
const char* ptr = get_default_syntax(i);
while(ptr && *ptr)
{
m_char_map[static_cast<unsigned char>(*ptr)] = i;
++ptr;
}
}
}
//
// finish off by calculating our escape types:
//
unsigned char i = 'A';
do
{
if(m_char_map[i] == 0)
{
if(this->m_pctype->is(std::ctype_base::lower, i))
m_char_map[i] = regex_constants::escape_type_class;
else if(this->m_pctype->is(std::ctype_base::upper, i))
m_char_map[i] = regex_constants::escape_type_not_class;
}
}while(0xFF != i++);
}
} // re_detail
} // boost

View File

@ -51,7 +51,6 @@ namespace{
template <class iterator>
std::string to_string(iterator i, iterator j)
{
BOOST_RE_GUARD_STACK
std::string s;
while(i != j)
{
@ -105,7 +104,6 @@ public:
void RegExData::update()
{
BOOST_RE_GUARD_STACK
strings.erase(strings.begin(), strings.end());
positions.erase(positions.begin(), positions.end());
if(t == type_pc)
@ -131,7 +129,6 @@ void RegExData::update()
void RegExData::clean()
{
BOOST_RE_GUARD_STACK
#ifndef BOOST_REGEX_NO_FILEITER
fbase = mapfile::iterator();
fm = match_results<mapfile::iterator>();
@ -142,54 +139,46 @@ void RegExData::clean()
RegEx::RegEx()
{
BOOST_RE_GUARD_STACK
pdata = new re_detail::RegExData();
}
RegEx::RegEx(const RegEx& o)
{
BOOST_RE_GUARD_STACK
pdata = new re_detail::RegExData(*(o.pdata));
}
RegEx::~RegEx()
{
BOOST_RE_GUARD_STACK
delete pdata;
}
RegEx::RegEx(const char* c, bool icase)
{
BOOST_RE_GUARD_STACK
pdata = new re_detail::RegExData();
SetExpression(c, icase);
}
RegEx::RegEx(const std::string& s, bool icase)
{
BOOST_RE_GUARD_STACK
pdata = new re_detail::RegExData();
SetExpression(s.c_str(), icase);
}
RegEx& RegEx::operator=(const RegEx& o)
{
BOOST_RE_GUARD_STACK
*pdata = *(o.pdata);
return *this;
}
RegEx& RegEx::operator=(const char* p)
{
BOOST_RE_GUARD_STACK
SetExpression(p, false);
return *this;
}
unsigned int RegEx::SetExpression(const char* p, bool icase)
{
BOOST_RE_GUARD_STACK
boost::uint_fast32_t f = icase ? regex::normal | regex::use_except | regex::icase : regex::normal | regex::use_except;
boost::uint_fast32_t f = icase ? regex::normal | regex::icase : regex::normal;
return pdata->e.set_expression(p, f);
}
@ -201,7 +190,6 @@ unsigned int RegEx::error_code()const
std::string RegEx::Expression()const
{
BOOST_RE_GUARD_STACK
return pdata->e.expression();
}
@ -210,7 +198,6 @@ std::string RegEx::Expression()const
//
bool RegEx::Match(const char* p, match_flag_type flags)
{
BOOST_RE_GUARD_STACK
pdata->t = re_detail::RegExData::type_pc;
pdata->pbase = p;
const char* end = p;
@ -226,7 +213,6 @@ bool RegEx::Match(const char* p, match_flag_type flags)
bool RegEx::Search(const char* p, match_flag_type flags)
{
BOOST_RE_GUARD_STACK
pdata->t = re_detail::RegExData::type_pc;
pdata->pbase = p;
const char* end = p;
@ -254,7 +240,6 @@ struct pred1
}
unsigned int RegEx::Grep(GrepCallback cb, const char* p, match_flag_type flags)
{
BOOST_RE_GUARD_STACK
pdata->t = re_detail::RegExData::type_pc;
pdata->pbase = p;
const char* end = p;
@ -284,7 +269,6 @@ private:
unsigned int RegEx::Grep(std::vector<std::string>& v, const char* p, match_flag_type flags)
{
BOOST_RE_GUARD_STACK
pdata->t = re_detail::RegExData::type_pc;
pdata->pbase = p;
const char* end = p;
@ -314,7 +298,6 @@ private:
}
unsigned int RegEx::Grep(std::vector<std::size_t>& v, const char* p, match_flag_type flags)
{
BOOST_RE_GUARD_STACK
pdata->t = re_detail::RegExData::type_pc;
pdata->pbase = p;
const char* end = p;
@ -347,7 +330,6 @@ struct pred4
namespace{
void BuildFileList(std::list<std::string>* pl, const char* files, bool recurse)
{
BOOST_RE_GUARD_STACK
file_iterator start(files);
file_iterator end;
if(recurse)
@ -392,7 +374,6 @@ void BuildFileList(std::list<std::string>* pl, const char* files, bool recurse)
unsigned int RegEx::GrepFiles(GrepFileCallback cb, const char* files, bool recurse, match_flag_type flags)
{
BOOST_RE_GUARD_STACK
unsigned int result = 0;
std::list<std::string> file_list;
BuildFileList(&file_list, files, recurse);
@ -420,7 +401,6 @@ unsigned int RegEx::GrepFiles(GrepFileCallback cb, const char* files, bool recur
unsigned int RegEx::FindFiles(FindFilesCallback cb, const char* files, bool recurse, match_flag_type flags)
{
BOOST_RE_GUARD_STACK
unsigned int result = 0;
std::list<std::string> file_list;
BuildFileList(&file_list, files, recurse);
@ -488,7 +468,6 @@ std::size_t RegEx::Split(std::vector<std::string>& v,
//
std::size_t RegEx::Position(int i)const
{
BOOST_RE_GUARD_STACK
switch(pdata->t)
{
case re_detail::RegExData::type_pc:
@ -508,16 +487,14 @@ std::size_t RegEx::Position(int i)const
return RegEx::npos;
}
unsigned int RegEx::Marks()const
std::size_t RegEx::Marks()const
{
BOOST_RE_GUARD_STACK
return pdata->e.mark_count();
}
std::size_t RegEx::Length(int i)const
{
BOOST_RE_GUARD_STACK
switch(pdata->t)
{
case re_detail::RegExData::type_pc:
@ -539,7 +516,6 @@ std::size_t RegEx::Length(int i)const
bool RegEx::Matched(int i)const
{
BOOST_RE_GUARD_STACK
switch(pdata->t)
{
case re_detail::RegExData::type_pc:
@ -562,7 +538,6 @@ bool RegEx::Matched(int i)const
std::string RegEx::What(int i)const
{
BOOST_RE_GUARD_STACK
std::string result;
switch(pdata->t)
{

View File

@ -67,7 +67,6 @@ const char* _fi_sep_alt = _fi_sep;
void mapfile::open(const char* file)
{
BOOST_RE_GUARD_STACK
#if defined(__CYGWIN__)||defined(__CYGWIN32__)
char win32file[ MAX_PATH ];
cygwin_conv_to_win32_path( file, win32file );
@ -110,7 +109,6 @@ void mapfile::open(const char* file)
void mapfile::close()
{
BOOST_RE_GUARD_STACK
if(hfile != INVALID_HANDLE_VALUE)
{
UnmapViewOfFile((void*)_first);
@ -125,7 +123,6 @@ void mapfile::close()
mapfile_iterator& mapfile_iterator::operator = (const mapfile_iterator& i)
{
BOOST_RE_GUARD_STACK
if(file && node)
file->unlock(node);
file = i.file;
@ -138,7 +135,6 @@ mapfile_iterator& mapfile_iterator::operator = (const mapfile_iterator& i)
mapfile_iterator& mapfile_iterator::operator++ ()
{
BOOST_RE_GUARD_STACK
if((++offset == mapfile::buf_size) && file)
{
++node;
@ -151,7 +147,6 @@ mapfile_iterator& mapfile_iterator::operator++ ()
mapfile_iterator mapfile_iterator::operator++ (int)
{
BOOST_RE_GUARD_STACK
mapfile_iterator temp(*this);
if((++offset == mapfile::buf_size) && file)
{
@ -165,7 +160,6 @@ mapfile_iterator mapfile_iterator::operator++ (int)
mapfile_iterator& mapfile_iterator::operator-- ()
{
BOOST_RE_GUARD_STACK
if((offset == 0) && file)
{
--node;
@ -180,7 +174,6 @@ mapfile_iterator& mapfile_iterator::operator-- ()
mapfile_iterator mapfile_iterator::operator-- (int)
{
BOOST_RE_GUARD_STACK
mapfile_iterator temp(*this);
if((offset == 0) && file)
{
@ -196,7 +189,6 @@ mapfile_iterator mapfile_iterator::operator-- (int)
mapfile_iterator operator + (const mapfile_iterator& i, long off)
{
BOOST_RE_GUARD_STACK
mapfile_iterator temp(i);
temp += off;
return temp;
@ -204,7 +196,6 @@ mapfile_iterator operator + (const mapfile_iterator& i, long off)
mapfile_iterator operator - (const mapfile_iterator& i, long off)
{
BOOST_RE_GUARD_STACK
mapfile_iterator temp(i);
temp -= off;
return temp;
@ -212,19 +203,16 @@ mapfile_iterator operator - (const mapfile_iterator& i, long off)
mapfile::iterator mapfile::begin()const
{
BOOST_RE_GUARD_STACK
return mapfile_iterator(this, 0);
}
mapfile::iterator mapfile::end()const
{
BOOST_RE_GUARD_STACK
return mapfile_iterator(this, _size);
}
void mapfile::lock(pointer* node)const
{
BOOST_RE_GUARD_STACK
assert(node >= _first);
assert(node <= _last);
if(node < _last)
@ -265,7 +253,6 @@ void mapfile::lock(pointer* node)const
void mapfile::unlock(pointer* node)const
{
BOOST_RE_GUARD_STACK
assert(node >= _first);
assert(node <= _last);
if(node < _last)
@ -279,7 +266,6 @@ void mapfile::unlock(pointer* node)const
long int get_file_length(std::FILE* hfile)
{
BOOST_RE_GUARD_STACK
long int result;
std::fseek(hfile, 0, SEEK_END);
result = std::ftell(hfile);
@ -290,7 +276,6 @@ long int get_file_length(std::FILE* hfile)
void mapfile::open(const char* file)
{
BOOST_RE_GUARD_STACK
hfile = std::fopen(file, "rb");
#ifndef BOOST_NO_EXCEPTIONS
try{
@ -325,7 +310,6 @@ void mapfile::open(const char* file)
void mapfile::close()
{
BOOST_RE_GUARD_STACK
if(hfile != 0)
{
pointer* p = _first;
@ -350,7 +334,6 @@ void mapfile::close()
file_iterator::file_iterator()
{
BOOST_RE_GUARD_STACK
_root = _path = 0;
ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
@ -381,7 +364,6 @@ file_iterator::file_iterator()
file_iterator::file_iterator(const char* wild)
{
BOOST_RE_GUARD_STACK
_root = _path = 0;
ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
@ -450,7 +432,6 @@ file_iterator::file_iterator(const char* wild)
file_iterator::file_iterator(const file_iterator& other)
{
BOOST_RE_GUARD_STACK
_root = _path = 0;
ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
@ -478,7 +459,6 @@ file_iterator::file_iterator(const file_iterator& other)
file_iterator& file_iterator::operator=(const file_iterator& other)
{
BOOST_RE_GUARD_STACK
std::strcpy(_root, other._root);
std::strcpy(_path, other._path);
ptr = _path + (other.ptr - other._path);
@ -496,7 +476,6 @@ file_iterator& file_iterator::operator=(const file_iterator& other)
file_iterator::~file_iterator()
{
BOOST_RE_GUARD_STACK
delete[] _root;
delete[] _path;
if(--(ref->count) == 0)
@ -509,7 +488,6 @@ file_iterator::~file_iterator()
file_iterator file_iterator::operator++(int)
{
BOOST_RE_GUARD_STACK
file_iterator temp(*this);
next();
return temp;
@ -518,7 +496,6 @@ file_iterator file_iterator::operator++(int)
void file_iterator::next()
{
BOOST_RE_GUARD_STACK
if(ref->hf != _fi_invalid_handle)
{
bool cont = true;
@ -545,7 +522,6 @@ void file_iterator::next()
directory_iterator::directory_iterator()
{
BOOST_RE_GUARD_STACK
_root = _path = 0;
ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
@ -576,7 +552,6 @@ directory_iterator::directory_iterator()
directory_iterator::directory_iterator(const char* wild)
{
BOOST_RE_GUARD_STACK
_root = _path = 0;
ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
@ -643,7 +618,6 @@ directory_iterator::directory_iterator(const char* wild)
directory_iterator::~directory_iterator()
{
BOOST_RE_GUARD_STACK
delete[] _root;
delete[] _path;
if(--(ref->count) == 0)
@ -656,7 +630,6 @@ directory_iterator::~directory_iterator()
directory_iterator::directory_iterator(const directory_iterator& other)
{
BOOST_RE_GUARD_STACK
_root = _path = 0;
ref = 0;
#ifndef BOOST_NO_EXCEPTIONS
@ -684,7 +657,6 @@ directory_iterator::directory_iterator(const directory_iterator& other)
directory_iterator& directory_iterator::operator=(const directory_iterator& other)
{
BOOST_RE_GUARD_STACK
std::strcpy(_root, other._root);
std::strcpy(_path, other._path);
ptr = _path + (other.ptr - other._path);
@ -701,7 +673,6 @@ directory_iterator& directory_iterator::operator=(const directory_iterator& othe
directory_iterator directory_iterator::operator++(int)
{
BOOST_RE_GUARD_STACK
directory_iterator temp(*this);
next();
return temp;
@ -709,7 +680,6 @@ directory_iterator directory_iterator::operator++(int)
void directory_iterator::next()
{
BOOST_RE_GUARD_STACK
if(ref->hf != _fi_invalid_handle)
{
bool cont = true;
@ -748,7 +718,6 @@ struct _fi_priv_data
_fi_priv_data::_fi_priv_data(const char* p)
{
BOOST_RE_GUARD_STACK
std::strcpy(root, p);
mask = root;
while(*mask) ++mask;
@ -775,7 +744,6 @@ _fi_priv_data::_fi_priv_data(const char* p)
bool iswild(const char* mask, const char* name)
{
BOOST_RE_GUARD_STACK
while(*mask && *name)
{
switch(*mask)
@ -817,7 +785,6 @@ bool iswild(const char* mask, const char* name)
unsigned _fi_attributes(const char* root, const char* name)
{
BOOST_RE_GUARD_STACK
char buf[MAX_PATH];
if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') )
std::sprintf(buf, "%s%s", root, name);
@ -834,7 +801,6 @@ unsigned _fi_attributes(const char* root, const char* name)
_fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindFileData)
{
BOOST_RE_GUARD_STACK
_fi_find_handle dat = new _fi_priv_data(lpFileName);
DIR* h = opendir(dat->root);
@ -850,7 +816,6 @@ _fi_find_handle _fi_FindFirstFile(const char* lpFileName, _fi_find_data* lpFindF
bool _fi_FindNextFile(_fi_find_handle dat, _fi_find_data* lpFindFileData)
{
BOOST_RE_GUARD_STACK
dirent* d;
do
{
@ -868,7 +833,6 @@ bool _fi_FindNextFile(_fi_find_handle dat, _fi_find_data* lpFindFileData)
bool _fi_FindClose(_fi_find_handle dat)
{
BOOST_RE_GUARD_STACK
closedir(dat->d);
delete dat;
return true;

View File

@ -35,7 +35,6 @@ const char* names[] = {"REG_NOERROR", "REG_NOMATCH", "REG_BADPAT", "REG_ECOLLATE
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char* ptr, int f)
{
BOOST_RE_GUARD_STACK
if(expression->re_magic != magic_value)
{
expression->guts = 0;
@ -54,7 +53,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char
#endif
}
// set default flags:
boost::uint_fast32_t flags = (f & REG_EXTENDED) ? regex::extended : regex::basic;
boost::uint_fast32_t flags = (f & REG_PERLEX) ? 0 : ((f & REG_EXTENDED) ? regex::extended : regex::basic);
expression->eflags = (f & REG_NEWLINE) ? match_not_dot_newline : match_default;
// and translate those that are actually set:
@ -74,13 +73,9 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char
if(f & REG_ICASE)
flags |= regex::icase;
if(f & REG_ESCAPE_IN_LISTS)
flags |= regex::escape_in_lists;
flags &= ~regex::no_escape_in_lists;
if(f & REG_NEWLINE_ALT)
flags |= regex::newline_alt;
#ifndef BOOST_REGEX_V3
if(f & REG_PERLEX)
flags |= regex::perlex;
#endif
const char* p2;
if(f & REG_PEND)
@ -110,12 +105,11 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompA(regex_tA* expression, const char
BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA* e, char* buf, regsize_t buf_size)
{
BOOST_RE_GUARD_STACK
std::size_t result = 0;
if(code & REG_ITOA)
{
code &= ~REG_ITOA;
if(code <= REG_E_UNKNOWN)
if(code <= (int)REG_E_UNKNOWN)
{
result = std::strlen(names[code]) + 1;
if(buf_size >= result)
@ -129,7 +123,7 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA*
char localbuf[5];
if(e == 0)
return 0;
for(int i = 0; i <= REG_E_UNKNOWN; ++i)
for(int i = 0; i <= (int)REG_E_UNKNOWN; ++i)
{
if(std::strcmp(e->re_endp, names[i]) == 0)
{
@ -144,7 +138,7 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA*
std::strcpy(buf, localbuf);
return std::strlen(localbuf) + 1;
}
if(code <= REG_E_UNKNOWN)
if(code <= (int)REG_E_UNKNOWN)
{
std::string p;
if((e) && (e->re_magic == magic_value))
@ -168,7 +162,6 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA*
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA* expression, const char* buf, regsize_t n, regmatch_t* array, int eflags)
{
BOOST_RE_GUARD_STACK
bool result = false;
match_flag_type flags = match_default | expression->eflags;
const char* end;
@ -209,7 +202,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA* expression, cons
if(result)
{
// extract what matched:
unsigned int i;
std::size_t i;
for(i = 0; (i < n) && (i < expression->re_nsub + 1); ++i)
{
array[i].rm_so = (m[i].matched == false) ? -1 : (m[i].first - buf);
@ -228,7 +221,6 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecA(const regex_tA* expression, cons
BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeA(regex_tA* expression)
{
BOOST_RE_GUARD_STACK
if(expression->re_magic == magic_value)
{
delete static_cast<regex*>(expression->guts);

View File

@ -46,12 +46,6 @@ namespace boost{
bad_pattern::~bad_pattern() throw() {}
bad_expression::~bad_expression() throw() {}
regbase::regbase()
: _flags(regbase::failbit){}
regbase::regbase(const regbase& b)
: _flags(b._flags){}
namespace re_detail{
@ -118,12 +112,6 @@ BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page()
}
#endif
BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_regex_exception(const std::string& msg)
{
bad_expression e(msg);
throw_exception(e);
}
#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
@ -140,7 +128,11 @@ BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p)
#else
#ifdef BOOST_HAS_THREADS
mem_block_cache block_cache = { 0, 0, BOOST_STATIC_MUTEX_INIT, };
#else
mem_block_cache block_cache = { 0, 0, };
#endif
BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block()
{

View File

@ -1,6 +1,6 @@
/*
*
* Copyright (c) 1998-2002
* Copyright (c) 1998-2004
* Dr John Maddock
*
* Use, modification and distribution are subject to the
@ -21,199 +21,6 @@
#include <boost/regex/config.hpp>
#ifdef BOOST_REGEX_DEBUG
#ifdef BOOST_MSVC
#include <crtdbg.h>
#endif
#ifdef BOOST_REGEX_V3
#include <boost/regex/v3/regex_raw_buffer.hpp>
#else
#include <boost/regex/v4/regex_raw_buffer.hpp>
#endif
#include <boost/regex.hpp>
#ifndef BOOST_RE_OLD_IOSTREAM
#include <ostream>
#else
#include <ostream.h>
#endif
namespace boost { namespace re_detail {
std::ostream& operator<<(std::ostream& s, syntax_element_type x)
{
return s << static_cast<unsigned long>(x);
}
}} // namespace boost::re_detail
namespace {
char b1[32] = {0,};
char guard_pattern[32]
= { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, };
char b2[32] = {0,};
static const int guard_size = 32;
bool check_pattern(void* p)
{
return p ? memcmp(p, guard_pattern, guard_size) : 0;
}
inline unsigned maxi(unsigned i, unsigned j)
{
return i < j ? j : i;
}
unsigned int allocated = 0;
struct init
{
init();
~init();
};
init::init()
{
#ifdef BOOST_MSVC
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF|_CRTDBG_DELAY_FREE_MEM_DF|_CRTDBG_LEAK_CHECK_DF);
#endif
}
init::~init()
{
}
init i;
void* get_mem(size_t n)
{
++allocated;
char* p = (char*)malloc(n + guard_size * 2 + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + boost::re_detail::padding_size);
char* base = p;
p = (char*)((std::ptrdiff_t)(p + boost::re_detail::padding_mask) & ~boost::re_detail::padding_mask);
std::memcpy(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size), guard_pattern, guard_size);
std::memcpy(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + guard_size + n, guard_pattern, guard_size);
*(int*)p = n;
*(void**)(p + sizeof(int)) = base;
return p + guard_size + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size);
}
void free_mem(void* b)
{
if(b)
{
char* p = (char*)b;
p -= (guard_size + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size));
if(check_pattern(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size)) || check_pattern(p + maxi(sizeof(int) + sizeof(void*), boost::re_detail::padding_size) + guard_size + *(int*)p))
{
cerr << "Error: freed memory has been written past end..." << endl;
}
free(*(void**)(p + sizeof(int)));
--allocated;
}
}
} // namespace
void* operator new(size_t n)
{
return get_mem(n);
}
void* operator new[](size_t n)
{
return get_mem(n);
}
void operator delete(void* p)
{
free_mem(p);
}
void operator delete[](void* p)
{
free_mem(p);
}
#include <set>
namespace boost{
namespace re_detail{
std::set<debug_guard*, std::less<debug_guard*> >* patterns = 0;
int pattern_count = 0;
void check_patterns(const char* f, int l)
{
if(pattern_count)
{
std::set<debug_guard*, std::less<debug_guard*> >::iterator i, j;
i = patterns->begin();
j = patterns->end();
while(i != j)
{
if(check_pattern((void*)(*i)->g1) || check_pattern((*i)->g2) || check_pattern((void*)(*i)->pc) || check_pattern((*i)->pnc))
{
cerr << "Error: static memory corruption at " << hex << *i << dec << " in " << (*i)->file << "@" << (*i)->line << " called from " << f << "@" << l << endl;
}
++i;
}
}
}
debug_guard::debug_guard(const char* f, int l, const char* p1, char* p2)
{
if(++pattern_count == 1)
patterns = new std::set<debug_guard*, std::less<debug_guard*> >;
file = f;
line = l;
std::memcpy(g1, guard_pattern, guard_size);
std::memcpy(g2, guard_pattern, guard_size);
if(p1)
{
pc = p1;
}
else
pc = 0;
if(p2)
{
pnc = p2;
std::memcpy(pnc, guard_pattern, guard_size);
}
else
pnc = 0;
patterns->insert(this);
}
debug_guard::~debug_guard()
{
check_patterns(file, line);
if(check_pattern(g1) || check_pattern(g2))
{
cerr << "Error: memory corruption " << file << "@" << line << endl;
}
patterns->erase(this);
if(--pattern_count == 0)
{
delete patterns;
patterns = 0;
}
}
} // namespace re_detail
} // namespace boost
#endif
//
// regex configuration information: this prints out the settings used

41
src/regex_raw_buffer.cpp Normal file
View File

@ -0,0 +1,41 @@
#include <boost/regex/v4/regex_raw_buffer.hpp>
namespace boost{ namespace re_detail{
void BOOST_REGEX_CALL raw_storage::resize(size_type n)
{
register size_type newsize = start ? last - start : 1024;
while(newsize < n)
newsize *= 2;
register size_type datasize = end - start;
// extend newsize to WORD/DWORD boundary:
newsize = (newsize + padding_mask) & ~(padding_mask);
// allocate and copy data:
register pointer ptr = static_cast<pointer>(::operator new(newsize));
BOOST_REGEX_NOEH_ASSERT(ptr)
std::memcpy(ptr, start, datasize);
// get rid of old buffer:
::operator delete(start);
// and set up pointers:
start = ptr;
end = ptr + datasize;
last = ptr + newsize;
}
void* BOOST_REGEX_CALL raw_storage::insert(size_type pos, size_type n)
{
BOOST_ASSERT(pos <= size_type(end - start));
if(size_type(last - end) < n)
resize(n + (end - start));
register void* result = start + pos;
std::memmove(start + pos + n, start + pos, (end - start) - pos);
end += n;
return result;
}
}} // namespaces

View File

@ -1,74 +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_synch.cpp
* VERSION: see <boost/version.hpp>
* DESCRIPTION: Thread synch helper functions, for regular
* expression library.
*/
#define BOOST_REGEX_SOURCE
#include <boost/regex/config.hpp>
#ifdef BOOST_REGEX_V3
#include <boost/regex/v3/regex_synch.hpp>
#else
#include <boost/regex/v4/regex_synch.hpp>
#endif
namespace boost{
namespace re_detail{
void BOOST_REGEX_CALL re_init_threads()
{
BOOST_RE_GUARD_STACK
#ifdef BOOST_HAS_THREADS
if(p_re_lock == 0)
p_re_lock = new critical_section();
cs_guard g(*p_re_lock);
++re_lock_count;
#endif
}
void BOOST_REGEX_CALL re_free_threads()
{
BOOST_RE_GUARD_STACK
#ifdef BOOST_HAS_THREADS
cs_guard g(*p_re_lock);
--re_lock_count;
if(re_lock_count == 0)
{
g.acquire(false);
delete p_re_lock;
p_re_lock = 0;
}
#endif
}
#ifdef BOOST_HAS_THREADS
BOOST_REGEX_DECL critical_section* p_re_lock = 0;
BOOST_REGEX_DECL unsigned int re_lock_count = 0;
#endif
} // namespace re_detail
} // namespace boost

View File

@ -0,0 +1,168 @@
/*
*
* 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 regex_traits_defaults.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares API's for access to regex_traits default properties.
*/
#include <boost/regex/regex_traits.hpp>
namespace boost{ namespace re_detail{
const char* get_default_syntax(regex_constants::syntax_type n)
{
// if the user hasn't supplied a message catalog, then this supplies
// default "messages" for us to load in the range 1-100.
const char* messages[] = {
"",
"(",
")",
"$",
"^",
".",
"*",
"+",
"?",
"[",
"]",
"|",
"\\",
"#",
"-",
"{",
"}",
"0123456789",
"b",
"B",
"<",
">",
"",
"",
"A",
"z",
"\n",
",",
"a",
"f",
"n",
"r",
"t",
"v",
"x",
"c",
":",
"=",
"e",
"",
"",
"",
"",
"",
"",
"",
"",
"E",
"Q",
"X",
"C",
"Z",
"G"
"!", };
return ((n >= (sizeof(messages) / sizeof(messages[1]))) ? "" : messages[n]);
}
const char* get_default_error_string(regex_constants::error_type n)
{
static const char* const s_default_error_messages[] = {
"Success", /* REG_NOERROR */
"No match", /* REG_NOMATCH */
"Invalid regular expression", /* REG_BADPAT */
"Invalid collation character", /* REG_ECOLLATE */
"Invalid character class name", /* REG_ECTYPE */
"Trailing backslash", /* REG_EESCAPE */
"Invalid back reference", /* REG_ESUBREG */
"Unmatched [ or [^", /* REG_EBRACK */
"Unmatched ( or \\(", /* REG_EPAREN */
"Unmatched \\{", /* REG_EBRACE */
"Invalid content of \\{\\}", /* REG_BADBR */
"Invalid range end", /* REG_ERANGE */
"Memory exhausted", /* REG_ESPACE */
"Invalid preceding regular expression", /* REG_BADRPT */
"Premature end of regular expression", /* REG_EEND */
"Regular expression too big", /* REG_ESIZE */
"Unmatched ) or \\)", /* REG_ERPAREN */
"Empty expression", /* REG_EMPTY */
"Complexity requirements exceeded", /* REG_ECOMPLEXITY */
"Out of stack space", /* REG_ESTACK */
"Unknown error", /* REG_E_UNKNOWN */
"",
"",
"",
};
return (n <= REG_E_UNKNOWN) ? s_default_error_messages[REG_E_UNKNOWN] : s_default_error_messages[n];
}
bool is_combining_implementation(boost::uint_least16_t c)
{
const boost::uint_least16_t combining_ranges[] = { 0x0300, 0x0361,
0x0483, 0x0486,
0x0903, 0x0903,
0x093E, 0x0940,
0x0949, 0x094C,
0x0982, 0x0983,
0x09BE, 0x09C0,
0x09C7, 0x09CC,
0x09D7, 0x09D7,
0x0A3E, 0x0A40,
0x0A83, 0x0A83,
0x0ABE, 0x0AC0,
0x0AC9, 0x0ACC,
0x0B02, 0x0B03,
0x0B3E, 0x0B3E,
0x0B40, 0x0B40,
0x0B47, 0x0B4C,
0x0B57, 0x0B57,
0x0B83, 0x0B83,
0x0BBE, 0x0BBF,
0x0BC1, 0x0BCC,
0x0BD7, 0x0BD7,
0x0C01, 0x0C03,
0x0C41, 0x0C44,
0x0C82, 0x0C83,
0x0CBE, 0x0CBE,
0x0CC0, 0x0CC4,
0x0CC7, 0x0CCB,
0x0CD5, 0x0CD6,
0x0D02, 0x0D03,
0x0D3E, 0x0D40,
0x0D46, 0x0D4C,
0x0D57, 0x0D57,
0x0F7F, 0x0F7F,
0x20D0, 0x20E1,
0x3099, 0x309A,
0xFE20, 0xFE23,
0xffff, 0xffff, };
const boost::uint_least16_t* p = combining_ranges + 1;
while(*p < c) p += 2;
--p;
if((c >= *p) && (c <= *(p+1)))
return true;
return false;
}
} // re_detail
} // boost

163
src/static_mutex.cpp Normal file
View File

@ -0,0 +1,163 @@
/*
*
* 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.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares static_mutex lock type.
*/
#include <boost/config.hpp>
#ifdef BOOST_HAS_THREADS
#include <boost/regex/static_mutex.hpp>
#if defined(BOOST_HAS_WINTHREADS)
#include <windows.h>
#endif
namespace boost{
#if defined(BOOST_HAS_PTHREADS) && defined(PTHREAD_MUTEX_INITIALIZER)
scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& m, bool lk)
: m_mutex(m), m_have_lock(false)
{
if(lk)
lock();
}
scoped_static_mutex_lock::~scoped_static_mutex_lock()
{
if(m_have_lock)
unlock();
}
void scoped_static_mutex_lock::lock()
{
if(0 == m_have_lock)
{
pthread_mutex_lock(&(m_mutex.m_mutex));
m_have_lock = true;
}
}
void scoped_static_mutex_lock::unlock()
{
if(m_have_lock)
{
pthread_mutex_unlock(&(m_mutex.m_mutex));
m_have_lock = false;
}
}
#elif defined(BOOST_HAS_WINTHREADS)
scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& m, bool lk)
: m_mutex(m), m_have_lock(false)
{
if(lk)
lock();
}
scoped_static_mutex_lock::~scoped_static_mutex_lock()
{
if(m_have_lock)
unlock();
}
void scoped_static_mutex_lock::lock()
{
if(0 == m_have_lock)
{
while(0 != InterlockedCompareExchange((LONG*)&(m_mutex.m_mutex), 1, 0))
{
Sleep(0);
}
m_have_lock = true;
}
}
void scoped_static_mutex_lock::unlock()
{
if(m_have_lock)
{
InterlockedExchange((LONG*)&(m_mutex.m_mutex), 0);
m_have_lock = false;
}
}
#else
//
// Portable version of a static mutex based on Boost.Thread library:
//
#include <stdlib.h>
#include <assert.h>
boost::recursive_mutex* static_mutex::m_pmutex = 0;
boost::once_flag static_mutex::m_once = BOOST_ONCE_INIT;
extern "C" void free_static_mutex()
{
delete static_mutex::m_pmutex;
static_mutex::m_pmutex = 0;
}
void static_mutex::init()
{
m_pmutex = new boost::recursive_mutex();
int r = atexit(free_static_mutex);
assert(0 == r);
}
scoped_static_mutex_lock::scoped_static_mutex_lock(static_mutex& , bool lk)
: m_plock(0), m_have_lock(false)
{
if(lk)
lock();
}
scoped_static_mutex_lock::~scoped_static_mutex_lock()
{
if(m_have_lock)
unlock();
delete m_plock;
}
void scoped_static_mutex_lock::lock()
{
if(0 == m_have_lock)
{
boost::call_once(&static_mutex::init, static_mutex::m_once);
if(0 == m_plock)
m_plock = new boost::recursive_mutex::scoped_lock(*static_mutex::m_pmutex, false);
m_plock->lock();
m_have_lock = true;
}
}
void scoped_static_mutex_lock::unlock()
{
if(m_have_lock)
{
m_plock->unlock();
m_have_lock = false;
}
}
#endif
}
#endif // BOOST_HAS_THREADS

View File

@ -43,7 +43,6 @@ const wchar_t* wnames[] = {L"REG_NOERROR", L"REG_NOMATCH", L"REG_BADPAT", L"REG_
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wchar_t* ptr, int f)
{
BOOST_RE_GUARD_STACK
if(expression->re_magic != wmagic_value)
{
expression->guts = 0;
@ -62,7 +61,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha
#endif
}
// set default flags:
boost::uint_fast32_t flags = (f & REG_EXTENDED) ? wregex::extended : wregex::basic;
boost::uint_fast32_t flags = (f & REG_PERLEX) ? 0 : ((f & REG_EXTENDED) ? wregex::extended : wregex::basic);
expression->eflags = (f & REG_NEWLINE) ? match_not_dot_newline : match_default;
// and translate those that are actually set:
@ -82,13 +81,9 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha
if(f & REG_ICASE)
flags |= wregex::icase;
if(f & REG_ESCAPE_IN_LISTS)
flags |= wregex::escape_in_lists;
flags &= ~wregex::no_escape_in_lists;
if(f & REG_NEWLINE_ALT)
flags |= wregex::newline_alt;
#ifndef BOOST_REGEX_V3
if(f & REG_PERLEX)
flags |= wregex::perlex;
#endif
const wchar_t* p2;
if(f & REG_PEND)
@ -118,7 +113,6 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wcha
BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW* e, wchar_t* buf, regsize_t buf_size)
{
BOOST_RE_GUARD_STACK
std::size_t result = 0;
if(code & REG_ITOA)
{
@ -162,12 +156,12 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW*
pt = &static_cast<wregex*>(e->guts)->get_traits();
(void)pt; // warning suppression
std::string p = pt->error_string(code);
std::size_t len = pt->strwiden(static_cast<wchar_t*>(0), 0, p.c_str());
if(len < buf_size)
if(p.size() < buf_size)
{
pt->strwiden(buf, buf_size, p.c_str());
std::copy(p.begin(), p.end(), buf);
buf[p.size()] = 0;
}
return len + 1;
return p.size() + 1;
}
if(buf_size)
*buf = 0;
@ -176,7 +170,6 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW*
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW* expression, const wchar_t* buf, regsize_t n, regmatch_t* array, int eflags)
{
BOOST_RE_GUARD_STACK
bool result = false;
match_flag_type flags = match_default | expression->eflags;
const wchar_t* end;
@ -216,7 +209,7 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW* expression, cons
if(result)
{
// extract what matched:
unsigned int i;
std::size_t i;
for(i = 0; (i < n) && (i < expression->re_nsub + 1); ++i)
{
array[i].rm_so = (m[i].matched == false) ? -1 : (m[i].first - buf);
@ -235,7 +228,6 @@ BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW* expression, cons
BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW* expression)
{
BOOST_RE_GUARD_STACK
if(expression->re_magic == wmagic_value)
{
delete static_cast<wregex*>(expression->guts);

View File

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

View File

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

1242
test/regress/basic_tests.cpp Normal file

File diff suppressed because it is too large Load Diff

126
test/regress/info.hpp Normal file
View File

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

45
test/regress/main.cpp Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

90
test/regress/test.hpp Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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