diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-06-25 22:59:01 +0000 |
---|---|---|
committer | <> | 2013-09-27 11:49:28 +0000 |
commit | 8c4528713d907ee2cfd3bfcbbad272c749867f84 (patch) | |
tree | c09e2ce80f47b90c85cc720f5139089ad9c8cfff /libs/python/src/errors.cpp | |
download | boost-tarball-baserock/morph.tar.gz |
Imported from /home/lorry/working-area/delta_boost-tarball/boost_1_54_0.tar.bz2.boost_1_54_0baserock/morph
Diffstat (limited to 'libs/python/src/errors.cpp')
-rw-r--r-- | libs/python/src/errors.cpp | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/libs/python/src/errors.cpp b/libs/python/src/errors.cpp new file mode 100644 index 000000000..34ea22f43 --- /dev/null +++ b/libs/python/src/errors.cpp @@ -0,0 +1,105 @@ +// Copyright David Abrahams 2001. +// Distributed under 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) + +#ifndef BOOST_PYTHON_SOURCE +# define BOOST_PYTHON_SOURCE +#endif + +#include <boost/python/errors.hpp> +#include <boost/cast.hpp> +#include <boost/python/detail/exception_handler.hpp> + +namespace boost { namespace python { + +error_already_set::~error_already_set() {} + +// IMPORTANT: this function may only be called from within a catch block! +BOOST_PYTHON_DECL bool handle_exception_impl(function0<void> f) +{ + try + { + if (detail::exception_handler::chain) + return detail::exception_handler::chain->handle(f); + f(); + return false; + } + catch(const boost::python::error_already_set&) + { + // The python error reporting has already been handled. + } + catch(const std::bad_alloc&) + { + PyErr_NoMemory(); + } + catch(const bad_numeric_cast& x) + { + PyErr_SetString(PyExc_OverflowError, x.what()); + } + catch(const std::out_of_range& x) + { + PyErr_SetString(PyExc_IndexError, x.what()); + } + catch(const std::invalid_argument& x) + { + PyErr_SetString(PyExc_ValueError, x.what()); + } + catch(const std::exception& x) + { + PyErr_SetString(PyExc_RuntimeError, x.what()); + } + catch(...) + { + PyErr_SetString(PyExc_RuntimeError, "unidentifiable C++ exception"); + } + return true; +} + +void BOOST_PYTHON_DECL throw_error_already_set() +{ + throw error_already_set(); +} + +namespace detail { + +bool exception_handler::operator()(function0<void> const& f) const +{ + if (m_next) + { + return m_next->handle(f); + } + else + { + f(); + return false; + } +} + +exception_handler::exception_handler(handler_function const& impl) + : m_impl(impl) + , m_next(0) +{ + if (chain != 0) + tail->m_next = this; + else + chain = this; + tail = this; +} + +exception_handler* exception_handler::chain; +exception_handler* exception_handler::tail; + +BOOST_PYTHON_DECL void register_exception_handler(handler_function const& f) +{ + // the constructor links the new object into a handler chain, so + // this object isn't actaully leaked (until, of course, the + // interpreter exits). + new exception_handler(f); +} + +} // namespace boost::python::detail + +}} // namespace boost::python + + |