Example #1
0
 def ns3_object_instance_creation_function(cpp_class, code_block, lvalue,
                                           parameters, construct_type_name):
     assert lvalue
     assert not lvalue.startswith('None')
     if cpp_class.cannot_be_constructed:
         raise CodeGenerationError("%s cannot be constructed (%s)"
                                   % cpp_class.full_name)
     if cpp_class.incomplete_type:
         raise CodeGenerationError("%s cannot be constructed (incomplete type)"
                                   % cpp_class.full_name)
     code_block.write_code("%s = new %s(%s);" % (lvalue, construct_type_name, parameters))
     code_block.write_code("%s->Ref ();" % (lvalue))
Example #2
0
    def generate_call(self, class_=None):
        "virtual method implementation; do not call"
        if class_ is None:
            class_ = self._class

        if self.throw:
            self.before_call.write_code('try\n{')
            self.before_call.indent()

        #assert isinstance(class_, CppClass)
        if class_.helper_class is None:
            class_.write_create_instance(self.before_call, "self->obj", ", ".join(self.call_params))
            class_.write_post_instance_creation_code(self.before_call, "self->obj", ", ".join(self.call_params))
            self.before_call.write_code("self->flags = PYBINDGEN_WRAPPER_FLAG_NONE;")
        else:
            ## We should only create a helper class instance when
            ## being called from a user python subclass.
            self.before_call.write_code("if (Py_TYPE(self) != &%s)" % class_.pytypestruct)
            self.before_call.write_code("{")
            self.before_call.indent()

            class_.write_create_instance(self.before_call, "self->obj", ", ".join(self.call_params),
                                         class_.helper_class.name)
            self.before_call.write_code("self->flags = PYBINDGEN_WRAPPER_FLAG_NONE;")
            self.before_call.write_code('((%s*) self->obj)->set_pyobj((PyObject *)self);'
                                        % class_.helper_class.name)
            class_.write_post_instance_creation_code(self.before_call, "self->obj", ", ".join(self.call_params),
                                                     class_.helper_class.name)

            self.before_call.unindent()
            self.before_call.write_code("} else {")
            self.before_call.indent()

            self.before_call.write_code("// visibility: %r" % self.visibility)
            try:
                if self.visibility not in ['public']:
                    raise CodeGenerationError("private/protected constructor")
                class_.get_construct_name()
            except CodeGenerationError:
                self.before_call.write_code('PyErr_SetString(PyExc_TypeError, "class \'%s\' '
                                            'cannot be constructed");' % class_.name)
                self.before_call.write_code('return -1;')
            else:
                class_.write_create_instance(self.before_call, "self->obj", ", ".join(self.call_params))
                self.before_call.write_code("self->flags = PYBINDGEN_WRAPPER_FLAG_NONE;")
                class_.write_post_instance_creation_code(self.before_call, "self->obj", ", ".join(self.call_params))

            self.before_call.unindent()
            self.before_call.write_code("}")

        if self.throw:
            for exc in self.throw:
                self.before_call.unindent()
                self.before_call.write_code('} catch (%s const &exc) {' % exc.full_name)
                self.before_call.indent()
                self.before_call.write_cleanup()
                exc.write_convert_to_python(self.before_call, 'exc')
                self.before_call.write_code('return -1;')
            self.before_call.unindent()
            self.before_call.write_code('}')
