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