Rewritten regex formatting code, refactored headers to reduce dependencies.

[SVN r22891]
This commit is contained in:
John Maddock
2004-05-22 11:04:22 +00:00
parent 03694d72ae
commit bdb4c091f1
33 changed files with 1001 additions and 690 deletions

View File

@ -33,9 +33,15 @@ using std::getline;
#include <boost/config.hpp>
#include <boost/regex.hpp>
#include <boost/cregex.hpp>
#include <boost/timer.hpp>
#include <boost/smart_ptr.hpp>
#if defined(_WIN32) && defined(BOOST_REGEX_USE_WIN32_LOCALE)
#include <windows.h>
#pragma comment(lib, "user32.lib")
#endif
#if (defined(_MSC_VER) && (_MSC_VER <= 1300)) || defined(__sgi)
// maybe no Koenig lookup, use using declaration instead:
using namespace boost;

View File

@ -40,30 +40,8 @@
# include BOOST_REGEX_USER_CONFIG
# include <cstdlib>
# include <cstddef>
# include <cstdio>
# include <clocale>
# include <cassert>
# include <string>
# include <stdexcept>
# 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>
# include <boost/mpl/bool_fwd.hpp>
# ifndef BOOST_NO_STD_LOCALE
# include <locale>
# endif
#else
//
// C build,
@ -122,27 +100,6 @@
#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__)
# define BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE
#endif
// fix problems with bool as a macro,
// this probably doesn't affect any current compilers:
#if defined(bool) || defined(true) || defined(false)
# define BOOST_REGEX_NO_BOOL
#endif
// We don't make our templates external if the compiler
// can't handle it:
#if (defined(BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS) || defined(__HP_aCC) || defined(__MWERKS__) || defined(__COMO__) || defined(BOOST_INTEL))\
&& !defined(BOOST_MSVC) && !defined(__BORLANDC__)
# define BOOST_REGEX_NO_EXTERNAL_TEMPLATES
#endif
// disable our own file-iterators and mapfiles if we can't
// support them:
@ -150,44 +107,12 @@
# define BOOST_REGEX_NO_FILEITER
#endif
#ifdef __cplusplus
#ifndef MB_CUR_MAX
// yuk!
// better make a conservative guess!
#define MB_CUR_MAX 10
#endif
namespace boost{ namespace re_detail{
#ifdef BOOST_NO_STD_DISTANCE
template <class T>
std::ptrdiff_t distance(const T& x, const T& y)
{ return y - x; }
#else
using std::distance;
#endif
}}
#ifdef BOOST_REGEX_NO_BOOL
# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)
#else
# ifdef BOOST_MSVC
// warning suppression with VC6:
# pragma warning(disable: 4800)
# pragma warning(disable: 4786)
# endif
# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)
#endif
#endif // __cplusplus
// backwards compatibitity:
#if defined(BOOST_RE_NO_LIB)
# define BOOST_REGEX_NO_LIB
#endif
#if defined(__GNUC__) && (defined(_WIN32) || defined(__CYGWIN__))
// gcc on win32 has problems merging switch statements in templates:
# define BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE
// gcc on win32 has problems if you include <windows.h>
// (sporadically generates bad code).
# define BOOST_REGEX_USE_C_LOCALE
@ -357,32 +282,6 @@ BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page();
#endif
/*****************************************************************************
*
* Error handling:
*
****************************************************************************/
#if defined(__cplusplus)
namespace boost{
namespace re_detail{
BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex);
template <class traits>
void raise_error(const traits& t, unsigned code)
{
(void)t; // warning suppression
std::runtime_error e(t.error_string(code));
::boost::re_detail::raise_runtime_error(e);
}
}
}
#endif
/*****************************************************************************
*
* Algorithm selection and configuration:
@ -419,93 +318,6 @@ void raise_error(const traits& t, unsigned code)
#endif
/*****************************************************************************
*
* Fix broken compilers that wrongly #define some symbols:
*
****************************************************************************/
#ifdef __cplusplus
// the following may be defined as macros; this is
// incompatable with std::something syntax, we have
// no choice but to undef them?
#ifdef sprintf
#undef sprintf
#endif
#ifdef swprintf
#undef swprintf
#endif
#endif
/*****************************************************************************
*
* Fix broken broken namespace support:
*
****************************************************************************/
#if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus)
namespace std{
using ::ptrdiff_t;
using ::size_t;
using ::sprintf;
using ::abs;
using ::setlocale;
# ifndef BOOST_NO_WREGEX
# ifndef BOOST_NO_SWPRINTF
using ::swprintf;
# endif
using ::wcstombs;
using ::mbstowcs;
# if !defined(BOOST_NO_STD_LOCALE) && !defined (__STL_NO_NATIVE_MBSTATE_T) && !defined(_STLP_NO_NATIVE_MBSTATE_T)
using ::mbstate_t;
# endif
# endif // BOOST_NO_WREGEX
using ::fseek;
using ::fread;
using ::ftell;
using ::fopen;
using ::fclose;
using ::FILE;
#ifdef BOOST_NO_EXCEPTIONS
using ::fprintf;
using ::abort;
#endif
}
#endif
/*****************************************************************************
*
* helper functions pointer_construct/pointer_destroy:
*
****************************************************************************/
#ifdef __cplusplus
namespace boost{ namespace re_detail{
#ifdef BOOST_MSVC
#pragma warning (push)
#pragma warning (disable : 4100)
#endif
template <class T>
inline void pointer_destroy(T* p)
{ p->~T(); (void)p; }
#ifdef BOOST_MSVC
#pragma warning (pop)
#endif
template <class T>
inline void pointer_construct(T* p, const T& t)
{ new (p) T(t); }
}} // namespaces
#endif
/*****************************************************************************
*
* helper memory allocation functions:

View File

@ -23,6 +23,10 @@
#include <boost/regex/config.hpp>
#endif
#include <stdexcept>
#include <cstddef>
#include <boost/regex/v4/error_type.hpp>
namespace boost{
#ifdef BOOST_HAS_ABI_HEADERS
@ -58,6 +62,21 @@ private:
std::ptrdiff_t m_position;
};
namespace re_detail{
BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex);
template <class traits>
void raise_error(const traits& t, unsigned code)
{
(void)t; // warning suppression
std::runtime_error e(t.error_string(code));
::boost::re_detail::raise_runtime_error(e);
}
}
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif

View File

@ -337,9 +337,9 @@ re_syntax_base* basic_regex_creator<charT, traits>::append_set(
//
// fill in the basics:
//
result->csingles = static_cast<unsigned int>(std::distance(char_set.singles_begin(), char_set.singles_end()));
result->cranges = static_cast<unsigned int>(std::distance(char_set.ranges_begin(), char_set.ranges_end())) / 2;
result->cequivalents = static_cast<unsigned int>(std::distance(char_set.equivalents_begin(), char_set.equivalents_end()));
result->csingles = static_cast<unsigned int>(::boost::re_detail::distance(char_set.singles_begin(), char_set.singles_end()));
result->cranges = static_cast<unsigned int>(::boost::re_detail::distance(char_set.ranges_begin(), char_set.ranges_end())) / 2;
result->cequivalents = static_cast<unsigned int>(::boost::re_detail::distance(char_set.equivalents_begin(), char_set.equivalents_end()));
result->cclasses = char_set.classes();
if(flags() & regbase::icase)
{

View File

@ -110,7 +110,7 @@ void basic_regex_parser<charT, traits>::parse(const charT* p1, const charT* p2,
// 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));
fail(regex_constants::error_paren, ::boost::re_detail::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);
@ -320,7 +320,7 @@ bool basic_regex_parser<charT, traits>::parse_open_paren()
// we either have a ')' or we have run out of characters prematurely:
//
if(m_position == m_end)
this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
this->fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_end));
BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
++m_position;
//
@ -511,7 +511,7 @@ bool basic_regex_parser<charT, traits>::parse_repeat(std::size_t low, std::size_
}
if(0 == this->m_last_state)
{
fail(regex_constants::error_badrepeat, std::distance(m_base, m_position));
fail(regex_constants::error_badrepeat, ::boost::re_detail::distance(m_base, m_position));
}
if(this->m_last_state->type == syntax_element_endmark)
{
@ -1039,13 +1039,15 @@ charT basic_regex_parser<charT, traits>::unescape_character()
fail(regex_constants::error_escape, m_position - m_base);
return result;
}
/*
if((*m_position < charT('@'))
|| (*m_position > charT(125)) )
{
fail(regex_constants::error_escape, m_position - m_base);
return result;
}
result = static_cast<charT>(*m_position - charT('@'));
*/
result = static_cast<charT>(*m_position % 32);
break;
case regex_constants::escape_type_hex:
++m_position;
@ -1090,7 +1092,7 @@ charT basic_regex_parser<charT, traits>::unescape_character()
{
// an octal escape sequence, the first character must be a zero
// followed by up to 3 octal digits:
std::ptrdiff_t len = (std::min)(std::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));
std::ptrdiff_t len = (std::min)(::boost::re_detail::distance(m_position, m_end), static_cast<std::ptrdiff_t>(4));
int val = this->m_traits.toi(m_position, m_position + len, 8);
if(val < 0)
fail(regex_constants::error_escape, m_position - m_base);
@ -1353,7 +1355,7 @@ bool basic_regex_parser<charT, traits>::parse_perl_extension()
// we either have a ')' or we have run out of characters prematurely:
//
if(m_position == m_end)
this->fail(regex_constants::error_paren, std::distance(m_base, m_end));
this->fail(regex_constants::error_paren, ::boost::re_detail::distance(m_base, m_end));
BOOST_ASSERT(this->m_traits.syntax_type(*m_position) == regex_constants::syntax_close_mark);
++m_position;
//

