Ejemplo n.º 1
0
def add_optional_vector_wrapper_for(mb, variable):
    if not templates.is_instantiation(variable.decl_type.decl_string):
        return False
    name, args = templates.split(variable.decl_type.decl_string)
    if not name == '::boost::optional':
        return False
    assert (len(args) == 1)
    vec, v_type = templates.split(args[0])

    mb.add_registration_code(
        textwrap.dedent("""
    bp::class_<{optional}>("{optional}", bp::init<>()) // support default non-construct init
        .def("is_initialized", &{optional}::is_initialized)
        .def("value", &{optional}::value, bp::return_internal_reference<>())
        .add_property("access", +[]({optional} const & self){{return *self;}}, +[]({optional}  self , bp::object& value)
            {{
                auto& vect = *self;
                vect.clear();
                for ( auto it = bp::stl_input_iterator< {v_type} > (value); it != bp::stl_input_iterator< {v_type} > (); it++) {{
                    vect.push_back(*it);
                }}
                self = vect;
            }} )
        ;
    ;
    """).format(optional=variable.decl_type.decl_string,
                alias=args[0],
                v_type=v_type[0]))
    return True
def scan_callback_classes(module_parser, callback_classes_file):
    callback_classes_file.write("callback_classes = [\n")
    for cls in module_parser.module_namespace.classes(function=module_parser.location_filter, recursive=False):
        if not cls.name.startswith("Callback<"):
            continue
        assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
        dummy_cls_name, template_parameters = templates.split(cls.decl_string)
        callback_classes_file.write("    %r,\n" % template_parameters)
    callback_classes_file.write("]\n")
def scan_callback_classes(module_parser, callback_classes_file):
    callback_classes_file.write("callback_classes = [\n")
    for cls in module_parser.module_namespace.classes(function=module_parser.location_filter,
                                                      recursive=False):
        if not cls.name.startswith("Callback<"):
            continue
        assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
        dummy_cls_name, template_parameters = templates.split(cls.decl_string)
        callback_classes_file.write("    %r,\n" % template_parameters)
    callback_classes_file.write("]\n")
