| /* |
| * |
| * 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 |
| |
| #ifdef BOOST_INTEL |
| #pragma warning(disable:383) |
| #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 |
| |
| |
| |
| |
| |
| |