/* * * Copyright (c) 1998-2004 * 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.cpp * VERSION: see <boost/version.hpp> * DESCRIPTION: Misc boost::regbase member funnctions. */ #define BOOST_REGEX_SOURCE #include <new> #include <boost/regex.hpp> #include <boost/throw_exception.hpp> #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 #ifndef NOMINMAX # define NOMINMAX #endif #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 #include <new> #else #include <boost/regex/v4/mem_block_cache.hpp> #endif #endif namespace boost{ // // fix: these are declared out of line here to ensure // that dll builds contain the Virtual table for these // types - this ensures that exceptions can be thrown // from the dll and caught in an exe. regex_error::regex_error(const std::string& s, regex_constants::error_type err, std::ptrdiff_t pos) : std::runtime_error(s) , m_error_code(err) , m_position(pos) { } regex_error::regex_error(regex_constants::error_type err) : std::runtime_error(::boost::re_detail::get_default_error_string(err)) , m_error_code(err) , m_position(0) { } regex_error::~regex_error() throw() { } void regex_error::raise()const { #ifndef BOOST_NO_EXCEPTIONS ::boost::throw_exception(*this); #endif } namespace re_detail{ BOOST_REGEX_DECL void BOOST_REGEX_CALL raise_runtime_error(const std::runtime_error& ex) { ::boost::throw_exception(ex); } // // error checking API: // BOOST_REGEX_DECL void BOOST_REGEX_CALL verify_options(boost::regex::flag_type /*ef*/, match_flag_type mf) { #ifndef BOOST_REGEX_V3 // // can't mix match_extra with POSIX matching rules: // if((mf & match_extra) && (mf & match_posix)) { std::logic_error msg("Usage Error: Can't mix regular expression captures with POSIX matching rules"); throw_exception(msg); } #endif } #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) _resetstkoflw(); #else // // We need to locate the current page being used by the stack, // move to the page below it and then deallocate and protect // that page. Note that ideally we would protect only the lowest // stack page that has been allocated: in practice there // seems to be no easy way to locate this page, in any case as // long as the next page is protected, then Windows will figure // the rest out for us... // SYSTEM_INFO si; GetSystemInfo(&si); MEMORY_BASIC_INFORMATION mi; DWORD previous_protection_status; // // this is an address in our stack space: // LPBYTE page = (LPBYTE)&page; // // Get the current memory page in use: // VirtualQuery(page, &mi, sizeof(mi)); // // Go to the page one below this: // page = (LPBYTE)(mi.BaseAddress)-si.dwPageSize; // // Free and protect everything from the start of the // allocation range, to the end of the page below the // one in use: // if (!VirtualFree(mi.AllocationBase, (LPBYTE)page - (LPBYTE)mi.AllocationBase, MEM_DECOMMIT) || !VirtualProtect(page, si.dwPageSize, PAGE_GUARD | PAGE_READWRITE, &previous_protection_status)) { throw std::bad_exception(); } #endif } #endif #if defined(BOOST_REGEX_NON_RECURSIVE) && !defined(BOOST_REGEX_V3) #if BOOST_REGEX_MAX_CACHE_BLOCKS == 0 BOOST_REGEX_DECL void* BOOST_REGEX_CALL get_mem_block() { return ::operator new(BOOST_REGEX_BLOCKSIZE); } BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p) { ::operator delete(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() { return block_cache.get(); } BOOST_REGEX_DECL void BOOST_REGEX_CALL put_mem_block(void* p) { block_cache.put(p); } #endif #endif } // namespace re_detail } // namespace boost #if defined(BOOST_RE_USE_VCL) && defined(BOOST_REGEX_DYN_LINK) int WINAPI DllEntryPoint(HINSTANCE , unsigned long , void*) { return 1; } #endif #if defined(__IBMCPP__) && defined(BOOST_REGEX_DYN_LINK) // // Is this correct - linker complains without it ? // int main() { return 0; } #endif