Exemplo n.º 1
0
    def generate(self, code_sink, wrapper_name=None, extra_wrapper_params=()):
        """
        Generates the wrapper code
        code_sink -- a CodeSink instance that will receive the generated code
        method_name -- actual name the method will get
        extra_wrapper_params -- extra parameters the wrapper function should receive

        Returns the corresponding PyMethodDef entry string.
        """

        if self.throw: # Bug #780945
            self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR = False
            self.reset_code_generation_state()

        class_ = self.class_
        #assert isinstance(class_, CppClass)
        tmp_sink = codesink.MemoryCodeSink()

        self.generate_body(tmp_sink, gen_call_params=[class_])

        if wrapper_name is None:
            self.wrapper_actual_name = self.wrapper_base_name
        else:
            self.wrapper_actual_name = wrapper_name

        self.get_wrapper_signature(self.wrapper_actual_name, extra_wrapper_params)
        self.write_open_wrapper(code_sink)#, add_static=self.static_decl)
        tmp_sink.flush_to(code_sink)
        self.write_close_wrapper(code_sink)
Exemplo n.º 2
0
    def generate(self, code_sink, wrapper_name=None, extra_wrapper_params=()):
        """
        Generates the wrapper code

        :param code_sink: a CodeSink instance that will receive the generated code
        :param wrapper_name: name of wrapper function
        """

        if self.throw:  # Bug #780945
            self.return_value.REQUIRES_ASSIGNMENT_CONSTRUCTOR = False
            self.reset_code_generation_state()

        if wrapper_name is None:
            self.wrapper_actual_name = self.wrapper_base_name
        else:
            self.wrapper_actual_name = wrapper_name
        tmp_sink = codesink.MemoryCodeSink()
        self.generate_body(tmp_sink)

        flags = self.get_py_method_def_flags()
        self.wrapper_args = []
        if 'METH_VARARGS' in flags:
            if self.self_parameter_pystruct is None:
                self_param = 'PyObject * PYBINDGEN_UNUSED(dummy)'
            else:
                self_param = '%s *self' % self.self_parameter_pystruct
            self.wrapper_args.append(self_param)
            self.wrapper_args.append("PyObject *args")
            if 'METH_KEYWORDS' in flags:
                self.wrapper_args.append("PyObject *kwargs")
        self.wrapper_args.extend(extra_wrapper_params)
        self.wrapper_return = "PyObject *"
        self.write_open_wrapper(code_sink)
        tmp_sink.flush_to(code_sink)
        self.write_close_wrapper(code_sink)
Exemplo n.º 3
0
 def generate(self, code_sink):
     """
     :param code_sink: a CodeSink instance that will receive the generated code
     """
     tmp_sink = codesink.MemoryCodeSink()
     self.generate_body(tmp_sink)
     code_sink.writeln("static PyObject* %s(%s *self, void * PYBINDGEN_UNUSED(closure))"
                       % (self.c_function_name, self.class_.pystruct))
     code_sink.writeln('{')
     code_sink.indent()
     tmp_sink.flush_to(code_sink)
     code_sink.unindent()
     code_sink.writeln('}')
Exemplo n.º 4
0
 def generate(self, code_sink):
     """
     code_sink -- a CodeSink instance that will receive the generated code
     """
     
     tmp_sink = codesink.MemoryCodeSink()
     self.generate_body(tmp_sink)
     code_sink.writeln("static PyObject* %s(%s *self)" % (self.c_function_name,
                                                          self.container.iter_pystruct))
     code_sink.writeln('{')
     code_sink.indent()
     tmp_sink.flush_to(code_sink)
     code_sink.unindent()
     code_sink.writeln('}')
Exemplo n.º 5
0
    def generate(self, code_sink, wrapper_name=None, extra_wrapper_params=()):
        """
        Generates the wrapper code
        :param code_sink: a CodeSink instance that will receive the generated code
        :returns: the wrapper function name.

        """

        if self.visibility == 'private':
            raise utils.SkipWrapper("Class %r has a private constructor ->"
                                    " cannot generate a constructor for it" % self._class.full_name)
        elif self.visibility == 'protected':
            if self._class.helper_class is None:
                raise utils.SkipWrapper("Class %r has a protected constructor and no helper class"
                                        " -> cannot generate a constructor for it" % self._class.full_name)

        #assert isinstance(class_, CppClass)
        tmp_sink = codesink.MemoryCodeSink()

        assert self._class is not None
        self.generate_body(tmp_sink, gen_call_params=[self._class])

        assert ((self.parse_params.get_parameters() == ['""'])
                or self.parse_params.get_keywords() is not None), \
               ("something went wrong with the type handlers;"
                " constructors need parameter names, "
                "yet no names were given for the class %s constructor"
                % self._class.name)

        if wrapper_name is None:
            self.wrapper_actual_name = self.wrapper_base_name
        else:
            self.wrapper_actual_name = wrapper_name

        self.wrapper_return = 'static int'
        self.wrapper_args = ["%s *self" % self._class.pystruct,
                             "PyObject *args", "PyObject *kwargs"]
        self.wrapper_args.extend(extra_wrapper_params)

        self.write_open_wrapper(code_sink)
        tmp_sink.flush_to(code_sink)
        code_sink.writeln('return 0;')
        self.write_close_wrapper(code_sink)
