diff options
Diffstat (limited to 'src/python')
-rw-r--r-- | src/python/py_amount.cc | 320 | ||||
-rw-r--r-- | src/python/py_commodity.cc | 63 | ||||
-rw-r--r-- | src/python/py_times.cc | 132 | ||||
-rw-r--r-- | src/python/py_utils.cc | 172 | ||||
-rw-r--r-- | src/python/pyfstream.h | 169 | ||||
-rw-r--r-- | src/python/pyinterp.cc | 238 | ||||
-rw-r--r-- | src/python/pyinterp.h | 98 | ||||
-rw-r--r-- | src/python/pyledger.cc | 46 | ||||
-rw-r--r-- | src/python/pyledger.h | 47 | ||||
-rw-r--r-- | src/python/pyutils.h | 112 | ||||
-rw-r--r-- | src/python/tuples.hpp | 281 |
11 files changed, 0 insertions, 1678 deletions
diff --git a/src/python/py_amount.cc b/src/python/py_amount.cc deleted file mode 100644 index 07be1512..00000000 --- a/src/python/py_amount.cc +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pyinterp.h" -#include "pyutils.h" -#include "amount.h" - -#include <boost/python/exception_translator.hpp> -#include <boost/python/implicit.hpp> -#include <boost/python/args.hpp> - -namespace ledger { - -using namespace boost::python; - -amount_t py_round_0(const amount_t& amount) { - return amount.round(); -} -amount_t py_round_1(const amount_t& amount, amount_t::precision_t prec) { - return amount.round(prec); -} - -double py_to_double_0(amount_t& amount) { - return amount.to_double(); -} -double py_to_double_1(amount_t& amount, bool no_check) { - return amount.to_double(no_check); -} - -long py_to_long_0(amount_t& amount) { - return amount.to_long(); -} -long py_to_long_1(amount_t& amount, bool no_check) { - return amount.to_long(no_check); -} - -boost::optional<amount_t> py_value_0(const amount_t& amount) { - return amount.value(); -} -boost::optional<amount_t> py_value_1(const amount_t& amount, - const boost::optional<moment_t>& moment) { - return amount.value(moment); -} - -void py_parse_2(amount_t& amount, object in, unsigned char flags) { - if (PyFile_Check(in.ptr())) { - pyifstream instr(reinterpret_cast<PyFileObject *>(in.ptr())); - amount.parse(instr, flags); - } else { - PyErr_SetString(PyExc_IOError, - "Argument to amount.parse(file) is not a file object"); - } -} -void py_parse_1(amount_t& amount, object in) { - py_parse_2(amount, in, 0); -} - -void py_parse_str_1(amount_t& amount, const string& str) { - amount.parse(str); -} -void py_parse_str_2(amount_t& amount, const string& str, unsigned char flags) { - amount.parse(str, flags); -} - -void py_read_1(amount_t& amount, object in) { - if (PyFile_Check(in.ptr())) { - pyifstream instr(reinterpret_cast<PyFileObject *>(in.ptr())); - amount.read(instr); - } else { - PyErr_SetString(PyExc_IOError, - "Argument to amount.parse(file) is not a file object"); - } -} -void py_read_2(amount_t& amount, const std::string& str) { - const char * p = str.c_str(); - amount.read(p); -} - -#define EXC_TRANSLATOR(type) \ - void exc_translate_ ## type(const type& err) { \ - PyErr_SetString(PyExc_ArithmeticError, err.what()); \ - } - -EXC_TRANSLATOR(amount_error) - -void export_amount() -{ - scope().attr("AMOUNT_PARSE_NO_MIGRATE") = AMOUNT_PARSE_NO_MIGRATE; - scope().attr("AMOUNT_PARSE_NO_REDUCE") = AMOUNT_PARSE_NO_REDUCE; - - class_< amount_t > ("amount") -#if 0 - .def("initialize", &amount_t::initialize) - .staticmethod("initialize") - .def("shutdown", &amount_t::shutdown) - .staticmethod("shutdown") -#endif - - .add_static_property("current_pool", - make_getter(&amount_t::current_pool, - return_value_policy<reference_existing_object>())) - - .add_static_property("keep_base", &amount_t::keep_base) - - .add_static_property("keep_price", &amount_t::keep_price) - .add_static_property("keep_date", &amount_t::keep_date) - .add_static_property("keep_tag", &amount_t::keep_tag) - - .add_static_property("stream_fullstrings", &amount_t::stream_fullstrings) - - .def(init<double>()) - .def(init<long>()) - .def(init<std::string>()) - - .def("exact", &amount_t::exact, args("value"), - "Construct an amount object whose display precision is always equal to its\n\ -internal precision.") - .staticmethod("exact") - - .def(init<amount_t>()) - - .def("compare", &amount_t::compare) - - .def(self == self) - .def(self == long()) - .def(long() == self) - .def(self == double()) - .def(double() == self) - - .def(self != self) - .def(self != long()) - .def(long() != self) - .def(self != double()) - .def(double() != self) - - .def(! self) - - .def(self < self) - .def(self < long()) - .def(long() < self) - .def(self < double()) - .def(double() < self) - - .def(self <= self) - .def(self <= long()) - .def(long() <= self) - .def(self <= double()) - .def(double() <= self) - - .def(self > self) - .def(self > long()) - .def(long() > self) - .def(self > double()) - .def(double() > self) - - .def(self >= self) - .def(self >= long()) - .def(long() >= self) - .def(self >= double()) - .def(double() >= self) - - .def(self += self) - .def(self += long()) - .def(self += double()) - - .def(self + self) - .def(self + long()) - .def(long() + self) - .def(self + double()) - .def(double() + self) - - .def(self -= self) - .def(self -= long()) - .def(self -= double()) - - .def(self - self) - .def(self - long()) - .def(long() - self) - .def(self - double()) - .def(double() - self) - - .def(self *= self) - .def(self *= long()) - .def(self *= double()) - - .def(self * self) - .def(self * long()) - .def(long() * self) - .def(self * double()) - .def(double() * self) - - .def(self /= self) - .def(self /= long()) - .def(self /= double()) - - .def(self / self) - .def(self / long()) - .def(long() / self) - .def(self / double()) - .def(double() / self) - - .add_property("precision", &amount_t::precision) - - .def("negate", &amount_t::negate) - .def("in_place_negate", &amount_t::in_place_negate, - return_value_policy<reference_existing_object>()) - .def(- self) - - .def("abs", &amount_t::abs) - .def("__abs__", &amount_t::abs) - - .def("round", py_round_0) - .def("round", py_round_1) - .def("unround", &amount_t::unround) - - .def("reduce", &amount_t::reduce) - .def("in_place_reduce", &amount_t::in_place_reduce, - return_value_policy<reference_existing_object>()) - - .def("unreduce", &amount_t::unreduce) - .def("in_place_unreduce", &amount_t::in_place_unreduce, - return_value_policy<reference_existing_object>()) - - .def("value", py_value_0) - .def("value", py_value_1) - - .def("sign", &amount_t::sign) - .def("__nonzero__", &amount_t::is_nonzero) - .def("is_nonzero", &amount_t::is_nonzero) - .def("is_zero", &amount_t::is_zero) - .def("is_realzero", &amount_t::is_realzero) - .def("is_null", &amount_t::is_null) - - .def("to_double", py_to_double_0) - .def("to_double", py_to_double_1) - .def("__float__", py_to_double_0) - .def("to_long", py_to_long_0) - .def("to_long", py_to_long_1) - .def("__int__", py_to_long_0) - .def("to_string", &amount_t::to_string) - .def("__str__", &amount_t::to_string) - .def("to_fullstring", &amount_t::to_fullstring) - .def("__repr__", &amount_t::to_fullstring) - - .def("fits_in_double", &amount_t::fits_in_double) - .def("fits_in_long", &amount_t::fits_in_long) - - .add_property("quantity_string", &amount_t::quantity_string) - - .add_property("commodity", - make_function(&amount_t::commodity, - return_value_policy<reference_existing_object>()), - make_function(&amount_t::set_commodity, - with_custodian_and_ward<1, 2>())) - - .def("has_commodity", &amount_t::has_commodity) - .def("clear_commodity", &amount_t::clear_commodity) - .add_property("number", &amount_t::number) - - .def("annotate_commodity", &amount_t::annotate_commodity) - .def("commodity_annotated", &amount_t::commodity_annotated) - .add_property("annotation_details", &amount_t::annotation_details) - .def("strip_annotations", &amount_t::strip_annotations) - - .def("parse", py_parse_1) - .def("parse", py_parse_2) - .def("parse", py_parse_str_1) - .def("parse", py_parse_str_2) - - .def("parse_conversion", &amount_t::parse_conversion) - .staticmethod("parse_conversion") - - .def("read", py_read_1) - .def("read", py_read_2) - .def("write", &amount_t::write) - - .def("valid", &amount_t::valid) - ; - - register_optional_to_python<amount_t>(); - - implicitly_convertible<double, amount_t>(); - implicitly_convertible<long, amount_t>(); - implicitly_convertible<string, amount_t>(); - -#define EXC_TRANSLATE(type) \ - register_exception_translator<type>(&exc_translate_ ## type); - - EXC_TRANSLATE(amount_error); -} - -} // namespace ledger diff --git a/src/python/py_commodity.cc b/src/python/py_commodity.cc deleted file mode 100644 index 0dab3cd3..00000000 --- a/src/python/py_commodity.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pyinterp.h" -#include "pyutils.h" -#include "amount.h" - -#include <boost/python/exception_translator.hpp> -#include <boost/python/implicit.hpp> - -namespace ledger { - -using namespace boost::python; - -void export_commodity() -{ - scope().attr("COMMODITY_STYLE_DEFAULTS") = COMMODITY_STYLE_DEFAULTS; - scope().attr("COMMODITY_STYLE_SUFFIXED") = COMMODITY_STYLE_SUFFIXED; - scope().attr("COMMODITY_STYLE_SEPARATED") = COMMODITY_STYLE_SEPARATED; - scope().attr("COMMODITY_STYLE_EUROPEAN") = COMMODITY_STYLE_EUROPEAN; - scope().attr("COMMODITY_STYLE_THOUSANDS") = COMMODITY_STYLE_THOUSANDS; - scope().attr("COMMODITY_STYLE_NOMARKET") = COMMODITY_STYLE_NOMARKET; - scope().attr("COMMODITY_STYLE_BUILTIN") = COMMODITY_STYLE_BUILTIN; - - class_< commodity_t, bases<>, - commodity_t, boost::noncopyable > ("commodity", no_init) - .def(self == self) - - .def("drop_flags", &commodity_t::drop_flags) - - .add_property("precision", &commodity_t::precision) - ; -} - -} // namespace ledger diff --git a/src/python/py_times.cc b/src/python/py_times.cc deleted file mode 100644 index 173f21fa..00000000 --- a/src/python/py_times.cc +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pyinterp.h" -#include "pyutils.h" - -#include <boost/cast.hpp> -#include <boost/python/module.hpp> -#include <boost/python/def.hpp> -#include <boost/python/to_python_converter.hpp> - -#include <Python.h> -#include <datetime.h> - -// jww (2007-05-04): Convert time duration objects to PyDelta - -namespace ledger { - -using namespace boost::python; - -typedef boost::gregorian::date date; - -struct date_to_python -{ - static PyObject* convert(const date& dte) - { - PyDateTime_IMPORT; - return PyDate_FromDate(dte.year(), dte.month(), dte.day()); - } -}; - -struct date_from_python -{ - static void* convertible(PyObject* obj_ptr) - { - PyDateTime_IMPORT; - if (PyDate_Check(obj_ptr)) return obj_ptr; - return 0; - } - - static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data) - { - PyDateTime_IMPORT; - int y = PyDateTime_GET_YEAR(obj_ptr); - int m = PyDateTime_GET_MONTH(obj_ptr); - int d = PyDateTime_GET_DAY(obj_ptr); - date* dte = new date(y,m,d); - data->convertible = (void*)dte; - } -}; - -typedef register_python_conversion<date, date_to_python, date_from_python> - date_python_conversion; - - -struct datetime_to_python -{ - static PyObject* convert(const moment_t& moment) - { - PyDateTime_IMPORT; - date dte = moment.date(); - moment_t::time_duration_type tod = moment.time_of_day(); - return PyDateTime_FromDateAndTime(dte.year(), dte.month(), dte.day(), - tod.hours(), tod.minutes(), tod.seconds(), - tod.total_microseconds() % 1000000); - } -}; - -struct datetime_from_python -{ - static void* convertible(PyObject* obj_ptr) - { - PyDateTime_IMPORT; - if(PyDateTime_Check(obj_ptr)) return obj_ptr; - return 0; - } - - static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data) - { - PyDateTime_IMPORT; - int y = PyDateTime_GET_YEAR(obj_ptr); - int m = PyDateTime_GET_MONTH(obj_ptr); - int d = PyDateTime_GET_DAY(obj_ptr); - int h = PyDateTime_DATE_GET_HOUR(obj_ptr); - int min = PyDateTime_DATE_GET_MINUTE(obj_ptr); - int s = PyDateTime_DATE_GET_SECOND(obj_ptr); - moment_t* moment = new moment_t(date(y,m,d), - moment_t::time_duration_type(h, min, s)); - data->convertible = (void*)moment; - } -}; - -typedef register_python_conversion<moment_t, datetime_to_python, datetime_from_python> - datetime_python_conversion; - -void export_times() -{ - date_python_conversion(); - datetime_python_conversion(); - - register_optional_to_python<moment_t>(); -} - -} // namespace ledger diff --git a/src/python/py_utils.cc b/src/python/py_utils.cc deleted file mode 100644 index 50ce9712..00000000 --- a/src/python/py_utils.cc +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pyinterp.h" -#include "pyutils.h" - -#include <boost/python/module.hpp> -#include <boost/python/def.hpp> -#include <boost/python/to_python_converter.hpp> - -namespace ledger { - -using namespace boost::python; - -struct bool_to_python -{ - static PyObject * convert(const bool truth) - { - if (truth) - Py_RETURN_TRUE; - else - Py_RETURN_FALSE; - } -}; - -struct bool_from_python -{ - static void* convertible(PyObject* obj_ptr) - { - if (!PyBool_Check(obj_ptr)) return 0; - return obj_ptr; - } - - static void construct(PyObject* obj_ptr, - converter::rvalue_from_python_stage1_data* data) - { - void* storage = ((converter::rvalue_from_python_storage<bool>*) data)->storage.bytes; - if (obj_ptr == Py_True) - new (storage) bool(true); - else - new (storage) bool(false); - data->convertible = storage; - } -}; - -typedef register_python_conversion<bool, bool_to_python, bool_from_python> - bool_python_conversion; - - -struct string_to_python -{ - static PyObject* convert(const string& str) - { - return incref(object(*boost::polymorphic_downcast<const std::string *>(&str)).ptr()); - } -}; - -struct string_from_python -{ - static void* convertible(PyObject* obj_ptr) - { - if (!PyString_Check(obj_ptr)) return 0; - return obj_ptr; - } - - static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data) - { - const char* value = PyString_AsString(obj_ptr); - if (value == 0) throw_error_already_set(); - void* storage = ((converter::rvalue_from_python_storage<string>*) data)->storage.bytes; - new (storage) string(value); - data->convertible = storage; - } -}; - -typedef register_python_conversion<string, string_to_python, string_from_python> - string_python_conversion; - - -struct istream_to_python -{ - static PyObject* convert(const std::istream& str) - { - return incref(boost::python::detail::none()); - } -}; - -struct istream_from_python -{ - static void* convertible(PyObject* obj_ptr) - { - if (!PyFile_Check(obj_ptr)) return 0; - return obj_ptr; - } - - static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data) - { - void* storage = ((converter::rvalue_from_python_storage<pyifstream>*) data)->storage.bytes; - new (storage) pyifstream(reinterpret_cast<PyFileObject *>(obj_ptr)); - data->convertible = storage; - } -}; - -typedef register_python_conversion<std::istream, istream_to_python, istream_from_python> - istream_python_conversion; - - -struct ostream_to_python -{ - static PyObject* convert(const std::ostream& str) - { - return incref(boost::python::detail::none()); - } -}; - -struct ostream_from_python -{ - static void* convertible(PyObject* obj_ptr) - { - if (!PyFile_Check(obj_ptr)) return 0; - return obj_ptr; - } - - static void construct(PyObject* obj_ptr, converter::rvalue_from_python_stage1_data* data) - { - void* storage = ((converter::rvalue_from_python_storage<pyofstream>*) data)->storage.bytes; - new (storage) pyofstream(reinterpret_cast<PyFileObject *>(obj_ptr)); - data->convertible = storage; - } -}; - -typedef register_python_conversion<std::ostream, ostream_to_python, ostream_from_python> - ostream_python_conversion; - - -void export_utils() -{ - bool_python_conversion(); - string_python_conversion(); - istream_python_conversion(); - ostream_python_conversion(); -} - -} // namespace ledger diff --git a/src/python/pyfstream.h b/src/python/pyfstream.h deleted file mode 100644 index f4650e0a..00000000 --- a/src/python/pyfstream.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PYFSTREAM_H -#define _PYFSTREAM_H - -// pyofstream -// - a stream that writes on a Python file object - -class pyoutbuf : public std::streambuf { - protected: - PyFileObject * fo; // Python file object - public: - // constructor - pyoutbuf (PyFileObject * _fo) : fo(_fo) {} - - protected: - // write one character - virtual int_type overflow (int_type c) { - if (c != EOF) { - char z[2]; - z[0] = c; - z[1] = '\0'; - if (PyFile_WriteString(z, (PyObject *)fo) < 0) { - return EOF; - } - } - return c; - } - - // write multiple characters - virtual std::streamsize xsputn (const char* s, std::streamsize num) { - char * buf = new char[num + 1]; - std::strncpy(buf, s, num); - buf[num] = '\0'; - if (PyFile_WriteString(buf, (PyObject *)fo) < 0) - num = 0; - delete[] buf; - return num; - } -}; - -class pyofstream : public std::ostream { - protected: - pyoutbuf buf; - public: - pyofstream (PyFileObject * fo) : std::ostream(0), buf(fo) { - rdbuf(&buf); - } -}; - -// pyifstream -// - a stream that reads on a file descriptor - -class pyinbuf : public std::streambuf { - protected: - PyFileObject * fo; // Python file object - protected: - /* data buffer: - * - at most, pbSize characters in putback area plus - * - at most, bufSize characters in ordinary read buffer - */ - static const int pbSize = 4; // size of putback area - static const int bufSize = 1024; // size of the data buffer - char buffer[bufSize + pbSize]; // data buffer - - public: - /* constructor - * - initialize file descriptor - * - initialize empty data buffer - * - no putback area - * => force underflow() - */ - pyinbuf (PyFileObject * _fo) : fo(_fo) { - setg (buffer+pbSize, // beginning of putback area - buffer+pbSize, // read position - buffer+pbSize); // end position - } - - protected: - // insert new characters into the buffer - virtual int_type underflow () { -#ifndef _MSC_VER - using std::memmove; -#endif - - // is read position before end of buffer? - if (gptr() < egptr()) { - return traits_type::to_int_type(*gptr()); - } - - /* process size of putback area - * - use number of characters read - * - but at most size of putback area - */ - int numPutback; - numPutback = gptr() - eback(); - if (numPutback > pbSize) { - numPutback = pbSize; - } - - /* copy up to pbSize characters previously read into - * the putback area - */ - memmove (buffer+(pbSize-numPutback), gptr()-numPutback, - numPutback); - - // read at most bufSize new characters - int num; - PyObject *line = PyFile_GetLine((PyObject *)fo, bufSize); - if (! line || ! PyString_Check(line)) { - // ERROR or EOF - return EOF; - } - - num = PyString_Size(line); - if (num == 0) - return EOF; - - memmove (buffer+pbSize, PyString_AsString(line), num); - - // reset buffer pointers - setg (buffer+(pbSize-numPutback), // beginning of putback area - buffer+pbSize, // read position - buffer+pbSize+num); // end of buffer - - // return next character - return traits_type::to_int_type(*gptr()); - } -}; - -class pyifstream : public std::istream { - protected: - pyinbuf buf; - public: - pyifstream (PyFileObject * fo) : std::istream(0), buf(fo) { - rdbuf(&buf); - } -}; - -#endif // _PYFSTREAM_H diff --git a/src/python/pyinterp.cc b/src/python/pyinterp.cc deleted file mode 100644 index d521a0ee..00000000 --- a/src/python/pyinterp.cc +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pyinterp.h" - -#include <boost/python/module_init.hpp> - -namespace ledger { - -using namespace boost::python; - -void export_utils(); -void export_times(); -void export_amount(); -void export_commodity(); -#if 0 -void export_balance(); -void export_value(); -void export_journal(); -void export_parser(); -void export_option(); -void export_walk(); -void export_report(); -void export_format(); -void export_valexpr(); -#endif - -void initialize_for_python() -{ - export_utils(); - export_times(); - export_amount(); - export_commodity(); -#if 0 - export_balance(); - export_value(); - export_journal(); - export_parser(); - export_option(); - export_walk(); - export_format(); - export_report(); - export_valexpr(); -#endif -} - -struct python_run -{ - object result; - - python_run(python_interpreter_t * intepreter, - const string& str, int input_mode) - : result(handle<>(borrowed(PyRun_String(str.c_str(), input_mode, - intepreter->nspace.ptr(), - intepreter->nspace.ptr())))) {} - operator object() { - return result; - } -}; - -python_interpreter_t::python_interpreter_t(xml::xpath_t::scope_t& parent) - : xml::xpath_t::symbol_scope_t(parent), - mmodule(borrowed(PyImport_AddModule("__main__"))), - nspace(handle<>(borrowed(PyModule_GetDict(mmodule.get())))) -{ - Py_Initialize(); - boost::python::detail::init_module("ledger", &initialize_for_python); -} - -object python_interpreter_t::import(const string& str) -{ - assert(Py_IsInitialized()); - - try { - PyObject * mod = PyImport_Import(PyString_FromString(str.c_str())); - if (! mod) - throw_(std::logic_error, "Failed to import Python module " << str); - - object newmod(handle<>(borrowed(mod))); - -#if 1 - // Import all top-level entries directly into the main namespace - dict m_nspace(handle<>(borrowed(PyModule_GetDict(mod)))); - nspace.update(m_nspace); -#else - nspace[string(PyModule_GetName(mod))] = newmod; -#endif - return newmod; - } - catch (const error_already_set&) { - PyErr_Print(); - throw_(std::logic_error, "Importing Python module " << str); - } - return object(); -} - -object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode) -{ - bool first = true; - string buffer; - buffer.reserve(4096); - - while (! in.eof()) { - char buf[256]; - in.getline(buf, 255); - if (buf[0] == '!') - break; - if (first) - first = false; - else - buffer += "\n"; - buffer += buf; - } - - try { - int input_mode; - switch (mode) { - case PY_EVAL_EXPR: input_mode = Py_eval_input; break; - case PY_EVAL_STMT: input_mode = Py_single_input; break; - case PY_EVAL_MULTI: input_mode = Py_file_input; break; - } - assert(Py_IsInitialized()); - return python_run(this, buffer, input_mode); - } - catch (const error_already_set&) { - PyErr_Print(); - throw_(std::logic_error, "Evaluating Python code"); - } - return object(); -} - -object python_interpreter_t::eval(const string& str, py_eval_mode_t mode) -{ - try { - int input_mode; - switch (mode) { - case PY_EVAL_EXPR: input_mode = Py_eval_input; break; - case PY_EVAL_STMT: input_mode = Py_single_input; break; - case PY_EVAL_MULTI: input_mode = Py_file_input; break; - } - assert(Py_IsInitialized()); - return python_run(this, str, input_mode); - } - catch (const error_already_set&) { - PyErr_Print(); - throw_(std::logic_error, "Evaluating Python code"); - } - return object(); -} - -value_t python_interpreter_t::functor_t::operator() - (xml::xpath_t::call_scope_t& args) -{ - try { - if (! PyCallable_Check(func.ptr())) { - return extract<value_t>(func.ptr()); - } else { - if (args.size() > 0) { - list arglist; - if (args.value().is_sequence()) - foreach (const value_t& value, args.value().as_sequence()) - arglist.append(value); - else - arglist.append(args.value()); - - if (PyObject * val = - PyObject_CallObject(func.ptr(), - boost::python::tuple(arglist).ptr())) { - value_t result = extract<value_t>(val)(); - Py_DECREF(val); - return result; - } - else if (PyObject * err = PyErr_Occurred()) { - PyErr_Print(); - throw_(xml::xpath_t::calc_error, - "While calling Python function '" /*<< name() <<*/ "': " << err); - } else { - assert(false); - } - } else { - return call<value_t>(func.ptr()); - } - } - } - catch (const error_already_set&) { - PyErr_Print(); - throw_(xml::xpath_t::calc_error, - "While calling Python function '" /*<< name() <<*/ "'"); - } - return NULL_VALUE; -} - -value_t python_interpreter_t::lambda_t::operator() - (xml::xpath_t::call_scope_t& args) -{ - try { - assert(args.size() == 1); - value_t item = args[0]; - assert(item.is_xml_node()); - return call<value_t>(func.ptr(), item.as_xml_node()); - } - catch (const error_already_set&) { - PyErr_Print(); - throw_(xml::xpath_t::calc_error, - "While evaluating Python lambda expression"); - } - return NULL_VALUE; -} - -} // namespace ledger diff --git a/src/python/pyinterp.h b/src/python/pyinterp.h deleted file mode 100644 index 3d69d972..00000000 --- a/src/python/pyinterp.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PYINTERP_H -#define _PYINTERP_H - -#include "xpath.h" - -#include <boost/python.hpp> -#include <Python.h> - -namespace ledger { - -class python_interpreter_t : public xml::xpath_t::symbol_scope_t -{ - boost::python::handle<> mmodule; - - public: - boost::python::dict nspace; - - python_interpreter_t(xml::xpath_t::scope_t& parent); - - virtual ~python_interpreter_t() { - Py_Finalize(); - } - - boost::python::object import(const string& name); - - enum py_eval_mode_t { - PY_EVAL_EXPR, - PY_EVAL_STMT, - PY_EVAL_MULTI - }; - - boost::python::object eval(std::istream& in, - py_eval_mode_t mode = PY_EVAL_EXPR); - boost::python::object eval(const string& str, - py_eval_mode_t mode = PY_EVAL_EXPR); - boost::python::object eval(const char * c_str, - py_eval_mode_t mode = PY_EVAL_EXPR) { - string str(c_str); - return eval(str, mode); - } - - class functor_t { - protected: - boost::python::object func; - public: - functor_t(const string& name, boost::python::object _func) : func(_func) {} - virtual ~functor_t() {} - virtual value_t operator()(xml::xpath_t::call_scope_t& args); - }; - - virtual xml::xpath_t::ptr_op_t lookup(const string& name) { - if (boost::python::object func = eval(name)) - return WRAP_FUNCTOR(functor_t(name, func)); - else - return xml::xpath_t::symbol_scope_t::lookup(name); - } - - class lambda_t : public functor_t { - public: - lambda_t(boost::python::object code) : functor_t("<lambda>", code) {} - virtual value_t operator()(xml::xpath_t::call_scope_t& args); - }; -}; - -} // namespace ledger - -#endif // _PYINTERP_H diff --git a/src/python/pyledger.cc b/src/python/pyledger.cc deleted file mode 100644 index ebbdc82e..00000000 --- a/src/python/pyledger.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <pyledger.h> - -using namespace boost::python; - -ledger::session_t python_session; - -namespace ledger { - extern void initialize_for_python(); -} - -BOOST_PYTHON_MODULE(ledger) -{ - ledger::set_session_context(&python_session); - ledger::initialize_for_python(); -} diff --git a/src/python/pyledger.h b/src/python/pyledger.h deleted file mode 100644 index 3ab82558..00000000 --- a/src/python/pyledger.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PYLEDGER_H -#define _PYLEDGER_H - -////////////////////////////////////////////////////////////////////// -// -// Ledger Accounting Tool (with Python support via Boost.Python) -// -// A command-line tool for general double-entry accounting. -// -// Copyright (c) 2003,2004 John Wiegley <johnw@newartisans.com> -// - -#include <ledger.h> -#include <pyinterp.h> - -#endif // _PYLEDGER_H diff --git a/src/python/pyutils.h b/src/python/pyutils.h deleted file mode 100644 index 41bbbfde..00000000 --- a/src/python/pyutils.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PY_UTILS_H -#define _PY_UTILS_H - -#include "pyfstream.h" - -template <typename T, typename TfromPy> -struct object_from_python -{ - object_from_python() { - boost::python::converter::registry::push_back - (&TfromPy::convertible, &TfromPy::construct, - boost::python::type_id<T>()); - } -}; - -template <typename T, typename TtoPy, typename TfromPy> -struct register_python_conversion -{ - register_python_conversion() { - boost::python::to_python_converter<T, TtoPy>(); - object_from_python<T, TfromPy>(); - } -}; - -template <typename T> -struct register_optional_to_python : public boost::noncopyable -{ - struct optional_to_python - { - static PyObject * convert(const boost::optional<T>& value) - { - return boost::python::incref - (value ? boost::python::to_python_value<T>()(*value) : - boost::python::detail::none()); - } - }; - - struct optional_from_python - { - static void * convertible(PyObject * source) - { - using namespace boost::python::converter; - - if (source == Py_None) - return source; - - const registration& converters(registered<T>::converters); - - if (implicit_rvalue_convertible_from_python(source, converters)) { - rvalue_from_python_stage1_data data = - rvalue_from_python_stage1(source, converters); - return rvalue_from_python_stage2(source, data, converters); - } - return NULL; - } - - static void construct(PyObject * source, - boost::python::converter::rvalue_from_python_stage1_data * data) - { - using namespace boost::python::converter; - - void * const storage = ((rvalue_from_python_storage<T> *) data)->storage.bytes; - - if (data->convertible == source) // == None - new (storage) boost::optional<T>(); // A Boost uninitialized value - else - new (storage) boost::optional<T>(*static_cast<T *>(data->convertible)); - - data->convertible = storage; - } - }; - - explicit register_optional_to_python() { - register_python_conversion<boost::optional<T>, - optional_to_python, optional_from_python>(); - } -}; - -//boost::python::register_ptr_to_python< boost::shared_ptr<Base> >(); - -#endif // _PY_UTILS_H diff --git a/src/python/tuples.hpp b/src/python/tuples.hpp deleted file mode 100644 index 523846a7..00000000 --- a/src/python/tuples.hpp +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2003-2007, John Wiegley. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of New Artisans LLC nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Copyright 2004-2007 Roman Yakovenko. -// 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 TUPLES_HPP_16_JAN_2007 -#define TUPLES_HPP_16_JAN_2007 - -#include "boost/python.hpp" -#include "boost/tuple/tuple.hpp" -#include "boost/python/object.hpp" //len function -#include <boost/mpl/int.hpp> -#include <boost/mpl/next.hpp> - -/** - * Converts boost::tuples::tuple<...> to\from Python tuple - * - * The conversion is done "on-the-fly", you should only register the conversion - * with your tuple classes. - * For example: - * - * typedef boost::tuples::tuple< int, double, std::string > triplet; - * boost::python::register_tuple< triplet >(); - * - * That's all. After this point conversion to\from next types will be handled - * by Boost.Python library: - * - * triplet - * triplet& ( return type only ) - * const triplet - * const triplet& - * - * Implementation description. - * The conversion uses Boost.Python custom r-value converters. r-value converters - * is very powerful and undocumented feature of the library. The only documentation - * we have is http://boost.org/libs/python/doc/v2/faq.html#custom_string . - * - * The conversion consists from two parts: "to" and "from". - * - * "To" conversion - * The "to" part is pretty easy and well documented ( http://docs.python.org/api/api.html ). - * You should use Python C API to create an instance of a class and than you - * initialize the relevant members of the instance. - * - * "From" conversion - * Lets start from analyzing one of the use case Boost.Python library have to - * deal with: - * - * void do_smth( const triplet& arg ){...} - * - * In order to allow calling this function from Python, the library should keep - * parameter "arg" alive until the function returns. In other words, the library - * should provide instances life-time management. The provided interface is not - * ideal and could be improved. You have to implement two functions: - * - * void* convertible( PyObject* obj ) - * Checks whether the "obj" could be converted to an instance of the desired - * class. If true, the function should return "obj", otherwise NULL - * - * void construct( PyObject* obj, converter::rvalue_from_python_stage1_data* data) - * Constructs the instance of the desired class. This function will be called - * if and only if "convertible" function returned true. The first argument - * is Python object, which was passed as parameter to "convertible" function. - * The second object is some kind of memory allocator for one object. Basically - * it keeps a memory chunk. You will use the memory for object allocation. - * - * For some unclear for me reason, the library implements "C style Inheritance" - * ( http://www.embedded.com/97/fe29712.htm ). So, in order to create new - * object in the storage you have to cast to the "right" class: - * - * typedef converter::rvalue_from_python_storage<your_type_t> storage_t; - * storage_t* the_storage = reinterpret_cast<storage_t*>( data ); - * void* memory_chunk = the_storage->storage.bytes; - * - * "memory_chunk" points to the memory, where the instance will be allocated. - * - * In order to create object at specific location, you should use placement new - * operator: - * - * your_type_t* instance = new (memory_chunk) your_type_t(); - * - * Now, you can continue to initialize the instance. - * - * instance->set_xyz = read xyz from obj - * - * If "your_type_t" constructor requires some arguments, "read" the Python - * object before you call the constructor: - * - * xyz_type xyz = read xyz from obj - * your_type_t* instance = new (memory_chunk) your_type_t(xyz); - * - * Hint: - * In most case you don't really need\have to work with C Python API. Let - * Boost.Python library to do some work for you! - * - **/ - -namespace boost{ namespace python{ - -namespace details{ - -//Small helper function, introduced to allow short syntax for index incrementing -template< int index> -typename mpl::next< mpl::int_< index > >::type increment_index(){ - typedef typename mpl::next< mpl::int_< index > >::type next_index_type; - return next_index_type(); -} - -} - -template< class TTuple > -struct to_py_tuple{ - - typedef mpl::int_< tuples::length< TTuple >::value > length_type; - - static PyObject* convert(const TTuple& c_tuple){ - list values; - //add all c_tuple items to "values" list - convert_impl( c_tuple, values, mpl::int_< 0 >(), length_type() ); - //create Python tuple from the list - return incref( python::tuple( values ).ptr() ); - } - -private: - - template< int index, int length > - static void - convert_impl( const TTuple &c_tuple, list& values, mpl::int_< index >, mpl::int_< length > ) { - values.append( c_tuple.template get< index >() ); - convert_impl( c_tuple, values, details::increment_index<index>(), length_type() ); - } - - template< int length > - static void - convert_impl( const TTuple&, list& values, mpl::int_< length >, mpl::int_< length >) - {} - -}; - - -template< class TTuple> -struct from_py_sequence{ - - typedef TTuple tuple_type; - - typedef mpl::int_< tuples::length< TTuple >::value > length_type; - - static void* - convertible(PyObject* py_obj){ - - if( !PySequence_Check( py_obj ) ){ - return 0; - } - - if( !PyObject_HasAttrString( py_obj, "__len__" ) ){ - return 0; - } - - python::object py_sequence( handle<>( borrowed( py_obj ) ) ); - - if( tuples::length< TTuple >::value != len( py_sequence ) ){ - return 0; - } - - if( convertible_impl( py_sequence, mpl::int_< 0 >(), length_type() ) ){ - return py_obj; - } - else{ - return 0; - } - } - - static void - construct( PyObject* py_obj, converter::rvalue_from_python_stage1_data* data){ - typedef converter::rvalue_from_python_storage<TTuple> storage_t; - storage_t* the_storage = reinterpret_cast<storage_t*>( data ); - void* memory_chunk = the_storage->storage.bytes; - TTuple* c_tuple = new (memory_chunk) TTuple(); - data->convertible = memory_chunk; - - python::object py_sequence( handle<>( borrowed( py_obj ) ) ); - construct_impl( py_sequence, *c_tuple, mpl::int_< 0 >(), length_type() ); - } - - static TTuple to_c_tuple( PyObject* py_obj ){ - if( !convertible( py_obj ) ){ - throw std::runtime_error( "Unable to construct boost::tuples::tuple from Python object!" ); - } - TTuple c_tuple; - python::object py_sequence( handle<>( borrowed( py_obj ) ) ); - construct_impl( py_sequence, c_tuple, mpl::int_< 0 >(), length_type() ); - return c_tuple; - } - -private: - - template< int index, int length > - static bool - convertible_impl( const python::object& py_sequence, mpl::int_< index >, mpl::int_< length > ){ - - typedef typename tuples::element< index, TTuple>::type element_type; - - object element = py_sequence[index]; - extract<element_type> type_checker( element ); - if( !type_checker.check() ){ - return false; - } - else{ - return convertible_impl( py_sequence, details::increment_index<index>(), length_type() ); - } - } - - template< int length > - static bool - convertible_impl( const python::object& py_sequence, mpl::int_< length >, mpl::int_< length > ){ - return true; - } - - template< int index, int length > - static void - construct_impl( const python::object& py_sequence, TTuple& c_tuple, mpl::int_< index >, mpl::int_< length > ){ - - typedef typename tuples::element< index, TTuple>::type element_type; - - object element = py_sequence[index]; - c_tuple.template get< index >() = extract<element_type>( element ); - - construct_impl( py_sequence, c_tuple, details::increment_index<index>(), length_type() ); - } - - template< int length > - static void - construct_impl( const python::object& py_sequence, TTuple& c_tuple, mpl::int_< length >, mpl::int_< length > ) - {} - -}; - -template< class TTuple> -void register_tuple(){ - - to_python_converter< TTuple, to_py_tuple<TTuple> >(); - - converter::registry::push_back( &from_py_sequence<TTuple>::convertible - , &from_py_sequence<TTuple>::construct - , type_id<TTuple>() ); -}; - -} } //boost::python - -#endif//TUPLES_HPP_16_JAN_2007 |