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 __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)
Пример #3
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)