From bf2fb3313c25fb852858ab79ab92e2f0f9625d47 Mon Sep 17 00:00:00 2001 From: "Gustavo J. A. M. Carneiro" Date: Thu, 31 May 2007 00:17:28 +0100 Subject: [PATCH] bool, double --- pybindgen/typehandlers/__init__.py | 4 + pybindgen/typehandlers/booltype.py | 125 +++++++++++++++++++++------ pybindgen/typehandlers/doubletype.py | 107 +++++++++++++++-------- tests/test-generation.py | 1 + 4 files changed, 177 insertions(+), 60 deletions(-) diff --git a/pybindgen/typehandlers/__init__.py b/pybindgen/typehandlers/__init__.py index 42413b5..c196c98 100644 --- a/pybindgen/typehandlers/__init__.py +++ b/pybindgen/typehandlers/__init__.py @@ -4,3 +4,7 @@ import base import voidtype import inttype import stringtype +import booltype +import doubletype + + diff --git a/pybindgen/typehandlers/booltype.py b/pybindgen/typehandlers/booltype.py index 8dcc37e..c3dd753 100644 --- a/pybindgen/typehandlers/booltype.py +++ b/pybindgen/typehandlers/booltype.py @@ -1,28 +1,103 @@ +# docstrings not neede here (the type handler interfaces are fully +# documented in base.py) pylint: disable-msg=C0111 -class BooleanReturn(ReturnType): - def get_c_type(self): - return "gboolean" - def write_decl(self): - self.wrapper.add_declaration("gboolean retval;") - self.wrapper.add_declaration("PyObject *py_main_retval;") - def write_error_return(self): - self.wrapper.write_code("return FALSE;") - def write_conversion(self): - self.wrapper.add_pyret_parse_item("O", "&py_main_retval", prepend=True) - self.wrapper.write_code( - "retval = PyObject_IsTrue(py_main_retval)? TRUE : FALSE;", - code_sink=self.wrapper.post_return_code) -type_matcher.register_ret("gboolean", BooleanReturn) - -class BooleanParam(Parameter): - def get_c_type(self): - return "gboolean" - def convert_c2py(self): - self.wrapper.add_declaration("PyObject *py_%s;" % self.name) - self.wrapper.write_code("py_%s = %s? Py_True : Py_False;" - % (self.name, self.name)) - self.wrapper.add_pyargv_item("py_%s" % self.name) - -type_matcher.register("gboolean", BooleanParam) +from base import ReturnValue, Parameter, \ + ReverseWrapperBase, ForwardWrapperBase +class BoolParam(Parameter): + + DIRECTIONS = [Parameter.DIRECTION_IN] + CTYPES = ['bool'] + + def convert_c_to_python(self, wrapper): + assert isinstance(wrapper, ReverseWrapperBase) + wrapper.build_params.add_parameter('N', ["PyBool_FromLong(%s)" % (self.name,)]) + + def convert_python_to_c(self, wrapper): + assert isinstance(wrapper, ForwardWrapperBase) + name = wrapper.declarations.declare_variable(self.ctype, self.name) + py_name = wrapper.declarations.declare_variable('PyObject *', 'py_'+self.name) + wrapper.parse_params.add_parameter('O', ['&'+py_name]) + wrapper.before_call.write_code("%s = PyObject_IsTrue(%s);" % (name, py_name)) + wrapper.call_params.append(name) + + +class BoolReturn(ReturnValue): + + CTYPES = ['bool'] + + def get_c_error_return(self): + return "return false;" + + def convert_python_to_c(self, wrapper): + py_name = wrapper.declarations.declare_variable('PyObject *', 'py_boolretval') + wrapper.parse_params.add_parameter("O", ["&"+py_name], prepend=True) + wrapper.after_call.write_code( + "retval = PyObject_IsTrue(%s);" % (py_name,)) + + def convert_c_to_python(self, wrapper): + wrapper.build_params.add_parameter( + "N", ["PyBool_FromLong(retval)"], prepend=True) + + +class BoolPtrParam(Parameter): + + DIRECTIONS = [Parameter.DIRECTION_IN, Parameter.DIRECTION_OUT, + Parameter.DIRECTION_IN|Parameter.DIRECTION_OUT] + CTYPES = ['bool*'] + + def convert_c_to_python(self, wrapper): + if self.direction & self.DIRECTION_IN: + wrapper.build_params.add_parameter( + 'N', ["PyBool_FromLong(*%s)" % (self.name,)]) + if self.direction & self.DIRECTION_OUT: + py_name = wrapper.declarations.declare_variable( + 'PyObject *', 'py_'+self.name) + wrapper.parse_params.add_parameter("O", ["&"+py_name]) + wrapper.after_call.write_code( + "*%s = PyObject_IsTrue(%s);" % (self.name, py_name,)) + + def convert_python_to_c(self, wrapper): + assert self.ctype == 'bool*' + name = wrapper.declarations.declare_variable(self.ctype[:-1], self.name) + wrapper.call_params.append('&'+name) + if self.direction & self.DIRECTION_IN: + py_name = wrapper.declarations.declare_variable("PyObject*", 'py_'+self.name) + wrapper.parse_params.add_parameter("O", ["&"+py_name]) + wrapper.before_call.write_code( + "%s = PyObject_IsTrue(%s);" % (self.name, py_name,)) + if self.direction & self.DIRECTION_OUT: + wrapper.build_params.add_parameter( + 'N', ["PyBool_FromLong(%s)" % (self.name,)]) + + +class BoolRefParam(Parameter): + + DIRECTIONS = [Parameter.DIRECTION_IN, Parameter.DIRECTION_OUT, + Parameter.DIRECTION_IN|Parameter.DIRECTION_OUT] + CTYPES = ['bool&'] + + def convert_c_to_python(self, wrapper): + if self.direction & self.DIRECTION_IN: + wrapper.build_params.add_parameter( + 'N', ["PyBool_FromLong(%s)" % (self.name,)]) + if self.direction & self.DIRECTION_OUT: + py_name = wrapper.declarations.declare_variable( + 'PyObject *', 'py_'+self.name) + wrapper.parse_params.add_parameter("O", ["&"+py_name]) + wrapper.after_call.write_code( + "%s = PyObject_IsTrue(%s);" % (self.name, py_name,)) + + def convert_python_to_c(self, wrapper): + assert self.ctype == 'bool&' + name = wrapper.declarations.declare_variable(self.ctype[:-1], self.name) + wrapper.call_params.append(name) + if self.direction & self.DIRECTION_IN: + py_name = wrapper.declarations.declare_variable("PyObject*", 'py_'+self.name) + wrapper.parse_params.add_parameter("O", ["&"+py_name]) + wrapper.before_call.write_code( + "%s = PyObject_IsTrue(%s);" % (self.name, py_name,)) + if self.direction & self.DIRECTION_OUT: + wrapper.build_params.add_parameter( + 'N', ["PyBool_FromLong(%s)" % (self.name,)]) diff --git a/pybindgen/typehandlers/doubletype.py b/pybindgen/typehandlers/doubletype.py index c82364f..4e4c6fe 100644 --- a/pybindgen/typehandlers/doubletype.py +++ b/pybindgen/typehandlers/doubletype.py @@ -1,43 +1,80 @@ +# docstrings not neede here (the type handler doubleerfaces are fully +# documented in base.py) pylint: disable-msg=C0111 + +from base import ReturnValue, Parameter, \ + ReverseWrapperBase, ForwardWrapperBase + class DoubleParam(Parameter): - def get_c_type(self): - return self.props.get('c_type', 'gdouble') - def convert_c2py(self): - self.wrapper.add_declaration("PyObject *py_%s;" % self.name) - self.wrapper.write_code(code=("py_%s = PyFloat_FromDouble(%s);" % - (self.name, self.name)), - cleanup=("Py_DECREF(py_%s);" % self.name)) - self.wrapper.add_pyargv_item("py_%s" % self.name) + + DIRECTIONS = [Parameter.DIRECTION_IN] + CTYPES = ['double'] + + def convert_c_to_python(self, wrapper): + assert isinstance(wrapper, ReverseWrapperBase) + wrapper.build_params.add_parameter('d', [self.name]) + + def convert_python_to_c(self, wrapper): + assert isinstance(wrapper, ForwardWrapperBase) + name = wrapper.declarations.declare_variable(self.ctype, self.name) + wrapper.parse_params.add_parameter('d', ['&'+name]) + wrapper.call_params.append(name) + + +class DoubleReturn(ReturnValue): + + CTYPES = ['double'] + + def get_c_error_return(self): + return "return 0;" + + def convert_python_to_c(self, wrapper): + wrapper.parse_params.add_parameter("d", ["&retval"], prepend=True) + + def convert_c_to_python(self, wrapper): + wrapper.build_params.add_parameter("d", ["retval"], prepend=True) + class DoublePtrParam(Parameter): - def __init__(self, wrapper, name, **props): - if "direction" not in props: - raise argtypes.ArgTypeConfigurationError( - "cannot use double* parameter without direction") - if props["direction"] not in ("out", ): # inout not yet implemented - raise argtypes.ArgTypeConfigurationError( - "cannot use double* parameter with direction '%s'" - % (props["direction"],)) - Parameter.__init__(self, wrapper, name, **props) - def get_c_type(self): - return self.props.get('c_type', 'double*') - def convert_c2py(self): - self.wrapper.add_pyret_parse_item("d", self.name) -for argtype in ('double*', 'gdouble*'): - type_matcher.register(argtype, DoublePtrParam) -class DoubleReturn(ReturnType): - def get_c_type(self): - return self.props.get('c_type', 'gdouble') - def write_decl(self): - self.wrapper.add_declaration("%s retval;" % self.get_c_type()) - def write_error_return(self): - self.wrapper.write_code("return -G_MAXFLOAT;") - def write_conversion(self): - self.wrapper.add_pyret_parse_item("d", "&retval", prepend=True) + DIRECTIONS = [Parameter.DIRECTION_IN, Parameter.DIRECTION_OUT, + Parameter.DIRECTION_IN|Parameter.DIRECTION_OUT] + CTYPES = ['double*'] + + def convert_c_to_python(self, wrapper): + if self.direction & self.DIRECTION_IN: + wrapper.build_params.add_parameter('d', ['*'+self.name]) + if self.direction & self.DIRECTION_OUT: + wrapper.parse_params.add_parameter("d", [self.name]) -for argtype in ('float', 'double', 'gfloat', 'gdouble'): - type_matcher.register(argtype, DoubleParam) - type_matcher.register_ret(argtype, DoubleReturn) + def convert_python_to_c(self, wrapper): + assert self.ctype == 'double*' + name = wrapper.declarations.declare_variable(self.ctype[:-1], self.name) + wrapper.call_params.append('&'+name) + if self.direction & self.DIRECTION_IN: + wrapper.parse_params.add_parameter('d', ['&'+name]) + if self.direction & self.DIRECTION_OUT: + wrapper.build_params.add_parameter("d", [name]) + +class DoubleRefParam(Parameter): + + DIRECTIONS = [Parameter.DIRECTION_IN, Parameter.DIRECTION_OUT, + Parameter.DIRECTION_IN|Parameter.DIRECTION_OUT] + CTYPES = ['double&'] + + def convert_c_to_python(self, wrapper): + if self.direction & self.DIRECTION_IN: + wrapper.build_params.add_parameter('d', [self.name]) + if self.direction & self.DIRECTION_OUT: + wrapper.parse_params.add_parameter("d", [self.name]) + + def convert_python_to_c(self, wrapper): + assert self.ctype == 'double&' + name = wrapper.declarations.declare_variable(self.ctype[:-1], self.name) + wrapper.call_params.append(name) + if self.direction & self.DIRECTION_IN: + wrapper.parse_params.add_parameter('d', ['&'+name]) + if self.direction & self.DIRECTION_OUT: + wrapper.build_params.add_parameter("d", [name]) diff --git a/tests/test-generation.py b/tests/test-generation.py index 2594efa..fa02c83 100755 --- a/tests/test-generation.py +++ b/tests/test-generation.py @@ -18,6 +18,7 @@ class MyReverseWrapper(typehandlers.base.ReverseWrapperBase): params.extend(self.build_params.get_parameters()) self.before_call.write_code('py_retval = PyObject_CallFunction(%s);' % (', '.join(params),)) self.before_call.write_error_check('py_retval == NULL') + self.before_call.add_cleanup_code('Py_DECREF(py_retval);') class MyForwardWrapper(typehandlers.base.ForwardWrapperBase):