1/*
2 *
3 * Copyright (c) 1998-2004
4 * John Maddock
5 *
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)
9 *
10 */
11
12 /*
13 * LOCATION: see http://www.boost.org for most recent version.
14 * FILE: regex.cpp
15 * VERSION: see <boost/version.hpp>
16 * DESCRIPTION: Misc boost::regbase member funnctions.
17 */
18
19
20#define BOOST_REGEX_SOURCE
21
22#include <boost/config.hpp>
23#include <new>
24#include <boost/regex.hpp>
25#include <boost/throw_exception.hpp>
26
27#if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
28# include <malloc.h>
29#endif
30#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
31#ifndef WIN32_LEAN_AND_MEAN
32# define WIN32_LEAN_AND_MEAN
33#endif
34#ifndef NOMINMAX
35# define NOMINMAX
36#endif
37#define NOGDI
38#define NOUSER
39#include <windows.h>
40#endif
41
42#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
43#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
44#include <new>
45#else
46#include <boost/regex/v4/mem_block_cache.hpp>
47#endif
48#endif
49
50#ifdef BOOST_INTEL
51#pragma warning(disable:383)
52#endif
53
54namespace boost{
55
56//
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.
61regex_error::regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos)
62 : std::runtime_error(s)
63 , m_error_code(err)
64 , m_position(pos)
65{
66}
67
68regex_error::regex_error(regex_constants::error_type err)
69 : std::runtime_error(::boost::BOOST_REGEX_DETAIL_NS::get_default_error_string(err))
70 , m_error_code(err)
71 , m_position(0)
72{
73}
74
75regex_error::~regex_error() throw()
76{
77}
78
79void regex_error::raise()const
80{
81#ifndef BOOST_NO_EXCEPTIONS
82 ::boost::throw_exception(*this);
83#endif
84}
85
86
87
88namespace BOOST_REGEX_DETAIL_NS{
89
90BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex)
91{
92 ::boost::throw_exception(ex);
93}
94//
95// error checking API:
96//
97BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex::flag_type /*ef*/, match_flag_type mf)
98{
99#ifndef BOOST_REGEX_V3
100 //
101 // can't mix match_extra with POSIX matching rules:
102 //
103 if((mf & match_extra) && (mf & match_posix))
104 {
105 std::logic_error msg("Usage Error: Can't mix regular expression captures with POSIX matching rules");
106 throw_exception(msg);
107 }
108#endif
109}
110
111#ifdef BOOST_REGEX_HAS_MS_STACK_GUARD
112
113static void execute_eror()
114{
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);
122}
123
124bool BOOST_REGEX_CALL abstract_protected_call::execute()const
125{
126 __try{
127 return this->call();
128 }__except(EXCEPTION_STACK_OVERFLOW == GetExceptionCode())
129 {
130 execute_eror();
131 }
132 // We never really get here at all:
133 return false;
134}
135
136BOOST_REGEX_DECL void BOOST_REGEX_CALL reset_stack_guard_page()
137{
138#if defined(BOOST_REGEX_HAS_MS_STACK_GUARD) && defined(_MSC_VER) && (_MSC_VER >= 1300)
139 _resetstkoflw();
140#else
141 //
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...
149 //
150 SYSTEM_INFO si;
151 GetSystemInfo(&si);
152 MEMORY_BASIC_INFORMATION mi;
153 DWORD previous_protection_status;
154 //
155 // this is an address in our stack space:
156 //
157 LPBYTE page = (LPBYTE)&page;
158 //
159 // Get the current memory page in use:
160 //
161 VirtualQuery(page, &mi, sizeof(mi));
162 //
163 // Go to the page one below this:
164 //
165 page = (LPBYTE)(mi.BaseAddress)-si.dwPageSize;
166 //
167 // Free and protect everything from the start of the
168 // allocation range, to the end of the page below the
169 // one in use:
170 //
171 if (!VirtualFree(mi.AllocationBase, (LPBYTE)page - (LPBYTE)mi.AllocationBase, MEM_DECOMMIT)
172 || !VirtualProtect(page, si.dwPageSize, PAGE_GUARD | PAGE_READWRITE, &previous_protection_status))
173 {
174 throw std::bad_exception();
175 }
176#endif
177}
178#endif
179
180#if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3)
181
182#if BOOST_REGEX_MAX_CACHE_BLOCKS == 0
183
184BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block()
185{
186 return ::operator new(BOOST_REGEX_BLOCKSIZE);
187}
188
189BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p)
190{
191 ::operator delete(p);
192}
193
194#else
195
196#if defined(BOOST_REGEX_MEM_BLOCK_CACHE_LOCK_FREE)
197mem_block_cache block_cache = { { {nullptr} } } ;
198#elif defined(BOOST_HAS_THREADS)
199mem_block_cache block_cache = { 0, 0, BOOST_STATIC_MUTEX_INIT, };
200#else
201mem_block_cache block_cache = { 0, 0, };
202#endif
203
204BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block()
205{
206 return block_cache.get();
207}
208
209BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p)
210{
211 block_cache.put(p);
212}
213
214#endif
215
216#endif
217
218} // namespace BOOST_REGEX_DETAIL_NS
219
220
221
222} // namespace boost
223
224#if defined(BOOST_RE_USE_VCL) && defined(BOOST_REGEX_DYN_LINK)
225
226int WINAPI DllEntryPoint(HINSTANCE , unsigned long , void*)
227{
228 return 1;
229}
230#endif
231
232