View File

@ -651,6 +651,14 @@ public:
{
return icase ? m_pimpl->m_pctype->tolower(c) : c;
}
charT tolower(charT c) const
{
return m_pimpl->m_pctype->tolower(c);
}
charT toupper(charT c) const
{
return m_pimpl->m_pctype->toupper(c);
}
string_type transform(const charT* p1, const charT* p2) const
{
return m_pimpl->m_pcollate->transform(p1, p2);

View File

@ -26,6 +26,12 @@
#include <boost/regex/v4/match_flags.hpp>
#include <boost/regex/v4/error_type.hpp>
#ifdef __cplusplus
#include <cstddef>
#else
#include <stddef.h>
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif

View File

@ -92,7 +92,7 @@ public:
const sub_match<BidiIterator>& s = m_subs[sub];
if(s.matched)
{
return boost::re_detail::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
return ::boost::re_detail::distance((BidiIterator)(m_base), (BidiIterator)(s.first));
}
}
return ~static_cast<difference_type>(0);
@ -151,6 +151,25 @@ public:
{
return regex_format(*this, fmt, flags);
}
// format with locale:
template <class OutputIterator, class RegexT>
OutputIterator format(OutputIterator out,
const string_type& fmt,
match_flag_type flags,
const RegexT& re) const
{
return ::boost::re_detail::regex_format_imp(out, *this, fmt.data(), fmt.data() + fmt.size(), flags, re.get_traits());
}
template <class RegexT>
string_type format(const string_type& fmt,
match_flag_type flags,
const RegexT& re) const
{
string_type result;
re_detail::string_out_iterator<string_type> i(result);
::boost::re_detail::regex_format_imp(i, *this, fmt.data(), fmt.data() + fmt.size(), flags, re.get_traits());
return result;
}
allocator_type get_allocator() const
{
@ -278,13 +297,13 @@ void BOOST_REGEX_CALL match_results<BidiIterator, Allocator>::maybe_assign(const
{
//
// leftmost takes priority over longest:
base1 = boost::re_detail::distance(base, p1->first);
base2 = boost::re_detail::distance(base, p2->first);
base1 = ::boost::re_detail::distance(base, p1->first);
base2 = ::boost::re_detail::distance(base, p2->first);
if(base1 < base2) return;
if(base2 < base1) break;
len1 = boost::re_detail::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
len2 = boost::re_detail::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
len1 = ::boost::re_detail::distance((BidiIterator)p1->first, (BidiIterator)p1->second);
len2 = ::boost::re_detail::distance((BidiIterator)p2->first, (BidiIterator)p2->second);
if((len1 != len2) || ((p1->matched == false) && (p2->matched == true)))
break;
if((p1->matched == true) && (p2->matched == false))

View File

@ -101,6 +101,7 @@ template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(
protected_proc_type proc)
{
/*
__try{
return (this->*proc)();
}__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
@ -111,6 +112,12 @@ bool perl_matcher<BidiIterator, Allocator, traits>::protected_call(
raise_error<traits>(traits_inst, regex_constants::error_size);
// and we never really get here at all:
return false;
*/
::boost::re_detail::concrete_protected_call
<perl_matcher<BidiIterator, Allocator, traits> >
obj(this, proc);
return obj.execute();
}
#endif
@ -664,7 +671,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_restart_continue()
template <class BidiIterator, class Allocator, class traits>
bool perl_matcher<BidiIterator, Allocator, traits>::match_backstep()
{
std::ptrdiff_t maxlen = std::distance(search_base, position);
std::ptrdiff_t maxlen = ::boost::re_detail::distance(search_base, position);
if(maxlen < static_cast<const re_brace*>(pstate)->index)
return false;
std::advance(position, -static_cast<const re_brace*>(pstate)->index);

View File

@ -582,7 +582,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
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 = static_cast<unsigned>((std::min)(static_cast<unsigned>(::boost::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);
@ -629,13 +629,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_char_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)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (traits_inst.translate(*position, icase) == what))
{
++position;
}
count = (unsigned)re_detail::distance(origin, position);
count = (unsigned)::boost::re_detail::distance(origin, position);
}
else
{
@ -696,13 +696,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::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)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
}
count = (unsigned)re_detail::distance(origin, position);
count = (unsigned)::boost::re_detail::distance(origin, position);
}
else
{
@ -764,13 +764,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_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)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
{
++position;
}
count = (unsigned)re_detail::distance(origin, position);
count = (unsigned)::boost::re_detail::distance(origin, position);
}
else
{

View File

@ -436,7 +436,7 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_dot_repeat_fast()
// 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>(::boost::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);
@ -494,13 +494,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_char_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)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (traits_inst.translate(*position, icase) == what))
{
++position;
}
count = (unsigned)re_detail::distance(origin, position);
count = (unsigned)::boost::re_detail::distance(origin, position);
}
else
{
@ -582,13 +582,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::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)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && map[static_cast<unsigned char>(traits_inst.translate(*position, icase))])
{
++position;
}
count = (unsigned)re_detail::distance(origin, position);
count = (unsigned)::boost::re_detail::distance(origin, position);
}
else
{
@ -671,13 +671,13 @@ bool perl_matcher<BidiIterator, Allocator, traits>::match_long_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)::boost::re_detail::distance(position, last), desired));
BidiIterator origin(position);
while((position != end) && (position != re_is_set_member(position, last, set, re.get_data(), icase)))
{
++position;
}
count = (unsigned)re_detail::distance(origin, position);
count = (unsigned)::boost::re_detail::distance(origin, position);
}
else
{

View File

@ -0,0 +1,65 @@
/*
*
* 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_PROTECTED_CALL_HPP
#define BOOST_REGEX_V4_PROTECTED_CALL_HPP
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX
#endif
namespace boost{
namespace re_detail{
class BOOST_REGEX_DECL abstract_protected_call
{
public:
bool BOOST_REGEX_CALL execute()const;
private:
virtual bool call()const = 0;
};
template <class T>
class concrete_protected_call
: public abstract_protected_call
{
public:
typedef bool (T::*proc_type)();
concrete_protected_call(T* o, proc_type p)
: obj(o), proc(p) {}
private:
virtual bool call()const;
T* obj;
proc_type proc;
};
template <class T>
bool concrete_protected_call<T>::call()const
{
return (obj->*proc)();
}
}
} // namespace boost
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_SUFFIX
#endif
#endif

View File

@ -21,39 +21,35 @@
#ifndef BOOST_RE_REGEX_HPP_INCLUDED
#define BOOST_RE_REGEX_HPP_INCLUDED
#ifndef BOOST_RE_CREGEX_HPP
#include <boost/cregex.hpp>
#endif
#ifdef __cplusplus
// what follows is all C++ don't include in C builds!!
#ifdef BOOST_REGEX_DEBUG
# include <iosfwd>
#endif
#include <new>
#include <cstring>
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#ifndef BOOST_REGEX_WORKAROUND_HPP
#include <boost/regex/v4/regex_workaround.hpp>
#endif
#ifndef BOOST_REGEX_FWD_HPP
#include <boost/regex_fwd.hpp>
#endif
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
#include <boost/regex/v4/regex_raw_buffer.hpp>
#endif
#ifndef BOOST_REGEX_KMP_HPP
#include <boost/regex/v4/regex_kmp.hpp>
#endif
#ifndef BOOST_RE_PAT_EXCEPT_HPP
#include <boost/regex/pattern_except.hpp>
#endif
#ifndef BOOST_REGEX_TRAITS_HPP
#include <boost/regex/regex_traits.hpp>
#endif
#include <boost/scoped_array.hpp>
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
#include <boost/regex/v4/error_type.hpp>
#endif
#ifndef BOOST_REGEX_V4_MATCH_FLAGS
#include <boost/regex/v4/match_flags.hpp>
#endif
#ifndef BOOST_REGEX_RAW_BUFFER_HPP
#include <boost/regex/v4/regex_raw_buffer.hpp>
#endif
#ifndef BOOST_RE_PAT_EXCEPT_HPP
#include <boost/regex/pattern_except.hpp>
#endif
#ifndef BOOST_REGEX_V4_CHAR_REGEX_TRAITS_HPP
#include <boost/regex/v4/char_regex_traits.hpp>
@ -67,9 +63,6 @@
#ifndef BOOST_REGEX_V4_ITERATOR_TRAITS_HPP
#include <boost/regex/v4/iterator_traits.hpp>
#endif
#ifndef BOOST_REGEX_V4_ITERATOR_TRAITS_HPP
#include <boost/regex/v4/iterator_traits.hpp>
#endif
#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP
#include <boost/regex/v4/basic_regex.hpp>
#endif
@ -131,6 +124,9 @@ typedef match_results<std::wstring::const_iterator> wsmatch;
#endif
} // namespace boost
#ifndef BOOST_REGEX_V4_PROTECTED_CALL_HPP
#include <boost/regex/v4/protected_call.hpp>
#endif
#ifndef BOOST_REGEX_MATCHER_HPP
#include <boost/regex/v4/perl_matcher.hpp>
#endif
@ -140,6 +136,12 @@ typedef match_results<std::wstring::const_iterator> wsmatch;
#ifndef BOOST_REGEX_V4_REGEX_SEARCH_HPP
#include <boost/regex/v4/regex_search.hpp>
#endif
#ifndef BOOST_REGEX_ITERATOR_HPP
#include <boost/regex/v4/regex_iterator.hpp>
#endif
#ifndef BOOST_REGEX_TOKEN_ITERATOR_HPP
#include <boost/regex/v4/regex_token_iterator.hpp>
#endif
#ifndef BOOST_REGEX_V4_REGEX_GREP_HPP
#include <boost/regex/v4/regex_grep.hpp>
#endif
@ -152,12 +154,6 @@ typedef match_results<std::wstring::const_iterator> wsmatch;
#ifndef BOOST_REGEX_SPLIT_HPP
#include <boost/regex/v4/regex_split.hpp>
#endif
#ifndef BOOST_REGEX_ITERATOR_HPP
#include <boost/regex/v4/regex_iterator.hpp>
#endif
#ifndef BOOST_REGEX_TOKEN_ITERATOR_HPP
#include <boost/regex/v4/regex_token_iterator.hpp>
#endif
#endif // __cplusplus

View File

@ -36,400 +36,509 @@ class match_results;
namespace re_detail{
template <class O, class I>
O BOOST_REGEX_CALL re_copy_out(O out, I first, I last)
//
// helper functions:
//
template <class charT>
std::ptrdiff_t global_length(const charT* p)
{
while(first != last)
std::ptrdiff_t n = 0;
while(*p)
{
*out = *first;
++out;
++first;
++p;
++n;
}
return out;
return n;
}
inline std::ptrdiff_t global_length(const char* p)
{
return (std::strlen)(p);
}
#ifndef BOOST_NO_WREGEX
inline std::ptrdiff_t global_length(const wchar_t* p)
{
return (std::wcslen)(p);
}
#endif
template <class charT>
inline charT global_lower(charT c)
{
return c;
}
template <class charT>
inline charT global_upper(charT c)
{
return c;
}
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_lower(char c);
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_upper(char c);
#ifndef BOOST_NO_WREGEX
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_lower(wchar_t c);
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_upper(wchar_t c);
#endif
template <class charT>
int global_value(charT c)
{
static const charT zero = '0';
static const charT nine = '9';
static const charT a = 'a';
static const charT f = 'f';
static const charT A = 'A';
static const charT F = 'F';
if((c >= zero) && (c <= nine))
return c - zero;
if((c >= a) && (c <= f))
return 10 + (c - a);
if((c >= A) && (c <= F))
return 10 + (c - A);
return -1;
}
template <class charT>
int global_toi(const charT*& p1, const charT* p2, int radix)
{
int next_value = global_value(*p1);
if((p1 == p2) || (next_value < 0) || (next_value >= radix))
return -1;
int result = 0;
while(p1 != p2)
{
next_value = global_value(*p1);
if((next_value < 0) || (next_value >= radix))
break;
result *= radix;
result += next_value;
++p1;
}
return result;
}
template <class charT, class traits_type>
void BOOST_REGEX_CALL re_skip_format(const charT*& fmt, const traits_type& traits_inst)
{
// dwa 9/13/00 - suppress incorrect unused parameter warning for MSVC
(void)traits_inst;
typedef typename traits_type::size_type traits_size_type;
typedef typename traits_type::string_type traits_string_type;
unsigned int parens = 0;
unsigned int c;
while(*fmt)
{
c = traits_inst.syntax_type(*fmt);
if((c == regex_constants::syntax_colon) && (parens == 0))
{
++fmt;
return;
}
else if(c == regex_constants::syntax_close_mark)
{
if(parens == 0)
{
++fmt;
return;
}
--parens;
}
else if(c == regex_constants::syntax_open_mark)
++parens;
else if(c == regex_constants::syntax_escape)
{
++fmt;
if(*fmt == 0)
return;
}
++fmt;
}
}
#ifdef BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN
//
// ugly hack for buggy output iterators
template <class T>
inline void oi_assign(T* p, T v)
// struct trivial_format_traits:
// defines minimum localisation support for formatting
// in the case that the actual regex traits is unavailable.
//
template <class charT>
struct trivial_format_traits
{
::boost::re_detail::pointer_destroy(p);
pointer_construct(p, v);
typedef charT char_type;
static std::ptrdiff_t length(const charT* p)
{
return global_length(p);
}
static charT tolower(charT c)
{
return ::boost::re_detail::global_lower(c);
}
static charT toupper(charT c)
{
return ::boost::re_detail::global_upper(c);
}
static int toi(const charT*& p1, const charT* p2, int radix)
{
return global_toi(p1, p2, radix);
}
};
template <class OutputIterator, class Results, class traits>
class basic_regex_formatter
{
public:
typedef typename traits::char_type char_type;
basic_regex_formatter(OutputIterator o, const Results& r, const traits& t)
: m_traits(t), m_results(r), m_out(o), m_state(output_copy) {}
OutputIterator format(const char_type* p1, const char_type* p2, match_flag_type f);
OutputIterator format(const char_type* p1, match_flag_type f)
{
return format(p1, p1 + m_traits.length(p1), f);
}
private:
typedef typename Results::value_type sub_match_type;
enum output_state
{
output_copy,
output_next_lower,
output_next_upper,
output_lower,
output_upper,
output_none
};
void put(char_type c);
void put(const sub_match_type& sub);
void format_all();
void format_perl();
void format_escape();
void format_conditional();
void format_until_scope_end();
const traits& m_traits; // the traits class for localised formatting operations
const Results& m_results; // the match_results being used.
OutputIterator m_out; // where to send output.
const char_type* m_position; // format string, current position
const char_type* m_end; // format string end
match_flag_type m_flags; // format flags to use
output_state m_state; // what to do with the next character
};
template <class OutputIterator, class Results, class traits>
OutputIterator basic_regex_formatter<OutputIterator, Results, traits>::format(const char_type* p1, const char_type* p2, match_flag_type f)
{
m_position = p1;
m_end = p2;
m_flags = f;
format_all();
return m_out;
}
#else
template <class OutputIterator, class Results, class traits>
void basic_regex_formatter<OutputIterator, Results, traits>::format_all()
{
// over and over:
while(m_position != m_end)
{
switch(*m_position)
{
case '&':
if(m_flags & ::boost::regex_constants::format_sed)
{
++m_position;
put(m_results[0]);
break;
}
put(*m_position++);
break;
case '\\':
format_escape();
break;
case '(':
if(m_flags & boost::regex_constants::format_all)
{
++m_position;
format_until_scope_end();
BOOST_ASSERT(*m_position == static_cast<char_type>(')'));
++m_position; // skip the closing ')'
break;
}
put(*m_position);
++m_position;
break;
case ')':
case ':':
if(m_flags & boost::regex_constants::format_all)
{
return;
}
put(*m_position);
++m_position;
break;
case '?':
if(m_flags & boost::regex_constants::format_all)
{
++m_position;
format_conditional();
break;
}
put(*m_position);
++m_position;
break;
case '$':
if((m_flags & format_sed) == 0)
{
format_perl();
break;
}
// fall through, not a special character:
default:
put(*m_position);
++m_position;
break;
}
}
}
template <class T>
inline void oi_assign(T* p, T v)
template <class OutputIterator, class Results, class traits>
void basic_regex_formatter<OutputIterator, Results, traits>::format_perl()
{
//
// if you get a compile time error in here then you either
// need to rewrite your output iterator to make it assignable
// (as is required by the standard), or define
// BOOST_NO_STD_OUTPUT_ITERATOR_ASSIGN to use the ugly hack above
*p = v;
}
#endif
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
//
// Ugly ugly hack,
// template don't merge if they contain switch statements so declare these
// templates in unnamed namespace (ie with internal linkage), each translation
// unit then gets its own local copy, it works seemlessly but bloats the app.
namespace{
#endif
//
// algorithm reg_format:
// takes the result of a match and a format string
// and merges them to produce a new string which
// is sent to an OutputIterator,
// _reg_format_aux does the actual work:
//
template <class OutputIterator, class Iterator, class charT, class traits_type>
OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
const match_results<Iterator>& m,
const charT*& fmt,
match_flag_type flags, const traits_type& traits_inst)
{
#ifdef __BORLANDC__
#pragma option push -w-8037
#endif
const charT* fmt_end = fmt;
while(*fmt_end) ++ fmt_end;
typedef typename traits_type::size_type traits_size_type;
typedef typename traits_type::string_type traits_string_type;
while(*fmt)
// On entry *m_position points to a '$' character
// output the information that goes with it:
//
BOOST_ASSERT(*m_position == '$');
//
// see if this is a trailing '$':
//
if(++m_position == m_end)
{
switch(traits_inst.syntax_type(*fmt))
--m_position;
put(*m_position);
++m_position;
return;
}
//
// OK find out what kind it is:
//
switch(*m_position)
{
case '&':
++m_position;
put(this->m_results[0]);
break;
case '`':
++m_position;
put(this->m_results.prefix());
break;
case '\'':
++m_position;
put(this->m_results.suffix());
break;
case '$':
put(*m_position++);
break;
default:
// see if we have a number:
{
case regex_constants::syntax_dollar:
if(flags & format_sed)
std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), std::distance(m_position, m_end));
int v = m_traits.toi(m_position, m_position + len, 10);
if(v < 0)
{
// no perl style replacement,
// $ is an ordinary character:
goto default_opt;
}
++fmt;
if(*fmt == 0) // oops trailing $
{
--fmt;
*out = *fmt;
++out;
return out;
}
switch(traits_inst.syntax_type(*fmt))
{
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 regex_constants::escape_type_end_buffer:
oi_assign(&out, re_copy_out(out, Iterator(m[-2].first), Iterator(m[-2].second)));
++fmt;
continue;
case regex_constants::syntax_digit:
{
expand_sub:
unsigned int index = traits_inst.toi(fmt, fmt_end, 10);
if(index < m.size())
oi_assign(&out, re_copy_out(out, Iterator(m[index].first), Iterator(m[index].second)));
continue;
}
}
// anything else:
if(*fmt == '&')
{
oi_assign(&out, re_copy_out(out, Iterator(m[0].first), Iterator(m[0].second)));
++fmt;
}
else
{
// probably an error, treat as a literal '$'
--fmt;
*out = *fmt;
++out;
++fmt;
}
continue;
case regex_constants::syntax_escape:
{
// escape sequence:
++fmt;
charT c(*fmt);
if(*fmt == 0)
{
--fmt;
*out = *fmt;
++out;
++fmt;
return out;
}
switch(traits_inst.syntax_type(*fmt))
{
case regex_constants::escape_type_control_a:
c = '\a';
++fmt;
// leave the $ as is, and carry on:
--m_position;
put(*m_position);
++m_position;
break;
case regex_constants::escape_type_control_f:
c = '\f';
++fmt;
break;
case regex_constants::escape_type_control_n:
c = '\n';
++fmt;
break;
case regex_constants::escape_type_control_r:
c = '\r';
++fmt;
break;
case regex_constants::escape_type_control_t:
c = '\t';
++fmt;
break;
case regex_constants::escape_type_control_v:
c = '\v';
++fmt;
break;
case regex_constants::escape_type_hex:
++fmt;
if(fmt == fmt_end)
{
*out = *--fmt;
++out;
return out;
}
// maybe have \x{ddd}
if(traits_inst.syntax_type(*fmt) == regex_constants::syntax_open_brace)
{
++fmt;
if(fmt == fmt_end)
{
fmt -= 2;
*out = *fmt;
++out;
++fmt;
continue;
}
int val = traits_inst.toi(fmt, fmt_end, 16);
if(val < 0)
{
fmt -= 2;
*out = *fmt;
++out;
++fmt;
continue;
}
c = static_cast<charT>(val);
if(traits_inst.syntax_type(*fmt) != regex_constants::syntax_close_brace)
{
while(traits_inst.syntax_type(*fmt) != regex_constants::syntax_escape)
--fmt;
++fmt;
*out = *fmt;
++out;
++fmt;
continue;
}
++fmt;
break;
}
else
{
int val = traits_inst.toi(fmt, fmt_end, 16);
if(val < 0)
{
--fmt;
*out = *fmt;
++out;
++fmt;
continue;
}
c = static_cast<charT>(val);
}
break;
case regex_constants::escape_type_ascii_control:
++fmt;
if(fmt == fmt_end)
{
--fmt;
*out = *fmt;
++out;
return out;
}
if( (*fmt < static_cast<charT>('@')) || (*fmt > static_cast<charT>('z')) )
{
--fmt;
*out = *fmt;
++out;
++fmt;
break;
}
c = static_cast<charT>(*fmt - static_cast<charT>('@'));
++fmt;
break;
case regex_constants::escape_type_e:
c = (charT)27;
++fmt;
break;
case regex_constants::syntax_digit:
if(flags & format_sed)
goto expand_sub;
else
c = static_cast<charT>(traits_inst.toi(fmt, fmt_end, 8));
break;
default:
//c = *fmt;
++fmt;
}
*out = c;
++out;
continue;
}
case regex_constants::syntax_open_mark:
if(0 == (flags & format_all))
{
*out = *fmt;
++out;
++fmt;
continue;
}
else
{
++fmt; // recurse
oi_assign(&out, _reg_format_aux(out, m, fmt, flags, traits_inst));
continue;
}
case regex_constants::syntax_close_mark:
if(0 == (flags & format_all))
{
*out = *fmt;
++out;
++fmt;
continue;
}
else
{
++fmt; // return from recursion
return out;
}
case regex_constants::syntax_colon:
if(flags & regex_constants::format_is_if)
{
++fmt;
return out;
}
*out = *fmt;
++out;
++fmt;
continue;
case regex_constants::syntax_question:
{
if(0 == (flags & format_all))
{
*out = *fmt;
++out;
++fmt;
continue;
}
else
{
++fmt;
if(*fmt == 0)
{
--fmt;
*out = *fmt;
++out;
++fmt;
return out;
}
unsigned int id = traits_inst.toi(fmt, fmt_end, 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(*(fmt-1)) == regex_constants::syntax_colon)
re_skip_format(fmt, traits_inst);
}
else
{
re_skip_format(fmt, traits_inst);
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;
}
}
default:
default_opt:
if((flags & format_sed) && (*fmt == '&'))
{
oi_assign(&out, re_copy_out(out, Iterator(m[0].first), Iterator(m[0].second)));
++fmt;
continue;
}
*out = *fmt;
++out;
++fmt;
// otherwise output sub v:
put(this->m_results[v]);
}
}
return out;
#ifdef __BORLANDC__
#pragma option pop
#endif
}
#if defined(BOOST_REGEX_NO_TEMPLATE_SWITCH_MERGE)
} // namespace
#endif
template <class OutputIterator, class Results, class traits>
void basic_regex_formatter<OutputIterator, Results, traits>::format_escape()
{
// skip the escape and check for trailing escape:
if(++m_position == m_end)
{
put(static_cast<char_type>('\\'));
return;
}
// now switch on the escape type:
switch(*m_position)
{
case 'a':
put(static_cast<char_type>('\a'));
++m_position;
break;
case 'f':
put(static_cast<char_type>('\f'));
++m_position;
break;
case 'n':
put(static_cast<char_type>('\n'));
++m_position;
break;
case 'r':
put(static_cast<char_type>('\r'));
++m_position;
break;
case 't':
put(static_cast<char_type>('\t'));
++m_position;
break;
case 'v':
put(static_cast<char_type>('\v'));
++m_position;
break;
case 'x':
if(++m_position == m_end)
{
put(static_cast<char_type>('x'));
return;
}
// maybe have \x{ddd}
if(*m_position == static_cast<char_type>('{'))
{
++m_position;
int val = m_traits.toi(m_position, m_end, 16);
if(val < 0)
{
// invalid value treat everything as literals:
put(static_cast<char_type>('x'));
put(static_cast<char_type>('{'));
return;
}
if(*m_position != static_cast<char_type>('}'))
{
while(*m_position != static_cast<char_type>('\\'))
--m_position;
++m_position;
put(*m_position++);
return;
}
++m_position;
put(static_cast<char_type>(val));
return;
}
else
{
std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), std::distance(m_position, m_end));
int val = m_traits.toi(m_position, m_position + len, 16);
if(val < 0)
{
--m_position;
put(*m_position++);
return;
}
put(static_cast<char_type>(val));
}
break;
case 'c':
if(++m_position == m_end)
{
--m_position;
put(*m_position++);
return;
}
put(static_cast<char_type>(*m_position++ % 32));
break;
case 'e':
put(static_cast<char_type>(27));
++m_position;
break;
default:
// see if we have a \n sed style backreference:
int v = m_traits.toi(m_position, m_position+1, 10);
if((v > 0) || ((v == 0) && (m_flags & ::boost::regex_constants::format_sed)))
{
put(m_results[v]);
break;
}
else if(v == 0)
{
// octal ecape sequence:
--m_position;
std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(4), std::distance(m_position, m_end));
v = m_traits.toi(m_position, m_position + len, 8);
BOOST_ASSERT(v >= 0);
put(static_cast<char_type>(v));
break;
}
// Otherwise output the character "as is":
put(*m_position++);
break;
}
}
template <class OutputIterator, class Results, class traits>
void basic_regex_formatter<OutputIterator, Results, traits>::format_conditional()
{
if(m_position == m_end)
{
// oops trailing '?':
put(static_cast<char_type>('?'));
return;
}
std::ptrdiff_t len = (std::min)(static_cast<std::ptrdiff_t>(2), std::distance(m_position, m_end));
int v = m_traits.toi(m_position, m_position + len, 10);
if(v < 0)
{
// oops not a number:
put(static_cast<char_type>('?'));
return;
}
// output varies depending upon whether sub-expression v matched or not:
if(m_results[v].matched)
{
format_all();
if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
{
// skip the ':':
++m_position;
// save output state, then turn it off:
output_state saved_state = m_state;
m_state = output_none;
// format the rest of this scope:
format_until_scope_end();
// restore output state:
m_state = saved_state;
}
}
else
{
// save output state, then turn it off:
output_state saved_state = m_state;
m_state = output_none;
// format until ':' or ')':
format_all();
// restore state:
m_state = saved_state;
if((m_position != m_end) && (*m_position == static_cast<char_type>(':')))
{
// skip the ':':
++m_position;
// format the rest of this scope:
format_until_scope_end();
}
}
}
template <class OutputIterator, class Results, class traits>
void basic_regex_formatter<OutputIterator, Results, traits>::format_until_scope_end()
{
do
{
format_all();
if((m_position == m_end) || (*m_position == static_cast<char_type>(')')))
return;
put(*m_position++);
}while(m_position != m_end);
}
template <class OutputIterator, class Results, class traits>
void basic_regex_formatter<OutputIterator, Results, traits>::put(char_type c)
{
// write a single character to output
// according to which case translation mode we are in:
switch(this->m_state)
{
case output_none:
return;
case output_next_lower:
c = m_traits.tolower(c);
this->m_state = output_copy;
break;
case output_next_upper:
c = m_traits.toupper(c);
this->m_state = output_copy;
break;
case output_lower:
c = m_traits.tolower(c);
break;
case output_upper:
c = m_traits.toupper(c);
break;
default:
break;
}
*m_out = c;
++m_out;
}
template <class OutputIterator, class Results, class traits>
void basic_regex_formatter<OutputIterator, Results, traits>::put(const sub_match_type& sub)
{
typedef typename sub_match_type::iterator iterator_type;
iterator_type i = sub.first;
while(i != sub.second)
{
put(*i);
++i;
}
}
template <class S>
class string_out_iterator
@ -447,30 +556,21 @@ public:
}
};
template <class OutputIterator, class Iterator, class charT, class traits_type>
class merge_out_predicate
template <class OutputIterator, class Iterator, class charT, class traits>
OutputIterator regex_format_imp(OutputIterator out,
const match_results<Iterator>& m,
const charT* p1, const charT* p2,
match_flag_type flags,
const traits& t
)
{
OutputIterator* out;
Iterator* last;
const charT* fmt;
match_flag_type flags;
const traits_type* pt;
re_detail::basic_regex_formatter<
OutputIterator,
match_results<Iterator>,
traits > f(out, m, t);
return f.format(p1, p2, flags);
}
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>& m)
{
const charT* f = fmt;
if(0 == (flags & format_no_copy))
oi_assign(out, re_copy_out(*out, Iterator(m[-1].first), Iterator(m[-1].second)));
oi_assign(out, _reg_format_aux(*out, m, f, flags, *pt));
*last = m[-2].first;
return flags & format_first_only ? false : true;
}
};
} // namespace re_detail
@ -481,8 +581,8 @@ OutputIterator regex_format(OutputIterator out,
match_flag_type flags = format_all
)
{
regex_traits<charT> t;
return re_detail::_reg_format_aux(out, m, fmt, flags, t);
re_detail::trivial_format_traits<charT> traits;
return regex_format_imp(out, m, fmt, fmt + traits.length(fmt), flags, traits);
}
template <class OutputIterator, class Iterator, class charT>
@ -492,9 +592,8 @@ OutputIterator regex_format(OutputIterator out,
match_flag_type flags = format_all
)
{
regex_traits<charT> t;
const charT* start = fmt.c_str();
return re_detail::_reg_format_aux(out, m, start, flags, t);
re_detail::trivial_format_traits<charT> traits;
return regex_format_imp(out, m, fmt.data(), fmt.data() + fmt.size(), flags, traits);
}
template <class Iterator, class charT>
@ -504,7 +603,8 @@ std::basic_string<charT> regex_format(const match_results<Iterator>& m,
{
std::basic_string<charT> result;
re_detail::string_out_iterator<std::basic_string<charT> > i(result);
regex_format(i, m, fmt, flags);
re_detail::trivial_format_traits<charT> traits;
regex_format_imp(i, m, fmt, fmt + traits.length(fmt), flags, traits);
return result;
}
@ -515,7 +615,8 @@ std::basic_string<charT> regex_format(const match_results<Iterator>& m,
{
std::basic_string<charT> result;
re_detail::string_out_iterator<std::basic_string<charT> > i(result);
regex_format(i, m, fmt.c_str(), flags);
re_detail::trivial_format_traits<charT> traits;
regex_format_imp(i, m, fmt.data(), fmt.data() + fmt.size(), flags, traits);
return result;
}

View File

@ -37,21 +37,21 @@ class regex_iterator_implementation
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator base; // start of sequence
BidirectionalIterator end; // end of sequence
const regex_type* pre; // the expression
const regex_type re; // the expression
match_flag_type flags; // flags for matching
public:
regex_iterator_implementation(const regex_type* p, BidirectionalIterator last, match_flag_type f)
: base(), end(last), pre(p), flags(f){}
: base(), end(last), re(*p), flags(f){}
bool init(BidirectionalIterator first)
{
base = first;
return regex_search(first, end, what, *pre, flags);
return regex_search(first, end, what, re, flags);
}
bool compare(const regex_iterator_implementation& that)
{
if(this == &that) return true;
return (pre == that.pre) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
return (re == that.re) && (end == that.end) && (flags == that.flags) && (what[0].first == that.what[0].first) && (what[0].second == that.what[0].second);
}
const match_results<BidirectionalIterator>& get()
{ return what; }
@ -63,7 +63,7 @@ public:
match_flag_type f(flags);
if(!what.length())
f |= regex_constants::match_not_initial_null;
bool result = regex_search(next_start, end, what, *pre, f);
bool result = regex_search(next_start, end, what, re, f);
if(result)
what.set_base(base);
return result;

View File

@ -55,7 +55,7 @@ kmp_info<charT>* kmp_compile(iterator first, iterator last, charT, Trans transla
typedef typename boost::detail::rebind_allocator<char, Allocator>::type atype;
int i, j, m;
i = 0;
m = static_cast<int>(boost::re_detail::distance(first, last));
m = static_cast<int>(::boost::re_detail::distance(first, last));
++m;
unsigned int size = sizeof(kmp_info<charT>) + sizeof(int)*m + sizeof(charT)*m;
--m;

View File

@ -25,6 +25,8 @@
#include <boost/regex/config.hpp>
#endif
#include <algorithm>
namespace boost{
namespace re_detail{

View File

@ -28,18 +28,38 @@ namespace boost{
# include BOOST_ABI_PREFIX
#endif
template <class OutputIterator, class Iterator, class traits, class charT>
template <class OutputIterator, class BidirectionalIterator, class traits, class charT>
OutputIterator regex_replace(OutputIterator out,
Iterator first,
Iterator last,
BidirectionalIterator first,
BidirectionalIterator last,
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, 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);
regex_iterator<BidirectionalIterator, charT, traits> i(first, last, e, flags);
regex_iterator<BidirectionalIterator, charT, traits> j;
if(i == j)
{
if(!(flags & regex_constants::format_no_copy))
out = std::copy(first, last, out);
}
else
{
BidirectionalIterator last_m = first;
while(i != j)
{
if(!(flags & regex_constants::format_no_copy))
out = std::copy(i->prefix().first, i->prefix().second, out);
out = i->format(out, fmt, flags, e);
last_m = (*i)[0].second;
if(flags & regex_constants::format_first_only)
break;
++i;
}
if(!(flags & regex_constants::format_no_copy))
out = std::copy(last_m, last, out);
}
return out;
}
template <class OutputIterator, class Iterator, class traits, class charT>

View File

@ -54,7 +54,7 @@ class regex_token_iterator_implementation
match_results<BidirectionalIterator> what; // current match
BidirectionalIterator end; // end of search area
const regex_type* pre; // the expression
const regex_type re; // the expression
match_flag_type flags; // match flags
value_type result; // the current string result
int N; // the current sub-expression being enumerated
@ -62,15 +62,15 @@ class regex_token_iterator_implementation
public:
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, int sub, match_flag_type f)
: end(last), pre(p), flags(f){ subs.push_back(sub); }
: end(last), re(*p), flags(f){ subs.push_back(sub); }
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const std::vector<int>& v, match_flag_type f)
: end(last), pre(p), subs(v), flags(f){}
: end(last), re(*p), flags(f), subs(v){}
#if (BOOST_WORKAROUND(__BORLANDC__, >= 0x560) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)))\
|| BOOST_WORKAROUND(BOOST_MSVC, < 1300) \
|| BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3003))
template <class T>
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const T& submatches, match_flag_type f)
: end(last), pre(p), flags(f)
: end(last), re(*p), flags(f)
{
// assert that T really is an array:
BOOST_STATIC_ASSERT(::boost::is_array<T>::value);
@ -83,7 +83,7 @@ public:
#else
template <std::size_t CN>
regex_token_iterator_implementation(const regex_type* p, BidirectionalIterator last, const int (&submatches)[CN], match_flag_type f)
: end(last), pre(p), flags(f)
: end(last), re(*p), flags(f)
{
for(std::size_t i = 0; i < CN; ++i)
{
@ -95,7 +95,7 @@ public:
bool init(BidirectionalIterator first)
{
N = 0;
if(regex_search(first, end, what, *pre, flags) == true)
if(regex_search(first, end, what, re, flags) == true)
{
N = 0;
result = ((subs[N] == -1) ? what.prefix() : what[(int)subs[N]]);
@ -113,7 +113,7 @@ public:
bool compare(const regex_token_iterator_implementation& that)
{
if(this == &that) return true;
return (pre == that.pre)
return (re == that.re)
&& (end == that.end)
&& (flags == that.flags)
&& (N == that.N)
@ -135,7 +135,7 @@ public:
if(what.prefix().first != what[0].second)
flags |= match_prev_avail;
BidirectionalIterator last_end(what[0].second);
if(regex_search(last_end, end, what, *pre, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags)))
if(regex_search(last_end, end, what, re, ((what[0].first == what[0].second) ? flags | regex_constants::match_not_initial_null : flags)))
{
N =0;
result =((subs[N] == -1) ? what.prefix() : what[subs[N]]);

View File

@ -19,11 +19,11 @@
#ifndef BOOST_REGEX_TRAITS_HPP_INCLUDED
#define BOOST_REGEX_TRAITS_HPP_INCLUDED
#ifndef BOOST_RE_CREGEX_HPP
#include <boost/cregex.hpp>
#ifndef BOOST_REGEX_CONFIG_HPP
#include <boost/regex/config.hpp>
#endif
#ifndef BOOST_REGEX_CSTRING_HPP
#include <boost/regex/v4/regex_cstring.hpp>
#ifndef BOOST_REGEX_WORKAROUND_HPP
#include <boost/regex/v4/regex_workaround.hpp>
#endif
#ifndef BOOST_REGEX_SYNTAX_TYPE_HPP
#include <boost/regex/v4/syntax_type.hpp>
@ -34,6 +34,9 @@
#ifndef BOOST_CPP_REGEX_TRAITS_HPP_INCLUDED
#include <boost/regex/v4/cpp_regex_traits.hpp>
#endif
#ifndef BOOST_REGEX_FWD_HPP_INCLUDED
#include <boost/regex_fwd.hpp>
#endif
#ifdef BOOST_HAS_ABI_HEADERS
# include BOOST_ABI_PREFIX

View File

@ -0,0 +1,114 @@
/*
*
* Copyright (c) 1998-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_workarounds.cpp
* VERSION see <boost/version.hpp>
* DESCRIPTION: Declares Misc workarounds.
*/
#ifndef BOOST_REGEX_WORKAROUND_HPP
#define BOOST_REGEX_WORKAROUND_HPP
#include <new>
#include <cstring>
#include <cstdlib>
#include <cstddef>
#include <cassert>
#include <string>
#include <stdexcept>
#include <iterator>
#include <iosfwd>
#include <vector>
#include <map>
#include <limits>
#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/detail/allocator.hpp>
#include <boost/throw_exception.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/mpl/bool_fwd.hpp>
#ifndef BOOST_NO_STD_LOCALE
# include <locale>
#endif
namespace boost{ namespace re_detail{
#ifdef BOOST_NO_STD_DISTANCE
template <class T>
std::ptrdiff_t distance(const T& x, const T& y)
{ return y - x; }
#else
using std::distance;
#endif
}}
#ifdef BOOST_REGEX_NO_BOOL
# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>((x) ? true : false)
#else
# ifdef BOOST_MSVC
// warning suppression with VC6:
# pragma warning(disable: 4800)
# pragma warning(disable: 4786)
# endif
# define BOOST_REGEX_MAKE_BOOL(x) static_cast<bool>(x)
#endif
/*****************************************************************************
*
* Fix broken broken namespace support:
*
****************************************************************************/
#if defined(BOOST_NO_STDC_NAMESPACE) && defined(__cplusplus)
namespace std{
using ::ptrdiff_t;
using ::size_t;
using ::abs;
}
#endif
/*****************************************************************************
*
* helper functions pointer_construct/pointer_destroy:
*
****************************************************************************/
#ifdef __cplusplus
namespace boost{ namespace re_detail{
#ifdef BOOST_MSVC
#pragma warning (push)
#pragma warning (disable : 4100)
#endif
template <class T>
inline void pointer_destroy(T* p)
{ p->~T(); (void)p; }
#ifdef BOOST_MSVC
#pragma warning (pop)
#endif
template <class T>
inline void pointer_construct(T* p, const T& t)
{ new (p) T(t); }
}} // namespaces
#endif
#endif // include guard

View File

@ -161,7 +161,7 @@ enum
force_newline = 2,
test_not_newline = 2,
test_newline = 3,
test_newline = 3
};
struct re_dot : public re_syntax_base
{

View File

@ -35,6 +35,8 @@ struct sub_match : public std::pair<BidiIterator, BidiIterator>
typedef typename re_detail::regex_iterator_traits<BidiIterator>::difference_type difference_type;
#endif
typedef BidiIterator iterator_type;
typedef BidiIterator iterator;
typedef BidiIterator const_iterator;
bool matched;
@ -47,13 +49,13 @@ struct sub_match : public std::pair<BidiIterator, BidiIterator>
}
difference_type BOOST_REGEX_CALL length()const
{
difference_type n = boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
difference_type n = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
return n;
}
std::basic_string<value_type> str()const
{
std::basic_string<value_type> result;
std::size_t len = boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
std::size_t len = ::boost::re_detail::distance((BidiIterator)this->first, (BidiIterator)this->second);
result.reserve(len);
BidiIterator i = this->first;
while(i != this->second)

View File

@ -33,6 +33,12 @@ typedef boost::match_flag_type match_flag_type;
#endif
#include <cstdio>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::sprintf;
}
#endif
namespace boost{
#ifdef __BORLANDC__
@ -359,7 +365,7 @@ void BuildFileList(std::list<std::string>* pl, const char* files, bool recurse)
while(dstart != dend)
{
std::sprintf(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr);
(std::sprintf)(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr);
BuildFileList(pl, buf, recurse);
++dstart;
}

View File

@ -21,12 +21,28 @@
#include <climits>
#include <stdexcept>
#include <string>
#include <boost/throw_exception.hpp>
#ifdef BOOST_REGEX_V3
#include <boost/regex/v3/fileiter.hpp>
#else
#include <boost/regex/v4/fileiter.hpp>
#endif
#include <cstdio>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::sprintf;
using ::fseek;
using ::fread;
using ::ftell;
using ::fopen;
using ::fclose;
using ::FILE;
}
#endif
#ifndef BOOST_REGEX_NO_FILEITER
#if defined(__CYGWIN__) || defined(__CYGWIN32__)
@ -787,9 +803,9 @@ unsigned _fi_attributes(const char* root, const char* name)
{
char buf[MAX_PATH];
if( ( (root[0] == *_fi_sep) || (root[0] == *_fi_sep_alt) ) && (root[1] == '\0') )
std::sprintf(buf, "%s%s", root, name);
(std::sprintf)(buf, "%s%s", root, name);
else
std::sprintf(buf, "%s%s%s", root, _fi_sep, name);
(std::sprintf)(buf, "%s%s%s", root, _fi_sep, name);
DIR* d = opendir(buf);
if(d)
{

View File

@ -19,8 +19,16 @@
#define BOOST_REGEX_SOURCE
#include <cstdio>
#include <boost/cregex.hpp>
#include <boost/regex.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::sprintf;
}
#endif
namespace boost{
namespace{
@ -135,13 +143,13 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorA(int code, const regex_tA*
{
if(std::strcmp(e->re_endp, names[i]) == 0)
{
std::sprintf(localbuf, "%d", i);
(std::sprintf)(localbuf, "%d", i);
if(std::strlen(localbuf) < buf_size)
std::strcpy(buf, localbuf);
return std::strlen(localbuf) + 1;
}
}
std::sprintf(localbuf, "%d", 0);
(std::sprintf)(localbuf, "%d", 0);
if(std::strlen(localbuf) < buf_size)
std::strcpy(buf, localbuf);
return std::strlen(localbuf) + 1;

View File

@ -26,6 +26,13 @@
#if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
# include <malloc.h>
#endif
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#define NOGDI
#define NOUSER
#include <windows.h>
#endif
#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
@ -72,6 +79,29 @@ BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex::flag_type /*
#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
static void execute_eror()
{
// we only get here after a stack overflow,
// this has to be a separate proceedure because we
// can't mix __try{}__except block with local objects
// that have destructors:
reset_stack_guard_page();
std::runtime_error err("Out of stack space, while attempting to match a regular expression.");
raise_runtime_error(err);
}
bool BOOST_REGEX_CALL abstract_protected_call::execute()const
{
__try{
return this->call();
}__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
{
execute_eror();
}
// We never really get here at all:
return false;
}
BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page()
{
#if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)

View File

@ -1,8 +1,18 @@
#define BOOST_REGEX_SOURCE
#include <memory>
#include <boost/assert.hpp>
#include <boost/regex/v4/regex_raw_buffer.hpp>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::memcpy;
using ::memmove;
}
#endif
namespace boost{ namespace re_detail{
void BOOST_REGEX_CALL raw_storage::resize(size_type n)

View File

@ -19,6 +19,23 @@
#define BOOST_REGEX_SOURCE
#include <boost/regex/regex_traits.hpp>
#include <cctype>
#ifndef BOOST_NO_WREGEX
#include <cwctype>
#endif
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
using ::tolower;
using ::toupper;
#ifndef BOOST_NO_WREGEX
using ::towlower;
using ::towupper;
#endif
}
#endif
namespace boost{ namespace re_detail{
BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_syntax(regex_constants::syntax_type n)
@ -113,7 +130,7 @@ BOOST_REGEX_DECL const char* BOOST_REGEX_CALL get_default_error_string(regex_con
"",
};
return (n > REG_E_UNKNOWN) ? s_default_error_messages[REG_E_UNKNOWN] : s_default_error_messages[n];
return (n > ::boost::regex_constants::error_unknown) ? s_default_error_messages[ ::boost::regex_constants::error_unknown] : s_default_error_messages[n];
}
BOOST_REGEX_DECL bool BOOST_REGEX_CALL is_combining_implementation(boost::uint_least16_t c)
@ -239,6 +256,26 @@ BOOST_REGEX_DECL std::string BOOST_REGEX_CALL lookup_default_collate_name(const
return std::string();
}
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_lower(char c)
{
return (std::tolower)(c);
}
BOOST_REGEX_DECL char BOOST_REGEX_CALL global_upper(char c)
{
return (std::toupper)(c);
}
#ifndef BOOST_NO_WREGEX
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_lower(wchar_t c)
{
return (std::towlower)(c);
}
BOOST_REGEX_DECL wchar_t BOOST_REGEX_CALL global_upper(wchar_t c)
{
return (std::towupper)(c);
}
#endif
} // re_detail
} // boost

View File

@ -22,12 +22,22 @@
#ifndef BOOST_NO_WREGEX
#include <boost/cregex.hpp>
#include <boost/regex.hpp>
#include <cwchar>
#include <cstring>
#include <cstdio>
#if defined(BOOST_NO_STDC_NAMESPACE)
namespace std{
# ifndef BOOST_NO_SWPRINTF
using ::swprintf;
# endif
}
#endif
namespace boost{
namespace {
@ -144,13 +154,13 @@ BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW*
{
if(std::wcscmp(e->re_endp, wnames[i]) == 0)
{
std::swprintf(localbuf, 5, L"%d", i);
(std::swprintf)(localbuf, 5, L"%d", i);
if(std::wcslen(localbuf) < buf_size)
std::wcscpy(buf, localbuf);
return std::wcslen(localbuf) + 1;
}
}
std::swprintf(localbuf, 5, L"%d", 0);
(std::swprintf)(localbuf, 5, L"%d", 0);
if(std::wcslen(localbuf) < buf_size)
std::wcscpy(buf, localbuf);
return std::wcslen(localbuf) + 1;

View File

@ -24,6 +24,7 @@ template regression
: <template>test # sources
regress/main.cpp
regress/basic_tests.cpp
regress/test_deprecated.cpp
<lib>../../test/build/boost_prg_exec_monitor
;
@ -57,6 +58,7 @@ template regression-dll
: <template>test-dll # sources
regress/main.cpp
regress/basic_tests.cpp
regress/test_deprecated.cpp
<lib>../../test/build/boost_prg_exec_monitor
;

View File

@ -481,9 +481,9 @@ void test_character_escapes()
TEST_REGEX_SEARCH("\\xFF", perl, "\xff", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\c@", perl, "\0", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\cA", perl, "\x1", match_default, make_array(0, 1, -2, -2));
TEST_REGEX_SEARCH("\\cz", perl, "\x3A", match_default, make_array(0, 1, -2, -2));
TEST_INVALID_REGEX("\\c=", extended);
TEST_INVALID_REGEX("\\c?", extended);
//TEST_REGEX_SEARCH("\\cz", perl, "\x3A", match_default, make_array(0, 1, -2, -2));
//TEST_INVALID_REGEX("\\c=", extended);
//TEST_INVALID_REGEX("\\c?", extended);
TEST_REGEX_SEARCH("=:", perl, "=:", match_default, make_array(0, 2, -2, -2));
TEST_REGEX_SEARCH("\\e", perl, "\x1B", match_default, make_array(0, 1, -2, -2));
@ -788,6 +788,8 @@ void test_tricky_cases2()
// bug in V4 code detected 2004/05/12:
TEST_REGEX_SEARCH("\\l+", perl|icase, "abcXYZ", match_default, make_array(0, 6, -2, -2));
TEST_REGEX_SEARCH("\\u+", perl|icase, "abcXYZ", match_default, make_array(0, 6, -2, -2));
TEST_REGEX_SEARCH("(a)(?:b)", perl|nosubs, "ab", match_default, make_array(0, 2, -2, -2));
//
// the strings in the next test case are too long for most compilers to cope with,
@ -892,7 +894,7 @@ void test_replace()
TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$15", "");
TEST_REGEX_REPLACE("(a+)b+", perl, "...aaabbb,,,", match_default|format_no_copy, "$1", "aaa");
TEST_REGEX_REPLACE("[[:digit:]]*", perl, "123ab", match_default|format_no_copy, "<$0>", "<123><><><>");
TEST_REGEX_REPLACE("[[:digit:]]*", perl, "123ab1", match_default|format_no_copy, "<$0>", "<123><><><1>");
TEST_REGEX_REPLACE("[[:digit:]]*", perl, "123ab1", match_default|format_no_copy, "<$0>", "<123><><><1><>");
// and now escapes:
TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "$x", "$x");
TEST_REGEX_REPLACE("a+", perl, "...aaa,,,", match_default|format_no_copy, "\\a", "\a");
@ -938,6 +940,9 @@ void test_replace()
TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,", match_default|format_all|format_first_only, "$1", "...bb,,,");
TEST_REGEX_REPLACE("a+(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all|format_first_only, "$1", "...bb,,,ab*abbb?");
TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all|format_first_only, "(?1A)(?2B)", "...Abb,,,ab*abbb?");
TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?1A", "...A,,,A*A?");
TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "?1:B", "...B,,,B*B?");
TEST_REGEX_REPLACE("(a+)|(b+)", perl, "...aaabb,,,ab*abbb?", match_default|format_all, "(?1A:(?2B))", "...AB,,,AB*AB?");
}
void test_non_greedy_repeats()
@ -1473,13 +1478,13 @@ void test_options()
TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "more than MILLION", match_default, make_array(0, 17, -2, -2));
TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "more \n than Million", match_default, make_array(0, 19, -2, -2));
TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "MORE THAN MILLION", match_default, make_array(-2, -2));
//TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase, "more \n than \n million", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?s-i:more.*than).*million", perl|icase|no_mod_s|no_mod_m, "more \n than \n million", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "more than million", match_default, make_array(0, 17, -2, -2));
TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "more than MILLION", match_default, make_array(0, 17, -2, -2));
TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "more \n than Million", match_default, make_array(0, 19, -2, -2));
TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "MORE THAN MILLION", match_default, make_array(-2, -2));
//TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase, "more \n than \n million", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?:(?s-i)more.*than).*million", perl|icase|no_mod_s|no_mod_m, "more \n than \n million", match_default, make_array(-2, -2));
TEST_REGEX_SEARCH("(?>a(?i)b+)+c", perl, "abc", match_default, make_array(0, 3, -2, -2));
TEST_REGEX_SEARCH("(?>a(?i)b+)+c", perl, "aBbc", match_default, make_array(0, 4, -2, -2));

View File

@ -1,5 +1,6 @@
#include "test.hpp"
#include <boost/cregex.hpp>
int get_posix_compile_options(boost::regex_constants::syntax_option_type opts)
{
@ -165,6 +166,7 @@ void test_deprecated(const char&, const test_regex_search_tag&)
void test_deprecated(const wchar_t&, const test_regex_search_tag&)
{
#ifndef BOOST_NO_WREGEX
const std::wstring& expression = test_info<wchar_t>::expression();
if(expression.find(L'\0') != std::wstring::npos)
return;
@ -213,6 +215,7 @@ void test_deprecated(const wchar_t&, const test_regex_search_tag&)
}
// clean up whatever:
boost::regfreeW(&re);
#endif
}
void test_deprecated(const char&, const test_invalid_regex_tag&)
@ -268,6 +271,7 @@ void test_deprecated(const char&, const test_invalid_regex_tag&)
void test_deprecated(const wchar_t&, const test_invalid_regex_tag&)
{
#ifndef BOOST_NO_WREGEX
const std::wstring& expression = test_info<wchar_t>::expression();
if(expression.find(L'\0') != std::string::npos)
return;
@ -282,4 +286,5 @@ void test_deprecated(const wchar_t&, const test_invalid_regex_tag&)
boost::regfreeW(&re);
BOOST_REGEX_TEST_ERROR("Expression : \"" << expression.c_str() << "\" unexpectedly compiled with the POSIX C API.", wchar_t);
}
#endif
}