Exemplo n.º 6
0
cls_pp = mod.add_class('PythonScript',
                       allow_subclassing=True,
                       foreign_cpp_namespace='Python',
                       custom_name='Plugin')
"""
 PythonPlugin implements LoggingInterface for messaging to Tiled
"""
cls_logi = tiled.add_class('LoggingInterface', destructor_visibility='private')
cls_logi.add_enum('OutputType', ('INFO', 'ERROR'))
cls_logi.add_method('log',
                    'void', [('OutputType', 'type'), ('const QString', 'msg')],
                    is_virtual=True)

with open('pythonbind.cpp', 'w') as fh:
    import pybindgen.typehandlers.codesink as cs
    sink = cs.MemoryCodeSink()

    print >> fh, """
#ifdef __MINGW32__
#include <cmath> // included before Python.h to fix ::hypot not declared issue
#endif
"""

    mod.generate(fh)

    print >> fh, """
PyObject* _wrap_convert_c2py__Tiled__LoggingInterface(Tiled::LoggingInterface *cvalue)
{
        PyObject *py_retval;
        PyTiledLoggingInterface *py_LoggingInterface;
        
Exemplo n.º 7
0
def test():
    code_out = codesink.FileCodeSink(sys.stdout)
    pybindgen.write_preamble(code_out)
    sys.stdout.write("""