Ejemplo n.º 4
0
def add_variant_converters_for(mb, cl):
    """
    Register to-python converters for boost::variant objects.
    (will copy contained type, see pywrap/variant_converter.hpp)

    Somehow mb.namespace('::boost').classes(allow_empty=True) does not
    contain the boost::variant class in the project this function was
    developed for, as a workaround we use:

        for td in namespace.typedefs(allow_empty=True):
           if not classes.add_variant_converters_for(mb, td.target_decl):
              continue
           # do other things with boost::variant class
    """
    if not templates.is_instantiation(cl.decl_string):
        return False
    name, args = templates.split(cl.decl_string)
    if not name == '::boost::variant':
        return False

    # Normally one would like to use cl.include_files.append() here, but
    # when "cl=td.target_decl", cl points to a
    # pyplusplus.decl_wrappers.class_wrapper.class_declaration_t
    # instead of a pyplusplus.decl_wrappers.class_wrapper.class_t object.
    mb.add_declaration_code('#include "pywrap/variant_converter.hpp"\n')
    mb.add_registration_code(
        textwrap.dedent("""
    typedef {variant} {alias};
    bp::to_python_converter<{alias}, variant_to_object<{alias}> >();
    """).format(variant=cl.decl_string, alias=cl.alias))
    for arg in args:
        if arg == 'boost::detail::variant::void_':
            continue
        mb.add_registration_code(
            textwrap.dedent("""
        bp::implicitly_convertible<{from_type}, {variant}>();
        """).format(variant=cl.alias, from_type=arg))
    return True
    def __call__(self, module_parser,
                 pygccxml_definition,
                 global_annotations,
                 parameter_annotations):
        try:
            ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name)
        except ValueError: # the header is not from ns3
            return # ignore the definition, it's not ns-3 def.

        definition_module = self.headers_map[ns3_header]

        ## Note: we don't include line numbers in the comments because
        ## those numbers are very likely to change frequently, which would
        ## cause needless changes, since the generated python files are
        ## kept under version control.

        #global_annotations['pygen_comment'] = "%s:%i: %s" % \
        #    (ns3_header, pygccxml_definition.location.line, pygccxml_definition)
        global_annotations['pygen_comment'] = "%s (module %r): %s" % \
            (ns3_header, definition_module, pygccxml_definition)


        ## handle ns3::Object::GetObject (left to its own devices,
        ## pybindgen will generate a mangled name containing the template
        ## argument type name).
        if isinstance(pygccxml_definition, member_function_t) \
                and pygccxml_definition.parent.name == 'Object' \
                and pygccxml_definition.name == 'GetObject':
            template_args = templates.args(pygccxml_definition.demangled_name)
            if template_args == ['ns3::Object']:
                global_annotations['template_instance_names'] = 'ns3::Object=>GetObject'

        ## Don't wrap Simulator::Schedule* (manually wrapped)
        if isinstance(pygccxml_definition, member_function_t) \
                and pygccxml_definition.parent.name == 'Simulator' \
                and pygccxml_definition.name.startswith('Schedule'):
            global_annotations['ignore'] = None

        # manually wrapped
        if isinstance(pygccxml_definition, member_function_t) \
                and pygccxml_definition.parent.name == 'Simulator' \
                and pygccxml_definition.name == 'Run':
            global_annotations['ignore'] = True

        ## http://www.gccxml.org/Bug/view.php?id=9915
        if isinstance(pygccxml_definition, calldef_t):
            for arg in pygccxml_definition.arguments:
                if arg.default_value is None:
                    continue
                elif arg.default_value == "ns3::MilliSeconds( )":
                    arg.default_value = "ns3::MilliSeconds(0)"
                elif arg.default_value == "ns3::Seconds( )":
                    arg.default_value = "ns3::Seconds(0)"

        ## classes
        if isinstance(pygccxml_definition, class_t):
            print >> sys.stderr, pygccxml_definition
            # no need for helper classes to allow subclassing in Python, I think...
            #if pygccxml_definition.name.endswith('Helper'):
            #    global_annotations['allow_subclassing'] = 'false'

            #
            # If a class is template instantiation, even if the
            # template was defined in some other module, if a template
            # argument belongs to this module then the template
            # instantiation will belong to this module.
            # 
            if templates.is_instantiation(pygccxml_definition.decl_string):
                cls_name, template_parameters = templates.split(pygccxml_definition.name)
                template_parameters_decls = [find_declaration_from_name(module_parser.global_ns, templ_param)
                                             for templ_param in template_parameters]
                #print >> sys.stderr, "********************", cls_name, repr(template_parameters_decls)
                
                template_parameters_modules = []
                for templ in template_parameters_decls:
                    if not hasattr(templ, 'location'):
                        continue
                    try:
                        h = get_ns3_relative_path(templ.location.file_name)
                    except ValueError:
                        continue
                    template_parameters_modules.append(self.headers_map[h])

                for templ_mod in template_parameters_modules:
                    if templ_mod == self.module:
                        definition_module = templ_mod
                        break
                #print >> sys.stderr, "********************", cls_name, repr(template_parameters_modules)


            if definition_module != self.module:
                global_annotations['import_from_module'] = 'ns.%s' % (definition_module.replace('-', '_'),)

            if pygccxml_definition.decl_string.startswith('::ns3::SimpleRefCount<'):
                global_annotations['incref_method'] = 'Ref'
                global_annotations['decref_method'] = 'Unref'
                global_annotations['peekref_method'] = 'GetReferenceCount'
                global_annotations['automatic_type_narrowing'] = 'true'
                return

            if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):
                # manually handled in ns3modulegen_core_customizations.py
                global_annotations['ignore'] = None
                return

            if pygccxml_definition.decl_string.startswith('::ns3::TracedCallback<'):
                global_annotations['ignore'] = None
                return

            if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):
                # handled by pybindgen "type transformation"
                global_annotations['ignore'] = None
                return

            # table driven class customization
            try:
                annotations = type_annotations[pygccxml_definition.decl_string]
            except KeyError:
                pass
            else:
                global_annotations.update(annotations)

        ## enums
        if isinstance(pygccxml_definition, enumeration_t):
            if definition_module != self.module:
                global_annotations['import_from_module'] = 'ns.%s' % definition_module

        ## free functions
        if isinstance(pygccxml_definition, free_function_t):

            if definition_module != self.module:
                global_annotations['ignore'] = None
                return

            if pygccxml_definition.name == 'PeekPointer':
                global_annotations['ignore'] = None
                return

        ## table driven methods/constructors/functions customization
        if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)):
            try:
                annotations = type_annotations[str(pygccxml_definition)]
            except KeyError:
                pass
            else:
                for key,value in annotations.items():
                    if key == 'params':
                        parameter_annotations.update (value)
                        del annotations['params']
                global_annotations.update(annotations)
