[pygccxml-commit] SF.net SVN: pygccxml:[1511] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-12-28 13:17:02
|
Revision: 1511 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1511&view=rev Author: roman_yakovenko Date: 2008-12-28 13:16:57 +0000 (Sun, 28 Dec 2008) Log Message: ----------- add handling for "C" functions Modified Paths: -------------- pygccxml_dev/pygccxml/msvc/common_utils.py pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/algorithm.py pyplusplus_dev/pyplusplus/code_creators/declaration_based.py pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper_printer.py pyplusplus_dev/pyplusplus/module_builder/ctypes_builder.py pyplusplus_dev/unittests/ctypes_pof_tester.py pyplusplus_dev/unittests/data/ctypes_pof/mydll.cpp pyplusplus_dev/unittests/data/ctypes_pof/mydll.h Added Paths: ----------- pyplusplus_dev/pyplusplus/code_creators/ctypes_formatter.py pyplusplus_dev/pyplusplus/code_creators/function_definition.py Modified: pygccxml_dev/pygccxml/msvc/common_utils.py =================================================================== --- pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pygccxml_dev/pygccxml/msvc/common_utils.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -262,5 +262,5 @@ % fname ) @staticmethod - def is_c_function( decl, blob, undecorated_blob ): - return decl.name == blob == undecorated_blob + def is_c_function( decl, blob ): + return decl.name == blob Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -153,3 +153,4 @@ from fields_definition import fields_definition_t from embedded_code_repository import embedded_code_repository_t from methods_definition import methods_definition_t +from function_definition import c_function_definition_t Modified: pyplusplus_dev/pyplusplus/code_creators/algorithm.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/algorithm.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/pyplusplus/code_creators/algorithm.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -11,7 +11,7 @@ from pyplusplus.decl_wrappers.algorithm import * -import types +import types import namespace def _make_flatten_list( creator_or_creators ): @@ -69,14 +69,14 @@ This class is used as container for different find algorithms. """ "creator_finder - this class used as namespace" - + @staticmethod def find_by_declaration( declaration_matcher, where, recursive=True ): - """Finds code creator by declaration. - declaration_matcher should be callable, that takes single argument + """Finds code creator by declaration. + declaration_matcher should be callable, that takes single argument declaration, and returns True or False where - code creator or list of code creators - This function returns a list of all relevant code creators + This function returns a list of all relevant code creators """ import declaration_based #prevent cyclic import search_area = where @@ -85,14 +85,14 @@ return filter( lambda inst: isinstance( inst, declaration_based.declaration_based_t ) \ and declaration_matcher( inst.declaration ) , search_area ) - + @staticmethod def find_by_declaration_single( declaration_matcher, where, recursive=True ): answer = creator_finder.find_by_declaration( declaration_matcher, where, recursive ) if len( answer ) == 1: return answer[0] return None - + @staticmethod def find_by_class_instance( what, where, recursive=True ): search_area = where @@ -101,4 +101,15 @@ return filter( lambda inst: isinstance( inst, what ), search_area ) def make_id_creator( code_creator ): - return lambda decl_string: create_identifier( code_creator, decl_string ) + return lambda decl_string: create_identifier( code_creator, decl_string ) + +def complete_py_name( decl ): + aliases = [] + current = decl + while current: + aliases.append( current.alias ) + current = current.parent + del aliases[-1] # :: from the global namespace + aliases.reverse() + return '.'.join( aliases ) + Added: pyplusplus_dev/pyplusplus/code_creators/ctypes_formatter.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/ctypes_formatter.py (rev 0) +++ pyplusplus_dev/pyplusplus/code_creators/ctypes_formatter.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -0,0 +1,145 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +""" +defines types visitor class interface +""" + +import algorithm +from pygccxml import declarations + +class type_converter_t(declarations.type_visitor_t): + """ + types visitor interface + + All functions within this class should be redefined in derived classes. + """ + def __init__(self, type_, decl_formatter): + declarations.type_visitor_t.__init__(self) + self.user_type = type_ + self.decl_formatter = decl_formatter + + def visit_void( self ): + return "None" + + def visit_char( self ): + return "ctypes.c_char" + + def visit_unsigned_char( self ): + return "ctypes.c_ubyte" + + def visit_signed_char( self ): + return "ctypes.c_byte" + + def visit_wchar( self ): + return "ctypes.c_wchar" + + def visit_short_int( self ): + return "ctypes.c_short" + + def visit_short_unsigned_int( self ): + return "ctypes.c_ushort" + + def visit_bool( self ): + return "ctypes.c_bool" + + def visit_int( self ): + return "ctypes.c_int" + + def visit_unsigned_int( self ): + return "ctypes.c_uint" + + def visit_long_int( self ): + return "ctypes.c_long" + + def visit_long_unsigned_int( self ): + return "ctypes.c_ulong" + + def visit_long_long_int( self ): + return "ctypes.c_longlong" + + def visit_long_long_unsigned_int( self ): + return "ctypes.c_ulonglong" + + def visit_float( self ): + return "ctypes.c_float" + + def visit_double( self ): + return "ctypes.c_double" + + def visit_long_double( self ): + return "ctypes.c_longdouble" + + #skip complex and jxxx types + + def visit_volatile( self ): + base_visitor = type_converter_t( self.user_type.base, self.decl_formatter ) + return declarations.apply_visitor( base_visitor, base_visitor.user_type ) + + def visit_const( self ): + base_visitor = type_converter_t( self.user_type.base, self.decl_formatter ) + return declarations.apply_visitor( base_visitor, base_visitor.user_type ) + + def visit_pointer( self ): + no_ptr = declarations.remove_const( declarations.remove_pointer( self.user_type ) ) + if declarations.is_same( declarations.char_t(), no_ptr ): + return "ctypes.c_char_p" + elif declarations.is_same( declarations.wchar_t(), no_ptr ): + return "ctypes.c_wchar_p" + elif declarations.is_same( declarations.void_t(), no_ptr ): + return "ctypes.c_void_p" + else: + base_visitor = type_converter_t( self.user_type.base, self.decl_formatter ) + internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type ) + return "ctypes.POINTER( %s )" % internal_type_str + + 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 = type_converter_t( self.user_type.base, self.decl_formatter ) + internal_type_str = declarations.apply_visitor( base_visitor, base_visitor.user_type ) + return "ctypes.POINTER( %s )" % internal_type_str + + def visit_array( self ): + item_visitor = type_converter_t( declarations.array_item_type(self.user_type) + , self.decl_formatter ) + 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_free_function_type( self ): + return_visitor = type_converter_t( self.return_type, self.decl_formatter ) + return_type = declarations.apply_visitor(return_visitor, self.return_type) + argtypes = [] + for arg in self.user_type.arguments_types: + arg_visitor = type_converter_t( arg, self.decl_formatter ) + argtypes.append( declarations.apply_visitor(arg_visitor, arg) ) + return declarations.call_invocation.join( "ctypes.CFUNCTYPE", [return_type] + argtypes ) + + #~ def visit_member_function_type( self ): + #~ raise NotImplementedError() + + #~ def visit_member_variable_type( self ): + #~ raise NotImplementedError() + + def visit_declarated( self ): + return self.decl_formatter( self.user_type.declaration ) + + def visit_restrict( self ): + base_visitor = type_converter_t( self.user_type.base, self.decl_formatter ) + return declarations.apply_visitor( base_visitor, base_visitor.user_type ) + +def as_ctype( type_, decl_formatter=algorithm.complete_py_name ): + v = type_converter_t( type_, decl_formatter ) + return declarations.apply_visitor( v, type_ ) + Property changes on: pyplusplus_dev/pyplusplus/code_creators/ctypes_formatter.py ___________________________________________________________________ Added: svn:mergeinfo + Modified: pyplusplus_dev/pyplusplus/code_creators/declaration_based.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/declaration_based.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/pyplusplus/code_creators/declaration_based.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -48,14 +48,7 @@ @utils.cached def complete_py_name( self ): - aliases = [] - current = self.declaration - while current: - aliases.append( current.alias ) - current = current.parent - del aliases[-1] # :: from the global namespace - aliases.reverse() - return '.'.join( aliases ) + return algorithm.complete_py_name( self.declaration ) @property def decl_identifier( self ): Added: pyplusplus_dev/pyplusplus/code_creators/function_definition.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/function_definition.py (rev 0) +++ pyplusplus_dev/pyplusplus/code_creators/function_definition.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -0,0 +1,60 @@ +# Copyright 2004-2008 Roman Yakovenko. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os +import code_creator +import ctypes_formatter +import declaration_based +from pygccxml import declarations + +""" +BSCGetBaseArray = _libraries['msbsc70.dll'].BSCGetBaseArray +BSCGetBaseArray.restype = BOOL +BSCGetBaseArray.argtypes = [POINTER(Bsc), IINST, POINTER(POINTER(IINST)), POINTER(ULONG)] + +""" + +class c_function_definition_t(code_creator.code_creator_t, declaration_based.declaration_based_t): + def __init__( self, free_fun ): + code_creator.code_creator_t.__init__(self) + declaration_based.declaration_based_t.__init__( self, free_fun ) + + @property + def ftype( self ): + return self.declaration.function_type() + + def __join_args( self, args ): + args_str = '' + arg_separator = ', ' + if 1 == len( args ): + args_str = ' ' + args[0] + ' ' + else: + args_str = ' ' + arg_separator.join( args ) + ' ' + return '[%s]' % args_str + + + def _create_impl(self): + result = [] + result.append( '#%s' % self.undecorated_decl_name ) + result.append( '%(alias)s = %(library_var_name)s.%(alias)s' + % dict( alias=self.declaration.alias + , library_var_name=self.top_parent.library_var_name ) ) + + if not declarations.is_void( self.ftype.return_type ): + result.append( '%(alias)s.restype = %(restype)s' + % dict( alias=self.declaration.alias + , restype=ctypes_formatter.as_ctype( self.ftype.return_type ) ) ) + + if self.ftype.arguments_types: + tmp = [] + tmp.append( '%(alias)s.argtypes = ' % dict( alias=self.declaration.alias ) ) + args = map( ctypes_formatter.as_ctype, self.ftype.arguments_types ) + tmp.append( self.__join_args( args ) ) + result.append( ''.join( tmp ) ) + + return os.linesep.join( result ) + + def _get_system_headers_impl( self ): + return [] Modified: pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py =================================================================== --- pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -5,11 +5,12 @@ import sort_algorithms import dependencies_manager +from pygccxml import msvc +from pyplusplus import _logging_ from pygccxml import declarations from pyplusplus import decl_wrappers from pyplusplus import code_creators from pyplusplus import code_repository -from pyplusplus import _logging_ ACCESS_TYPES = declarations.ACCESS_TYPES VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES @@ -163,6 +164,10 @@ def visit_free_function( self ): self.__dependencies_manager.add_exported( self.curr_decl ) + if self.curr_decl.name in self.__exported_symbols \ + and self.curr_decl.name == self.__exported_symbols[ self.curr_decl.name ]: + #we deal with c function + self.curr_code_creator.adopt_creator( code_creators.c_function_definition_t( self.curr_decl ) ) def visit_free_operator( self ): self.__dependencies_manager.add_exported( self.curr_decl ) Modified: pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper_printer.py =================================================================== --- pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper_printer.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/pyplusplus/decl_wrappers/decl_wrapper_printer.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -29,12 +29,12 @@ if not self.print_details: return intend_txt = ' ' * (self.level+1) * self.INDENT_SIZE - self.writer( intend_txt + "Alias: " + self.instance.alias + os.linesep ) - self.writer( intend_txt + "Ignore: " + str( self.instance.ignore ) + os.linesep ) + self.writer( intend_txt + "alias: " + self.instance.alias + os.linesep ) + self.writer( intend_txt + "ignore: " + str( self.instance.ignore ) + os.linesep ) if not self.instance.ignore: msgs = self.instance.readme() if msgs: - self.writer( intend_txt + "ReadMe: " + os.linesep ) + self.writer( intend_txt + "readme: " + os.linesep ) more_intend_txt = ' ' * (self.level+2) * self.INDENT_SIZE for msg in msgs: self.writer( more_intend_txt + msg + os.linesep ) @@ -43,13 +43,19 @@ if not self.print_details: return self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Call policies: " + str(self.instance.call_policies) + os.linesep ) + + "call policies: " + str(self.instance.call_policies) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Use keywords: " + str(self.instance.use_keywords) + os.linesep ) + + "use keywords: " + str(self.instance.use_keywords) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Use signature: " + str(self.instance.create_with_signature) + os.linesep ) + + "use signature: " + str(self.instance.create_with_signature) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Use default arguments: " + str(self.instance.use_default_arguments) + os.linesep ) + + "use default arguments: " + str(self.instance.use_default_arguments) + os.linesep ) + try: + from pygccxml import msvc + self.writer( ' ' * (self.level+1) * self.INDENT_SIZE + + "undecorated decl: " + msvc.undecorate_decl(self.instance) + os.linesep ) + except: + pass def visit_member_function( self ): super( decl_wrapper_printer_t, self ).visit_member_function() @@ -85,22 +91,22 @@ def visit_class(self ): super( decl_wrapper_printer_t, self ).visit_class() self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Expose using scope: " + str(self.instance.always_expose_using_scope) + os.linesep ) + + "expose using scope: " + str(self.instance.always_expose_using_scope) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Redefine operators: " + str(self.instance.redefine_operators) + os.linesep ) + + "redefine operators: " + str(self.instance.redefine_operators) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Held type: " + str(self.instance.held_type) + os.linesep ) + + "held type: " + str(self.instance.held_type) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Use noncopyable: " + str(self.instance.noncopyable) + os.linesep ) + + "use noncopyable: " + str(self.instance.noncopyable) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Class wrapper alias: " + str(self.instance.wrapper_alias) + os.linesep ) + + "class wrapper alias: " + str(self.instance.wrapper_alias) + os.linesep ) def visit_enumeration(self): super( decl_wrapper_printer_t, self ).visit_enumeration() self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Enumeration value aliases: " + str(self.instance.value_aliases) + os.linesep ) + + "enumeration value aliases: " + str(self.instance.value_aliases) + os.linesep ) self.writer( ' ' * (self.level+1) * self.INDENT_SIZE - + "Enumeration export values: " + str(self.instance.export_values) + os.linesep ) + + "enumeration export values: " + str(self.instance.export_values) + os.linesep ) def visit_namespace(self ): super( decl_wrapper_printer_t, self ).visit_namespace() Modified: pyplusplus_dev/pyplusplus/module_builder/ctypes_builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/ctypes_builder.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/pyplusplus/module_builder/ctypes_builder.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -80,8 +80,10 @@ def __include_declarations( self ): self.global_ns.exclude() - undecorated = set( self.__blob2undecorated.values() ) - is_exported = lambda d: msvc.undecorate_decl( d ) in undecorated + b2u = self.__blob2undecorated + undecorated = set( b2u.values() ) + is_exported = lambda d: msvc.undecorate_decl( d ) in undecorated \ + or d.name in b2u and b2u[d.name] == d.name #treatment of C functions included_decls = set() included_decls.update( self.global_ns.calldefs( is_exported, allow_empty=True, recursive=True ) ) Modified: pyplusplus_dev/unittests/ctypes_pof_tester.py =================================================================== --- pyplusplus_dev/unittests/ctypes_pof_tester.py 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/unittests/ctypes_pof_tester.py 2008-12-28 13:16:57 UTC (rev 1511) @@ -20,14 +20,15 @@ def test(self): mb = ctypes_module_builder_t( [self.header], self.symbols_file, autoconfig.cxx_parsers_cfg.gccxml ) - #~ mb.global_ns.include() + #~ mb.print_declarations() mb.build_code_creator( self.symbols_file ) mb.write_module( os.path.join( autoconfig.build_directory, self.module_name + '.py' ) ) #mb.code_creator.create() sys.path.append( autoconfig.build_directory ) import ctypes_pof + print ctypes_pof.identity( 23 ) + self.failUnless( ctypes_pof.identity( 23 ) == 23 ) - def create_suite(): suite = unittest.TestSuite() if 'win' in sys.platform: Modified: pyplusplus_dev/unittests/data/ctypes_pof/mydll.cpp =================================================================== --- pyplusplus_dev/unittests/data/ctypes_pof/mydll.cpp 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/unittests/data/ctypes_pof/mydll.cpp 2008-12-28 13:16:57 UTC (rev 1511) @@ -47,6 +47,8 @@ void do_smth( number_aptr_t& ){ } +int identity( int i){ return i;} + BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved Modified: pyplusplus_dev/unittests/data/ctypes_pof/mydll.h =================================================================== --- pyplusplus_dev/unittests/data/ctypes_pof/mydll.h 2008-12-28 12:12:16 UTC (rev 1510) +++ pyplusplus_dev/unittests/data/ctypes_pof/mydll.h 2008-12-28 13:16:57 UTC (rev 1511) @@ -26,3 +26,9 @@ typedef std::auto_ptr< pof::number_t > number_aptr_t; void __declspec(dllexport) do_smth( number_aptr_t& ); + +extern "C"{ + +int __declspec(dllexport) identity( int ); + +} \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |