def __parse_xml_file(self, xml_file): scanner_ = scanner_t(xml_file, self.__decl_factory, self.__config) scanner_.read() self.__xml_generator_from_xml_file = \ scanner_.xml_generator_from_xml_file decls = scanner_.declarations() types = scanner_.types() files = scanner_.files() linker_ = linker.linker_t( decls=decls, types=types, access=scanner_.access(), membership=scanner_.members(), files=files, xml_generator_from_xml_file=self.__xml_generator_from_xml_file) for type_ in list(types.values()): # I need this copy because internaly linker change types collection linker_.instance = type_ declarations.apply_visitor(linker_, type_) for decl in decls.values(): linker_.instance = decl declarations.apply_visitor(linker_, decl) declarations_joiner.bind_aliases(iter(decls.values())) # Patch the declarations tree if self.__xml_generator_from_xml_file.is_castxml: patcher.update_unnamed_class(decls.values()) patcher.fix_calldef_decls( scanner_.calldefs(), scanner_.enums(), self.__cxx_std) decls = [inst for inst in iter(decls.values()) if self.__check(inst)] return decls, list(files.values())
def create(self, decl_headers=None): """ create and return the module for the extension - code creators tree root. :param decl_headers: If None the headers for the wrapped decls are automatically found. But you can pass a list of headers here to override that search. :rtype: :class:`code_creators.module_t` """ # Invoke the appropriate visit_*() method on all decls for decl in self.__decls: self.curr_decl = decl declarations.apply_visitor(self, decl) for operator in self.__free_operators: self._adopt_free_operator(operator) self._treat_smart_pointers() if self.__enable_indexing_suite: self._treat_indexing_suite() for creator in code_creators.make_flatten_generator(self.__extmodule): creator.target_configuration = self.__target_configuration # last action. self._append_user_code() add_include = self.__extmodule.add_include # add system headers system_headers = self.__extmodule.get_system_files(recursive=True, unique=True, language="c++") map(lambda header: add_include(header, user_defined=False, system=True), system_headers) # add user defined header files if decl_headers is None: decl_headers = declarations.declaration_files(self.__decls) map(lambda header: add_include(header, user_defined=False, system=False), decl_headers) self.__dependencies_manager.inform_user() return self.__extmodule
def visit_namespace(self ): self.__print_decl_header() if self.__recursive: for decl in self.__inst.declarations: prn = DeclPrinter( self.level + 1, self.__printDetails, self.__recursive ) prn.instance = decl declarations.apply_visitor( prn, decl )
def visit_free_function_type( self ): return_visitor = self.create_converter( self.user_type.return_type ) return_type = declarations.apply_visitor( return_visitor, self.user_type.return_type ) argtypes = [] for arg in self.user_type.arguments_types: arg_visitor = self.create_converter( arg ) argtypes.append( declarations.apply_visitor(arg_visitor, arg) ) return declarations.call_invocation.join( "ctypes.CFUNCTYPE", [return_type] + argtypes )
def print_members(members_type, members, curr_level): print ' ' * curr_level * self.INDENT_SIZE + members_type.ljust( self.JUSTIFY ) if self.__recursive: curr_level += 1 for member in members: prn = DeclPrinter( curr_level + 1, self.__printDetails, self.__recursive ) prn.instance = member declarations.apply_visitor( prn, member )
def visit_namespace(self): self.__print_decl_header() if self.__recursive: for decl in self.__inst.declarations: prn = DeclPrinter(self.level + 1, self.__printDetails, self.__recursive) prn.instance = decl declarations.apply_visitor(prn, decl)
def print_members(members_type, members, curr_level): print ' ' * curr_level * self.INDENT_SIZE + members_type.ljust( self.JUSTIFY) if self.__recursive: curr_level += 1 for member in members: prn = DeclPrinter(curr_level + 1, self.__printDetails, self.__recursive) prn.instance = member declarations.apply_visitor(prn, member)
def visit_free_function_type(self): return_visitor = self.create_converter(self.user_type.return_type) return_type = declarations.apply_visitor(return_visitor, self.user_type.return_type) argtypes = [] for arg in self.user_type.arguments_types: arg_visitor = self.create_converter(arg) argtypes.append(declarations.apply_visitor(arg_visitor, arg)) return declarations.call_invocation.join("ctypes.CFUNCTYPE", [return_type] + argtypes)
def print_declarations( decls, detailed=True, recursive=True, writer=sys.stdout.write ): """ Print decl tree rooted at each of the included nodes. decls - either a single decl or a list of decls. """ prn = decl_wrapper_printer_t(0, detailed, recursive, writer) if type(decls) is not list: decls = [decls] for d in decls: prn.level = 0 prn.instance = d declarations.apply_visitor(prn, d)
def print_declarations( decls, detailed=True, recursive=True, writer=sys.stdout.write ): """ print declarations tree :param decls: could be single :class:`pygccxml.declarations.declaration_t` object or list of them """ prn = decl_wrapper_printer_t(0, detailed, recursive, writer) if type(decls) is not list: decls = [decls] for d in decls: prn.level = 0 prn.instance = d declarations.apply_visitor(prn, d)
def visit_namespace(self ): if not self.__contains_exported( self.curr_decl ): return if self.global_ns is not self.curr_decl: ns_creator = code_creators.namespace_as_pyclass_t( self.curr_decl ) self.__namespace2pyclass[ self.curr_decl ] = ns_creator self.__namespace2pyclass[ self.curr_decl.parent ].adopt_creator( ns_creator ) ns = self.curr_decl for decl in self.curr_decl.decls( recursive=False, allow_empty=True ): if isinstance( decl, declarations.namespace_t) or self.__should_generate_code( decl ): self.curr_decl = decl declarations.apply_visitor( self, decl ) self.curr_decl = ns
def visit_class(self): self.__dependencies_manager.add_exported( self.curr_decl ) if self.curr_decl.opaque: cls_intro_cc = self.__class2introduction[ self.curr_decl ] cls_intro_cc.adopt_creator( code_creators.opaque_init_introduction_t( self.curr_decl ) ) else: class_ = self.curr_decl for decl in self.curr_decl.decls( recursive=False, allow_empty=True ): if isinstance( decl, declarations.variable_t ): continue #fields_definition_t class treats them if self.__should_generate_code( decl ): self.curr_decl = decl declarations.apply_visitor( self, decl ) self.curr_decl = class_
def visit_class(self): self.__dependencies_manager.add_exported(self.curr_decl) if self.curr_decl.opaque: cls_intro_cc = self.__class2introduction[self.curr_decl] cls_intro_cc.adopt_creator( code_creators.opaque_init_introduction_t(self.curr_decl)) else: class_ = self.curr_decl for decl in self.curr_decl.decls(recursive=False, allow_empty=True): if isinstance(decl, declarations.variable_t): continue #fields_definition_t class treats them if self.__should_generate_code(decl): self.curr_decl = decl declarations.apply_visitor(self, decl) self.curr_decl = class_
def visit_array( self ): item_visitor = self.create_converter( declarations.array_item_type(self.user_type) ) item_type = declarations.apply_visitor( item_visitor, item_visitor.user_type ) size = declarations.array_size( self.user_type ) if size == declarations.array_t.SIZE_UNKNOWN: size = 0 return "( %s * %d )" % ( item_type, size )
def visit_namespace(self): if not self.__contains_exported(self.curr_decl): return if self.global_ns is not self.curr_decl: ns_creator = code_creators.namespace_as_pyclass_t(self.curr_decl) self.__namespace2pyclass[self.curr_decl] = ns_creator self.__namespace2pyclass[self.curr_decl.parent].adopt_creator( ns_creator) ns = self.curr_decl for decl in self.curr_decl.decls(recursive=False, allow_empty=True): if isinstance(decl, declarations.namespace_t ) or self.__should_generate_code(decl): self.curr_decl = decl declarations.apply_visitor(self, decl) self.curr_decl = ns
def visit_declarated( self ): #TODO: the follwoing code removes typedefs if isinstance( self.user_type.declaration, declarations.typedef_t ): base_visitor = self.create_converter( self.user_type.declaration.type ) return declarations.apply_visitor( base_visitor, base_visitor.user_type ) else: return self.decl_formatter( self.user_type.declaration )
def create(self): """ create and return the module for the extension - code creators tree root :rtype: :class:`code_creators.module_t` """ # Invoke the appropriate visit_*() method on all decls ccc = self.curr_code_creator ccc.adopt_creator(code_creators.import_t('ctypes')) ccc.adopt_creator( code_creators.import_t(code_repository.ctypes_utils.file_name)) ccc.adopt_creator(code_creators.separator_t()) ccc.adopt_creator( code_creators.library_reference_t(self.__library_path)) ccc.adopt_creator( code_creators.name_mappings_t(self.__exported_symbols)) ccc.adopt_creator(code_creators.separator_t()) #adding namespaces global_ns_cc = code_creators.bookmark_t() ccc.adopt_creator(global_ns_cc) ccc.adopt_creator(self.__class_ccs) self.__namespace2pyclass[self.global_ns] = global_ns_cc #adding class introductions - special case because of hierarchy f = lambda cls: self.__should_generate_code( cls ) \ and isinstance( cls.parent, declarations.namespace_t ) ns_classes = self.global_ns.classes(f, recursive=True, allow_empty=True) ns_classes = sort_algorithms.sort_classes(ns_classes, include_vars=True) for class_ in ns_classes: self.__add_class_introductions(self.__class_ccs, class_) ccc.adopt_creator(self.__class_defs_ccs) ccc.adopt_creator(code_creators.separator_t()) ccc.adopt_creator(self.__typedefs_ccs) declarations.apply_visitor(self, self.curr_decl) self.__dependencies_manager.inform_user() return self.module
def visit_declarated(self): #TODO: the follwoing code removes typedefs if isinstance(self.user_type.declaration, declarations.typedef_t): base_visitor = self.create_converter( self.user_type.declaration.type) return declarations.apply_visitor(base_visitor, base_visitor.user_type) else: return self.decl_formatter(self.user_type.declaration)
def visit_array(self): item_visitor = self.create_converter( declarations.array_item_type(self.user_type)) item_type = declarations.apply_visitor(item_visitor, item_visitor.user_type) size = declarations.array_size(self.user_type) if size == declarations.array_t.SIZE_UNKNOWN: size = 0 return "( %s * %d )" % (item_type, size)
def __parse_xml_file(self, xml_file): scanner_ = scanner_t(xml_file, self.__decl_factory, self.__config) scanner_.read() decls = scanner_.declarations() types = scanner_.types() files = {} for file_id, file_path in scanner_.files().items(): files[file_id] = self.__produce_full_file(file_path) linker_ = linker.linker_t( decls=decls, types=types, access=scanner_.access(), membership=scanner_.members(), files=files) for type_ in list(types.values()): # I need this copy because internaly linker change types collection linker_.instance = type_ declarations.apply_visitor(linker_, type_) for decl in decls.values(): linker_.instance = decl declarations.apply_visitor(linker_, decl) bind_aliases(iter(decls.values())) # Join declarations if self.__join_decls: for ns in iter(decls.values()): if isinstance(ns, declarations.namespace_t): self.join_declarations(ns) # some times gccxml report typedefs defined in no namespace # it happens for example in next situation # template< typename X> # void ddd(){ typedef typename X::Y YY;} # if I will fail on this bug next time, the right way to fix it may be # different patcher.fix_calldef_decls(scanner_.calldefs(), scanner_.enums(), self.__cxx_std) decls = [ inst for inst in iter( decls.values()) if isinstance( inst, declarations.namespace_t) and not inst.parent] return decls, list(files.values())
def create(self ): """ create and return the module for the extension - code creators tree root :rtype: :class:`code_creators.module_t` """ # Invoke the appropriate visit_*() method on all decls ccc = self.curr_code_creator ccc.adopt_creator( code_creators.import_t( 'ctypes' ) ) ccc.adopt_creator( code_creators.import_t( code_repository.ctypes_utils.file_name ) ) ccc.adopt_creator( code_creators.separator_t() ) ccc.adopt_creator( code_creators.library_reference_t( self.__library_path ) ) ccc.adopt_creator( code_creators.name_mappings_t( self.__exported_symbols ) ) ccc.adopt_creator( code_creators.separator_t() ) #adding namespaces global_ns_cc = code_creators.bookmark_t() ccc.adopt_creator( global_ns_cc ) ccc.adopt_creator( self.__class_ccs ) self.__namespace2pyclass[ self.global_ns ] = global_ns_cc #adding class introductions - special case because of hierarchy f = lambda cls: self.__should_generate_code( cls ) \ and isinstance( cls.parent, declarations.namespace_t ) ns_classes = self.global_ns.classes( f, recursive=True, allow_empty=True) ns_classes = sort_algorithms.sort_classes( ns_classes, include_vars=True ) for class_ in ns_classes: self.__add_class_introductions( self.__class_ccs, class_ ) ccc.adopt_creator( self.__class_defs_ccs ) ccc.adopt_creator( code_creators.separator_t() ) ccc.adopt_creator( self.__typedefs_ccs ) declarations.apply_visitor( self, self.curr_decl ) self.__dependencies_manager.inform_user() return self.module
def visit_reference( self ): no_ref = declarations.remove_const( declarations.remove_reference( self.user_type ) ) if declarations.is_same( declarations.char_t(), no_ref ): return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ref ): return "ctypes.c_wchar_p" elif declarations.is_same( declarations.void_t(), no_ref ): return "ctypes.c_void_p" else: base_visitor = self.create_converter( self.user_type.base ) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type ) return "ctypes.POINTER( %s )" % internal_type_str
def create(self, decl_headers=None): """ create and return the module for the extension - code creators tree root. :param decl_headers: If None the headers for the wrapped decls are automatically found. But you can pass a list of headers here to override that search. :rtype: :class:`code_creators.module_t` """ # Invoke the appropriate visit_*() method on all decls for decl in self.__decls: self.curr_decl = decl declarations.apply_visitor(self, decl) for operator in self.__free_operators: self._adopt_free_operator(operator) self._treat_smart_pointers() if self.__enable_indexing_suite: self._treat_indexing_suite() for creator in code_creators.make_flatten_generator(self.__extmodule): creator.target_configuration = self.__target_configuration #last action. self._append_user_code() add_include = self.__extmodule.add_include #add system headers system_headers = self.__extmodule.get_system_files(recursive=True, unique=True, language='c++') map( lambda header: add_include(header, user_defined=False, system=True ), system_headers) #add user defined header files if decl_headers is None: decl_headers = declarations.declaration_files(self.__decls) map( lambda header: add_include( header, user_defined=False, system=False), decl_headers) self.__dependencies_manager.inform_user() return self.__extmodule
def visit_reference(self): no_ref = declarations.remove_const( declarations.remove_reference(self.user_type)) if declarations.is_same(declarations.char_t(), no_ref): return "ctypes.c_char_p" elif declarations.is_same(declarations.wchar_t(), no_ref): return "ctypes.c_wchar_p" elif declarations.is_same(declarations.void_t(), no_ref): return "ctypes.c_void_p" else: base_visitor = self.create_converter(self.user_type.base) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type) return "ctypes.POINTER( %s )" % internal_type_str
def visit_pointer( self ): no_ptr = declarations.remove_const( declarations.remove_pointer( self.user_type ) ) if declarations.is_same( declarations.char_t(), no_ptr ) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ptr ) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_wchar_p" elif declarations.is_same( declarations.void_t(), no_ptr ): return "ctypes.c_void_p" else: base_visitor = self.create_converter( self.user_type.base ) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type ) if declarations.is_calldef_pointer( self.user_type ): return internal_type_str else: return "ctypes.POINTER( %s )" % internal_type_str
def visit_pointer(self): no_ptr = declarations.remove_const( declarations.remove_pointer(self.user_type)) if declarations.is_same( declarations.char_t(), no_ptr) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_char_p" elif declarations.is_same( declarations.wchar_t(), no_ptr) and self.treat_char_ptr_as_binary_data == False: return "ctypes.c_wchar_p" elif declarations.is_same(declarations.void_t(), no_ptr): return "ctypes.c_void_p" else: base_visitor = self.create_converter(self.user_type.base) internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type) if declarations.is_calldef_pointer(self.user_type): return internal_type_str else: return "ctypes.POINTER( %s )" % internal_type_str
def visit_class(self ): if self.curr_decl.indexing_suite: self.__types_db.update_containers( self.curr_decl ) return #it will be exposed later, using other code creators self.__dependencies_manager.add_exported( self.curr_decl ) cls_decl = self.curr_decl cls_parent_cc = self.curr_code_creator exportable_members = self.curr_decl.get_exportable_members(sort_algorithms.sort) wrapper = None cls_cc = None if cls_decl.introduces_new_scope: cls_cc = code_creators.class_t( class_inst=self.curr_decl ) else: cls_cc = self.curr_code_creator if self.curr_decl.is_wrapper_needed(): wrapper = code_creators.class_wrapper_t( declaration=self.curr_decl , class_creator=cls_cc ) cls_cc.wrapper = wrapper cls_cc.associated_decl_creators.append( wrapper ) #insert wrapper before module body if isinstance( self.curr_decl.parent, declarations.class_t ): #we deal with internal class self.curr_code_creator.wrapper.adopt_creator( wrapper ) else: self.__extmodule.adopt_declaration_creator( wrapper ) #next constructors are not present in code, but compiler generated #Boost.Python requiers them to be declared in the wrapper class noncopyable_vars = self.curr_decl.find_noncopyable_vars() copy_constr = self.curr_decl.find_copy_constructor() if not self.curr_decl.noncopyable and copy_constr and copy_constr.is_artificial: cccc = code_creators.copy_constructor_wrapper_t( constructor=copy_constr) wrapper.adopt_creator( cccc ) trivial_constr = self.curr_decl.find_trivial_constructor() if trivial_constr and trivial_constr.is_artificial and not noncopyable_vars: tcons = code_creators.null_constructor_wrapper_t( constructor=trivial_constr ) wrapper.adopt_creator( tcons ) exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc ) if cls_decl.introduces_new_scope: cls_parent_cc.adopt_creator( cls_cc ) self.curr_code_creator = cls_cc if cls_decl.expose_this: cls_cc.adopt_creator( code_creators.expose_this_t( cls_decl ) ) if cls_decl.expose_sizeof: cls_cc.adopt_creator( code_creators.expose_sizeof_t( cls_decl ) ) for decl in exportable_members: if decl in exposed: continue self.curr_decl = decl declarations.apply_visitor( self, decl ) for redefined_func in cls_decl.redefined_funcs(): if isinstance( redefined_func, declarations.operator_t ): continue self.curr_decl = redefined_func declarations.apply_visitor( self, redefined_func ) #all static_methods_t should be moved to the end #better approach is to move them after last def of relevant function static_methods = [creator for creator in cls_cc.creators if isinstance( creator, code_creators.static_method_t )] for static_method in static_methods: cls_cc.remove_creator( static_method ) cls_cc.adopt_creator( static_method ) if cls_decl.exception_translation_code: translator = code_creators.exception_translator_t( cls_decl ) self.__extmodule.adopt_declaration_creator( translator ) cls_cc.associated_decl_creators.append( translator ) translator_register \ = code_creators.exception_translator_register_t( cls_decl, translator ) cls_cc.adopt_creator( translator_register ) for property_def in cls_decl.properties: cls_cc.adopt_creator( code_creators.property_t(property_def) ) if wrapper and cls_decl.destructor_code: destructor = code_creators.destructor_wrapper_t( class_=cls_decl ) wrapper.adopt_creator( destructor ) for fc in cls_decl.fake_constructors: if self.__fc_manager.should_generate_code( fc ): self.__dependencies_manager.add_exported( fc ) cls_cc.adopt_creator( code_creators.make_constructor_t( fc ) ) self.curr_decl = cls_decl self.curr_code_creator = cls_parent_cc
def visit_const(self): base_visitor = self.create_converter(self.user_type.base) return declarations.apply_visitor(base_visitor, base_visitor.user_type)
def as_ctype(type_, treat_char_ptr_as_binary_data=False): v = type_converter_t(type_, treat_char_ptr_as_binary_data) return declarations.apply_visitor(v, type_)
def as_ctype( type_, treat_char_ptr_as_binary_data=False): v = type_converter_t( type_, treat_char_ptr_as_binary_data ) return declarations.apply_visitor( v, type_ )
def visit_const( self ): base_visitor = self.create_converter( self.user_type.base ) return declarations.apply_visitor( base_visitor, base_visitor.user_type )
def visit_class(self ): self.__dependencies_manager.add_exported( self.curr_decl ) cls_decl = self.curr_decl cls_parent_cc = self.curr_code_creator exportable_members = self.curr_decl.get_exportable_members(sort_algorithms.sort) wrapper = None cls_cc = code_creators.class_t( class_inst=self.curr_decl ) if self.curr_decl.is_wrapper_needed(): wrapper = code_creators.class_wrapper_t( declaration=self.curr_decl , class_creator=cls_cc ) cls_cc.wrapper = wrapper cls_cc.associated_decl_creators.append( wrapper ) #insert wrapper before module body if isinstance( self.curr_decl.parent, declarations.class_t ): #we deal with internal class self.curr_code_creator.wrapper.adopt_creator( wrapper ) else: self.__extmodule.adopt_declaration_creator( wrapper ) #next constructors are not present in code, but compiler generated #Boost.Python requiers them to be declared in the wrapper class if '0.9' in self.curr_decl.compiler: copy_constr = self.curr_decl.find_copy_constructor() add_to_wrapper = False if declarations.has_copy_constructor( self.curr_decl ): #find out whether user or compiler defined it if self.curr_decl.noncopyable: add_to_wrapper = False elif not copy_constr: add_to_wrapper = True #compiler defined will not be exposed manually later elif copy_constr.is_artificial: add_to_wrapper = True #compiler defined will not be exposed manually later if add_to_wrapper: cccc = code_creators.copy_constructor_wrapper_t( class_=self.curr_decl) wrapper.adopt_creator( cccc ) trivial_constr = self.curr_decl.find_trivial_constructor() add_to_wrapper = False if declarations.has_trivial_constructor( self.curr_decl ): if not trivial_constr: add_to_wrapper = True elif trivial_constr.is_artificial: add_to_wrapper = True if add_to_wrapper: tcons = code_creators.null_constructor_wrapper_t( class_=self.curr_decl ) wrapper.adopt_creator( tcons ) else: if declarations.has_copy_constructor( self.curr_decl ): copy_constr = self.curr_decl.find_copy_constructor() if not self.curr_decl.noncopyable and copy_constr.is_artificial: cccc = code_creators.copy_constructor_wrapper_t( class_=self.curr_decl) wrapper.adopt_creator( cccc ) null_constr = self.curr_decl.find_trivial_constructor() if null_constr and null_constr.is_artificial: #this constructor is not going to be exposed tcons = code_creators.null_constructor_wrapper_t( class_=self.curr_decl ) wrapper.adopt_creator( tcons ) exposed = self.expose_overloaded_mem_fun_using_macro( cls_decl, cls_cc ) cls_parent_cc.adopt_creator( cls_cc ) self.curr_code_creator = cls_cc for decl in exportable_members: if decl in exposed: continue self.curr_decl = decl declarations.apply_visitor( self, decl ) for redefined_func in cls_decl.redefined_funcs(): if isinstance( redefined_func, declarations.operator_t ): continue self.curr_decl = redefined_func declarations.apply_visitor( self, redefined_func ) #all static_methods_t should be moved to the end #better approach is to move them after last def of relevant function static_methods = filter( lambda creator: isinstance( creator, code_creators.static_method_t ) , cls_cc.creators ) for static_method in static_methods: cls_cc.remove_creator( static_method ) cls_cc.adopt_creator( static_method ) if cls_decl.exception_translation_code: translator = code_creators.exception_translator_t( cls_decl ) self.__extmodule.adopt_declaration_creator( translator ) cls_cc.associated_decl_creators.append( translator ) translator_register \ = code_creators.exception_translator_register_t( cls_decl, translator ) cls_cc.adopt_creator( translator_register ) for property_def in cls_decl.properties: cls_cc.adopt_creator( code_creators.property_t(property_def) ) self.curr_decl = cls_decl self.curr_code_creator = cls_parent_cc