Example #3
0
            def convert_python_to_c(self, wrapper):
                "parses python args to get C++ value"
                assert isinstance(wrapper, typehandlers.ForwardWrapperBase)

                if self.DISABLED:
                    raise CodeGenerationError("wrapper could not be generated")

                if self.default_value is None:
                    py_callback = wrapper.declarations.declare_variable(
                        'PyObject*', self.name)
                    wrapper.parse_params.add_parameter('O',
                                                       ['&' + py_callback],
                                                       self.name)
                    wrapper.before_call.write_error_check(
                        '!PyCallable_Check(%s)' % py_callback,
                        'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");'
                        % self.name)
                    callback_impl = wrapper.declarations.declare_variable(
                        'ns3::Ptr<%s>' % self.PYTHON_CALLBACK_IMPL_NAME,
                        '%s_cb_impl' % self.name)
                    wrapper.before_call.write_code(
                        "%s = ns3::Create<%s> (%s);" %
                        (callback_impl, self.PYTHON_CALLBACK_IMPL_NAME,
                         py_callback))
                    wrapper.call_params.append(
                        'ns3::Callback<%s> (%s)' %
                        (', '.join(self.TEMPLATE_ARGS), callback_impl))
                else:
                    py_callback = wrapper.declarations.declare_variable(
                        'PyObject*', self.name, 'NULL')
                    wrapper.parse_params.add_parameter('O',
                                                       ['&' + py_callback],
                                                       self.name,
                                                       optional=True)
                    value = wrapper.declarations.declare_variable(
                        'ns3::Callback<%s>' % ', '.join(self.TEMPLATE_ARGS),
                        self.name + '_value', self.default_value)

                    wrapper.before_call.write_code("if (%s) {" %
                                                   (py_callback, ))
                    wrapper.before_call.indent()

                    wrapper.before_call.write_error_check(
                        '!PyCallable_Check(%s)' % py_callback,
                        'PyErr_SetString(PyExc_TypeError, "parameter \'%s\' must be callbale");'
                        % self.name)

                    wrapper.before_call.write_code(
                        "%s = ns3::Callback<%s> (ns3::Create<%s> (%s));" %
                        (value, ', '.join(self.TEMPLATE_ARGS),
                         self.PYTHON_CALLBACK_IMPL_NAME, py_callback))

                    wrapper.before_call.unindent()
                    wrapper.before_call.write_code(
                        "}")  # closes: if (py_callback) {

                    wrapper.call_params.append(value)
Example #4
0
    def get_py_method_def(self, name):
        """
        Returns an array element to use in a PyMethodDef table.
        Should only be called after code generation.

        name -- python wrapper/method name
        """
        if len(self.all_wrappers) == 1 \
                and not getattr(self.all_wrappers[0], 'NEEDS_OVERLOADING_INTERFACE', False):
            return self.all_wrappers[0].get_py_method_def(name)
        else:
            self._normalize_py_method_flags()
            flags = self.all_wrappers[0].get_py_method_def_flags()
            ## detect inconsistencies in flags; they must all be the same
            if __debug__:
                for func in self.all_wrappers:
                    try:
                        assert set(func.get_py_method_def_flags()) == set(flags),\
                            ("Expected PyMethodDef flags %r, got %r"
                             % (flags, func.get_py_method_def_flags()))
                    except (TypeConfigurationError, CodeGenerationError,
                            NotSupportedError):
                        pass
            # check available docstrings for the overloads
            docstrings_set = set()
            for wrap in self.all_wrappers:
                if wrap.docstring is not None:
                    docstrings_set.add(wrap.docstring)
            docstring = None
            if len(docstrings_set) is 1:
                docstring = docstrings_set.pop()
            elif len(docstrings_set) > 1:
                raise CodeGenerationError(
                    "Overloaded '%s' has conflicting docstrings" %
                    self.wrapper_name)

            assert isinstance(self.wrapper_return, string_types)
            assert isinstance(self.wrapper_actual_name, string_types)
            assert isinstance(self.wrapper_args, list)

            return "{(char *) \"%s\", (PyCFunction) %s, %s, %s }," % \
                (name, self.wrapper_actual_name, '|'.join(sorted(flags)),
                 (docstring is None and "NULL" or ('"'+docstring+'"')))
Example #5
0
def ns3_ptr_instance_creation_function(cpp_class, code_block, lvalue,
                                       parameters, construct_type_name):
    """
    ns3::Ptr "instance creation function"; it is called whenever a new
    C++ class instance needs to be created

    :param cpp_class: the CppClass object whose instance is to be created
    :param code_block: CodeBlock object on which the instance creation code should be generated
    :param lvalue: lvalue expression that should hold the result in the end
    :param parameters: stringified list of parameters
    :param construct_type_name: actual name of type to be constructed (it is
                          not always the class name, sometimes it's
                          the python helper class)
    """
    assert lvalue
    assert not lvalue.startswith('None')
    if cpp_class.incomplete_type:
        raise CodeGenerationError(
            "%s cannot be constructed (incomplete type)" % cpp_class.full_name)
    code_block.write_code("%s = ::ns3::Create<%s>(%s);" %
                          (lvalue, construct_type_name, parameters))