#include <string>
#include <stdint.h>
""")
    ## Declare a dummy class
    sys.stdout.write('''
class Foo
{
    std::string m_datum;
public:
    Foo () : m_datum ("")
        {}
    Foo (std::string datum) : m_datum (datum)
        {}
    std::string get_datum () const { return m_datum; }

    Foo (Foo const & other) : m_datum (other.get_datum ())
        {}
};
''')

    module = Module("foo")

    ## Register type handlers for the class
    Foo = module.add_class('Foo')
    Foo.add_constructor([Parameter.new("const Foo&", "foo")])
    #Foo.full_name = Foo.name # normally adding the class to a module would take care of this
    Foo.generate_forward_declarations(code_out, module)

    wrapper_number = 0

    ## test return type handlers of reverse wrappers
    for return_type, return_handler in list(typehandlers.base.return_type_matcher.items()):
        if type_blacklisted(return_type):
            continue
        if os.name == 'nt':
            if stdint_rx.search(return_type):
                continue # win32 does not support the u?int\d+_t types (defined in <stdint.h>)

        code_out.writeln("/* Test %s (%s) return type  */" % (return_type, return_handler))
        if issubclass(return_handler, (cppclass.CppClassPtrReturnValue,
                                       typehandlers.pyobjecttype.PyObjectReturnValue)):
            for caller_owns_return in True, False:
                retval = return_handler(return_type, caller_owns_return=caller_owns_return)
                wrapper = MyReverseWrapper(retval, [])
                wrapper_number += 1
                try:
                    wrapper.generate(code_out,
                                     '_test_wrapper_number_%i' % (wrapper_number,),
                                     ['static'])
                except NotImplementedError:
                    sys.stderr.write("ReverseWrapper %s(void) (caller_owns_return=%r)"
                                     " could not be generated: not implemented\n"
                                     % (retval.ctype, caller_owns_return))
                sys.stdout.write("\n")
        else:
            retval = return_handler(return_type)
            try:
                wrapper = MyReverseWrapper(retval, [])
            except NotSupportedError:
                continue
            except NotImplementedError:
                sys.stderr.write("ReverseWrapper %s(void) could not be generated: not implemented\n"
                                 % (retval.ctype))
                continue
            wrapper_number += 1
            memsink = codesink.MemoryCodeSink()
            try:
                wrapper.generate(memsink,
                                 '_test_wrapper_number_%i' % (wrapper_number,),
                                 ['static'])
            except NotImplementedError:
                sys.stderr.write("ReverseWrapper %s xxx (void) could not be generated: not implemented\n"
                                 % (retval.ctype,))
                continue
            except NotSupportedError:
                continue
            else:
                memsink.flush_to(code_out)
            sys.stdout.write("\n")


    ## test parameter type handlers of reverse wrappers
    for param_type, param_handler in list(typehandlers.base.param_type_matcher.items()):
        if type_blacklisted(param_type):
            continue
        if os.name == 'nt':
            if stdint_rx.search(param_type):
                continue # win32 does not support the u?int\d+_t types (defined in <stdint.h>)
        for direction in param_handler.DIRECTIONS:
            if direction == (Parameter.DIRECTION_IN):
                param_name = 'param'
            elif direction == (Parameter.DIRECTION_IN|Parameter.DIRECTION_OUT):
                param_name = 'param_inout'
            elif direction == (Parameter.DIRECTION_OUT):
                param_name = 'param_out'

                def try_wrapper(param, wrapper_number):
                    if 'const' in param.ctype and direction&Parameter.DIRECTION_OUT:
                        return
                    code_out.writeln("/* Test %s (%s) param type  */" % (param_type, param_handler))
                    wrapper = MyReverseWrapper(ReturnValue.new('void'), [param])
                    try:
                        wrapper.generate(code_out,
                                         '_test_wrapper_number_%i' % (wrapper_number,),
                                         ['static'])
                    except NotImplementedError:
                        sys.stderr.write("ReverseWrapper void(%s) could not be generated: not implemented"
                                         % (param.ctype))
                    sys.stdout.write("\n")

                if issubclass(param_handler, (cppclass.CppClassPtrParameter,
                                              typehandlers.pyobjecttype.PyObjectParam)):
                    for transfer_ownership in True, False:
                        try:
                            param = param_handler(param_type, param_name, transfer_ownership=transfer_ownership)
                        except TypeError:
                            sys.stderr.write("ERROR -----> param_handler(param_type=%r, "
                                             "transfer_ownership=%r, is_const=%r)\n"
                                             % (param_type, transfer_ownership, is_const))
                        wrapper_number += 1
                        try_wrapper(param, wrapper_number)
                else:
                    param = param_handler(param_type, param_name, direction)
                    wrapper_number += 1
                    try_wrapper(param, wrapper_number)

    
    ## test generic forward wrappers, and module

    for return_type, return_handler in list(typehandlers.base.return_type_matcher.items()):
        if type_blacklisted(return_type):
            continue
        if os.name == 'nt':
            if stdint_rx.search(return_type):
                continue # win32 does not support the u?int\d+_t types (defined in <stdint.h>)
        wrapper_number += 1
        function_name = 'foo_function_%i' % (wrapper_number,)
        ## declare a fake prototype
        sys.stdout.write("%s %s(void);\n\n" % (return_type, function_name))

        if issubclass(return_handler, (cppclass.CppClassPtrReturnValue,
                                       typehandlers.pyobjecttype.PyObjectReturnValue)):
            retval = return_handler(return_type, caller_owns_return=True)
        else:
            retval = return_handler(return_type)

        module.add_function(function_name, retval, [])
    
    for param_type, param_handler in list(typehandlers.base.param_type_matcher.items()):
        if type_blacklisted(param_type):
            continue
        if os.name == 'nt':
            if stdint_rx.search(param_type):
                continue # win32 does not support the u?int\d+_t types (defined in <stdint.h>)

        for is_const in [True, False]:
            for direction in param_handler.DIRECTIONS:
                if direction == (Parameter.DIRECTION_IN):
                    param_name = 'param'
                elif direction == (Parameter.DIRECTION_IN|Parameter.DIRECTION_OUT):
                    param_name = 'param_inout'
                elif direction == (Parameter.DIRECTION_OUT):
                    param_name = 'param_out'

                if is_const and direction & Parameter.DIRECTION_OUT:
                    continue # const and output parameter makes no sense

                if is_const:
                    if '&' in param_type: # const references not allowed
                        continue
                    param_type_with_const = "const %s" % (param_type,)
                else:
                    param_type_with_const = param_type

                if issubclass(param_handler, (cppclass.CppClassPtrParameter,
                                              typehandlers.pyobjecttype.PyObjectParam)):
                    for transfer_ownership in True, False:
                        name = param_name + (transfer_ownership and '_transfer' or '_notransfer')
                        try:
                            param = param_handler(param_type, name, transfer_ownership=transfer_ownership)
                        except TypeError:
                            sys.stderr.write("ERROR -----> param_handler(param_type=%r, "
                                             "name=%r, transfer_ownership=%r, is_const=%r)\n"
                                             % (param_type, name, transfer_ownership, is_const))
                        wrapper_number += 1
                        function_name = 'foo_function_%i' % (wrapper_number,)
                        ## declare a fake prototype
                        sys.stdout.write("void %s(%s %s);\n\n" % (function_name, param_type_with_const, name))
                        module.add_function(function_name, ReturnValue.new('void'), [param])
                else:
                    param = param_handler(param_type, param_name, direction)
                    wrapper_number += 1
                    function_name = 'foo_function_%i' % (wrapper_number,)
                    ## declare a fake prototype
                    sys.stdout.write("void %s(%s);\n\n" % (function_name, param_type_with_const))
                    module.add_function(function_name, ReturnValue.new('void'), [param])

    module.generate(code_out)