3 * Copyright (c) 1998-2004
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
13 * LOCATION: see http://www.boost.org for most recent version.
15 * VERSION: see <boost/version.hpp>
16 * DESCRIPTION: Misc boost::regbase member funnctions.
20 #define BOOST_REGEX_SOURCE
22 #include <boost/config.hpp>
24 #include <boost/regex.hpp>
25 #include <boost/throw_exception.hpp>
27 #if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
30 #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
31 #ifndef WIN32_LEAN_AND_MEAN
32 # define WIN32_LEAN_AND_MEAN
42 #if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
43 #if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
46 #include <boost/regex/v4/mem_block_cache.hpp>
51 #pragma warning(disable:383)
57 // fix: these are declared out of line here to ensure
58 // that dll builds contain the Virtual table for these
59 // types - this ensures that exceptions can be thrown
60 // from the dll and caught in an exe.
61 regex_error::regex_error(const std::string
& s
, regex_constants::error_type err
, std::ptrdiff_t pos
)
62 : std::runtime_error(s
)
68 regex_error::regex_error(regex_constants::error_type err
)
69 : std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err
))
75 regex_error::~regex_error() throw()
79 void regex_error::raise()const
81 #ifndef BOOST_NO_EXCEPTIONS
82 ::boost::throw_exception(*this);
88 namespace BOOST_REGEX_DETAIL_NS
{
90 BOOST_REGEX_DECL
void BOOST_REGEX_CALL
raise_runtime_error(const std::runtime_error
& ex
)
92 ::boost::throw_exception(ex
);
95 // error checking API:
97 BOOST_REGEX_DECL
void BOOST_REGEX_CALL
verify_options(boost::regex::flag_type
/*ef*/, match_flag_type mf
)
99 #ifndef BOOST_REGEX_V3
101 // can't mix match_extra with POSIX matching rules:
103 if((mf
& match_extra
) && (mf
& match_posix
))
105 std::logic_error
msg("Usage Error: Can't mix regular expression captures with POSIX matching rules");
106 throw_exception(msg
);
111 #ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
113 static void execute_eror()
115 // we only get here after a stack overflow,
116 // this has to be a separate proceedure because we
117 // can't mix __try{}__except block with local objects
118 // that have destructors:
119 reset_stack_guard_page();
120 std::runtime_error
err("Out of stack space, while attempting to match a regular expression.");
121 raise_runtime_error(err
);
124 bool BOOST_REGEX_CALL
abstract_protected_call::execute()const
128 }__except(EXCEPTION_STACK_OVERFLOW
== GetExceptionCode())
132 // We never really get here at all:
136 BOOST_REGEX_DECL
void BOOST_REGEX_CALL
reset_stack_guard_page()
138 #if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
142 // We need to locate the current page being used by the stack,
143 // move to the page below it and then deallocate and protect
144 // that page. Note that ideally we would protect only the lowest
145 // stack page that has been allocated: in practice there
146 // seems to be no easy way to locate this page, in any case as
147 // long as the next page is protected, then Windows will figure
148 // the rest out for us...
152 MEMORY_BASIC_INFORMATION mi
;
153 DWORD previous_protection_status
;
155 // this is an address in our stack space:
157 LPBYTE page
= (LPBYTE
)&page
;
159 // Get the current memory page in use:
161 VirtualQuery(page
, &mi
, sizeof(mi
));
163 // Go to the page one below this:
165 page
= (LPBYTE
)(mi
.BaseAddress
)-si
.dwPageSize
;
167 // Free and protect everything from the start of the
168 // allocation range, to the end of the page below the
171 if (!VirtualFree(mi
.AllocationBase
, (LPBYTE
)page
- (LPBYTE
)mi
.AllocationBase
, MEM_DECOMMIT
)
172 || !VirtualProtect(page
, si
.dwPageSize
, PAGE_GUARD
| PAGE_READWRITE
, &previous_protection_status
))
174 throw std::bad_exception();
180 #if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
182 #if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
184 BOOST_REGEX_DECL
void* BOOST_REGEX_CALL
get_mem_block()
186 return ::operator new(BOOST_REGEX_BLOCKSIZE
);
189 BOOST_REGEX_DECL
void BOOST_REGEX_CALL
put_mem_block(void* p
)
191 ::operator delete(p
);
196 #if defined(BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE)
197 mem_block_cache block_cache
= { { {nullptr} } } ;
198 #elif defined(BOOST_HAS_THREADS)
199 mem_block_cache block_cache
= { 0, 0, BOOST_STATIC_MUTEX_INIT
, };
201 mem_block_cache block_cache
= { 0, 0, };
204 BOOST_REGEX_DECL
void* BOOST_REGEX_CALL
get_mem_block()
206 return block_cache
.get();
209 BOOST_REGEX_DECL
void BOOST_REGEX_CALL
put_mem_block(void* p
)
218 } // namespace BOOST_REGEX_DETAIL_NS
224 #if defined(BOOST_RE_USE_VCL) && defined(BOOST_REGEX_DYN_LINK)
226 int WINAPI
DllEntryPoint(HINSTANCE
, unsigned long , void*)