Ejemplo n.º 6
0
    def __call__(self, module_parser, pygccxml_definition, global_annotations,
                 parameter_annotations):
        try:
            ns3_header = get_ns3_relative_path(
                pygccxml_definition.location.file_name)
        except ValueError:
            return

        definition_module = self.headers_map[ns3_header]








        global_annotations['pygen_comment'] = "%s (module %r): %s" % \
            (ns3_header, definition_module, pygccxml_definition)





        if isinstance(pygccxml_definition, member_function_t) \
                and pygccxml_definition.parent.name == 'Object' \
                and pygccxml_definition.name == 'GetObject':
            template_args = templates.args(pygccxml_definition.demangled_name)
            if template_args == ['ns3::Object']:
                global_annotations[
                    'template_instance_names'] = 'ns3::Object=>GetObject'


        if isinstance(pygccxml_definition, member_function_t) \
                and pygccxml_definition.parent.name == 'Simulator' \
                and pygccxml_definition.name.startswith('Schedule'):
            global_annotations['ignore'] = None


        if isinstance(pygccxml_definition, member_function_t) \
                and pygccxml_definition.parent.name == 'Simulator' \
                and pygccxml_definition.name == 'Run':
            global_annotations['ignore'] = True

        if isinstance(pygccxml_definition, calldef_t):
            for arg in pygccxml_definition.arguments:
                if arg.default_value is None:
                    continue
                elif arg.default_value == "ns3::MilliSeconds( )":
                    arg.default_value = "ns3::MilliSeconds(0)"
                elif arg.default_value == "ns3::Seconds( )":
                    arg.default_value = "ns3::Seconds(0)"

        if isinstance(pygccxml_definition, class_t):
            print >> sys.stderr, pygccxml_definition

            if templates.is_instantiation(pygccxml_definition.decl_string):
                cls_name, template_parameters = templates.split(
                    pygccxml_definition.name)
                template_parameters_decls = [
                    find_declaration_from_name(module_parser.global_ns,
                                               templ_param)
                    for templ_param in template_parameters
                ]

                template_parameters_modules = []
                for templ in template_parameters_decls:
                    if not hasattr(templ, 'location'):
                        continue
                    try:
                        h = get_ns3_relative_path(templ.location.file_name)
                    except ValueError:
                        continue
                    template_parameters_modules.append(self.headers_map[h])

                for templ_mod in template_parameters_modules:
                    if templ_mod == self.module:
                        definition_module = templ_mod
                        break

            if definition_module != self.module:
                global_annotations['import_from_module'] = 'ns.%s' % (
                    definition_module.replace('-', '_'), )

            if pygccxml_definition.decl_string.startswith(
                    '::ns3::SimpleRefCount<'):
                global_annotations['incref_method'] = 'Ref'
                global_annotations['decref_method'] = 'Unref'
                global_annotations['peekref_method'] = 'GetReferenceCount'
                global_annotations['automatic_type_narrowing'] = 'true'
                return

            if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):

                global_annotations['ignore'] = None
                return

            if pygccxml_definition.decl_string.startswith(
                    '::ns3::TracedCallback<'):
                global_annotations['ignore'] = None
                return

            if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):

                global_annotations['ignore'] = None
                return

            try:
                annotations = type_annotations[pygccxml_definition.decl_string]
            except KeyError:
                pass
            else:
                global_annotations.update(annotations)

        if isinstance(pygccxml_definition, enumeration_t):
            if definition_module != self.module:
                global_annotations[
                    'import_from_module'] = 'ns.%s' % definition_module

        if isinstance(pygccxml_definition, free_function_t):

            if definition_module != self.module:
                global_annotations['ignore'] = None
                return

            if pygccxml_definition.name == 'PeekPointer':
                global_annotations['ignore'] = None
                return

        if isinstance(pygccxml_definition,
                      (free_function_t, member_function_t, constructor_t)):
            try:
                annotations = type_annotations[str(pygccxml_definition)]
            except KeyError:
                pass
            else:
                for key, value in annotations.items():
                    if key == 'params':
                        parameter_annotations.update(value)
                        del annotations['params']
                global_annotations.update(annotations)