[pygccxml-commit] SF.net SVN: pygccxml:[1515] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2008-12-30 11:27:04
|
Revision: 1515 http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1515&view=rev Author: roman_yakovenko Date: 2008-12-30 11:27:00 +0000 (Tue, 30 Dec 2008) Log Message: ----------- another set of changes for ctypes code generator Modified Paths: -------------- pygccxml_dev/unittests/autoconfig.py pyplusplus_dev/pyplusplus/code_creators/__init__.py pyplusplus_dev/pyplusplus/code_creators/compound.py pyplusplus_dev/pyplusplus/code_creators/function_definition.py pyplusplus_dev/pyplusplus/code_creators/methods_definition.py pyplusplus_dev/pyplusplus/code_repository/ctypes_utils.py pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py pyplusplus_dev/unittests/autoconfig.py pyplusplus_dev/unittests/ctypes_pof_tester.py Modified: pygccxml_dev/unittests/autoconfig.py =================================================================== --- pygccxml_dev/unittests/autoconfig.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pygccxml_dev/unittests/autoconfig.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -28,7 +28,7 @@ print 'unittests will run on DEVELOPMENT version' compiler = pygccxml.utils.native_compiler.get_gccxml_compiler() - +compiler = 'msvc71' print 'GCCXML configured to simulate compiler ', compiler pygccxml.declarations.class_t.USE_DEMANGLED_AS_NAME = True Modified: pyplusplus_dev/pyplusplus/code_creators/__init__.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/pyplusplus/code_creators/__init__.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -155,12 +155,11 @@ from mem_fun_introduction import vmem_fun_introduction_t from mem_fun_introduction import init_introduction_t from mem_fun_introduction import del_introduction_t - - 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 function_definition_t from function_definition import init_definition_t -from function_definition import multi_init_definition_t +from function_definition import multi_method_definition_t from function_definition import del_definition_t +from function_definition import mem_fun_definition_t Modified: pyplusplus_dev/pyplusplus/code_creators/compound.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/compound.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/pyplusplus/code_creators/compound.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -87,3 +87,18 @@ if unique: files = self.unique_headers( files ) return files + + def find_by_creator_class( self, class_, unique=True, recursive=False ): + #I will add missing functionality later + assert recursive == False + found = filter( lambda cc: isinstance( cc, class_ ), self.creators ) + if not found: + return None + elif 1 == len( found ): + return found + else: + if unique: + raise LookupError( "Too many creators(%d) of type %s were found." + % ( len( found ), class_.__name__ ) ) + else: + return found Modified: pyplusplus_dev/pyplusplus/code_creators/function_definition.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/function_definition.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/pyplusplus/code_creators/function_definition.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -12,105 +12,166 @@ #TODO - unable to call C function, if dll was loaded as CPPDLL -def join_arguments( args ): - args_str = '' - arg_separator = ', ' - if 1 == len( args ): - args_str = ' ' + args[0] + ' ' - else: - args_str = ' ' + arg_separator.join( args ) + ' ' - return '[%s]' % args_str -class function_definition_t(code_creator.code_creator_t, declaration_based.declaration_based_t): - def __init__( self, free_fun ): +class METHOD_MODE: + STAND_ALONE = "stand alone" + MULTI_METHOD = "multi method" + all = [ STAND_ALONE, MULTI_METHOD ] + + +def get_mem_fun_factory_var_name( cc ): + import methods_definition + while not isinstance( cc, methods_definition.methods_definition_t ): + cc = cc.parent + return cc.mem_fun_factory_var_name + +class callable_definition_t(code_creator.code_creator_t, declaration_based.declaration_based_t): + def __init__( self, callable ): code_creator.code_creator_t.__init__(self) - declaration_based.declaration_based_t.__init__( self, free_fun ) + declaration_based.declaration_based_t.__init__( self, callable ) + self.__mode = METHOD_MODE.STAND_ALONE + def __get_mode(self): + return self.__mode + def __set_mode(self, new_mode): + assert new_mode in METHOD_MODE.all + self.__mode = new_mode + method_mode = property( __get_mode, __set_mode ) + @property def ftype( self ): return self.declaration.function_type() + def join_arguments( 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 + + @property + def mem_fun_factory_var_name( self ): + return get_mem_fun_factory_var_name( self ) + + def restype_code(self): + if not declarations.is_void( self.ftype.return_type ): + return ctypes_formatter.as_ctype( self.ftype.return_type ) + else: + return '' + + def argtypes_code(self): + if not self.ftype.arguments_types: + return '' + args = map( ctypes_formatter.as_ctype, self.ftype.arguments_types ) + return self.join_arguments( args ) + + def _get_system_headers_impl( self ): + return [] + + +class function_definition_t(callable_definition_t): + def __init__( self, free_fun ): + callable_definition_t.__init__( self, free_fun ) + def _create_impl(self): result = [] result.append( '%(alias)s = getattr( %(library_var_name)s, %(library_var_name)s.undecorated_names["%(undecorated_decl_name)s"] )' % dict( alias=self.declaration.alias , library_var_name=self.top_parent.library_var_name , undecorated_decl_name=self.undecorated_decl_name) ) - - if not declarations.is_void( self.ftype.return_type ): + restype = self.restype_code() + if restype: result.append( '%(alias)s.restype = %(restype)s' - % dict( alias=self.declaration.alias - , restype=ctypes_formatter.as_ctype( self.ftype.return_type ) ) ) + % dict( alias=self.declaration.alias, restype=restype ) ) - 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( join_arguments( args ) ) - result.append( ''.join( tmp ) ) + argtypes = self.argtypes_code() + if argtypes: + result.append( '%(alias)s.argtypes = %(argtypes)s' + % dict( alias=self.declaration.alias, argtypes=argtypes ) ) return os.linesep.join( result ) - def _get_system_headers_impl( self ): - return [] - -def mem_fun_factory_var_name( cc ): - import methods_definition - while not isinstance( cc, methods_definition.methods_definition_t ): - cc = cc.parent - return cc.mem_fun_factory_var_name - - -class METHOD_MODE: - STAND_ALONE = "stand alone" - MULTI_METHOD = "multi method" - all = [ STAND_ALONE, MULTI_METHOD ] - -class init_definition_t( code_creator.code_creator_t, declaration_based.declaration_based_t ): +class init_definition_t( callable_definition_t ): def __init__( self, constructor ): - code_creator.code_creator_t.__init__( self ) - declaration_based.declaration_based_t.__init__( self, constructor ) - self.__mode = METHOD_MODE.STAND_ALONE + callable_definition_t.__init__( self, constructor ) - def __get_mode(self): - return self.__mode - def __set_mode(self, new_mode): - assert new_mode in METHOD_MODE.all - self.__mode = new_mode - method_mode = property( __get_mode, __set_mode ) + def _get_alias_impl( self ): + return "__init__" def _create_impl(self): tmpl = '' - substitue_dict = dict( mfcreator=mem_fun_factory_var_name( self ) ) + substitue_dict = dict( mfcreator=self.mem_fun_factory_var_name ) if self.declaration.is_trivial_constructor: tmpl = '%(mfcreator)s.default_constructor()' elif self.declaration.is_copy_constructor: tmpl = '%(mfcreator)s.copy_constructor()' else: + tmpl = '"%(undecorated_decl_name)s", argtypes=%(args)s' if self.method_mode == METHOD_MODE.STAND_ALONE: - tmpl = '%(mfcreator)s( "%(undecorated_decl_name)s", argtypes=%(args)s )' - else: - tmpl = '"%(undecorated_decl_name)s", argtypes=%(args)s' - args = map( ctypes_formatter.as_ctype, self.declaration.function_type().arguments_types ) - substitue_dict['args'] = join_arguments( args ) + tmpl = '%(mfcreator)s( ' + tmpl + ' )' + + substitue_dict['args'] = self.argtypes_code() substitue_dict['undecorated_decl_name'] = self.undecorated_decl_name if self.method_mode == METHOD_MODE.STAND_ALONE: - tmp = '"__init__" : ' + tmpl + tmp = '"%s" : %s' % ( self.declaration.alias, tmpl ) return tmpl % substitue_dict - def _get_system_headers_impl( self ): - return [] +#TODO: aliases for a mem fun and const mem fun with the same name should be different -class multi_init_definition_t( compound.compound_t ): +class mem_fun_definition_t( callable_definition_t ): + def __init__( self, constructor ): + callable_definition_t.__init__( self, constructor ) + + def _create_impl(self): + result = [] + + result.append( '"%s"' % self.undecorated_decl_name ) + + restype = self.restype_code() + if self.method_mode == METHOD_MODE.STAND_ALONE and restype: + result.append( 'restype=%s' % restype ) + argtypes = self.argtypes_code() + if argtypes: + result.append( 'argtypes=%s' % argtypes ) + construction_code = ', '.join( result ) + if self.method_mode == METHOD_MODE.MULTI_METHOD: + return construction_code + else: + return '"%(alias)s" : %(mfcreator)s( %(construction_code)s ),' \ + % dict( alias=self.declaration.alias + , mfcreator=self.mem_fun_factory_var_name + , construction_code=construction_code ) + +class multi_method_definition_t( compound.compound_t ): def __init__( self ): compound.compound_t.__init__( self ) + def get_first_callable( self ): + return self.find_by_creator_class( callable_definition_t, unique=False )[0] + + @property + def multi_method_alias(self): + return self.get_first_callable().alias + def _create_impl(self): result = [] - result.append( '"__init__" : %s.multi_method()' % mem_fun_factory_var_name(self) ) + + return_type = self.get_first_callable().ftype.return_type + restype = '' + if return_type: + restype = self.iif( not declarations.is_void( return_type ) + , ctypes_formatter.as_ctype( return_type ) + , '' ) + + result.append( '"%(alias)s" : %(mfcreator)s.multi_method(%(restype)s)' + % dict( alias=self.multi_method_alias + , mfcreator=get_mem_fun_factory_var_name(self) + , restype=restype ) ) for creator in self.creators: code = '' - if isinstance( creator, init_definition_t ): + if isinstance( creator, callable_definition_t ): creator.method_mode = METHOD_MODE.MULTI_METHOD code = '.register( %s )' % creator.create() else: @@ -123,23 +184,13 @@ return [] -class del_definition_t( code_creator.code_creator_t, declaration_based.declaration_based_t ): +class del_definition_t( callable_definition_t ): def __init__( self, destructor ): - code_creator.code_creator_t.__init__( self ) - declaration_based.declaration_based_t.__init__( self, destructor ) + callable_definition_t.__init__( self, destructor ) def _create_impl(self): - return '"__del__" : %(mfcreator)s.destructor(is_virtual=%(virtual)s)' \ - % dict( mfcreator=mem_fun_factory_var_name( self ) + return '"__del__" : %(mfcreator)s.destructor(is_virtual=%(virtual)s),' \ + % dict( mfcreator=self.mem_fun_factory_var_name , virtual=self.iif( self.declaration.virtuality==declarations.VIRTUALITY_TYPES.NOT_VIRTUAL , 'False' , 'True' ) ) - - def _get_system_headers_impl( self ): - return [] - - - - - - Modified: pyplusplus_dev/pyplusplus/code_creators/methods_definition.py =================================================================== --- pyplusplus_dev/pyplusplus/code_creators/methods_definition.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/pyplusplus/code_creators/methods_definition.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -17,6 +17,20 @@ def mem_fun_factory_var_name(self): return "mfcreator" + def find_mutli_method( self, alias ): + import function_definition + mmdef_t = function_definition.multi_method_definition_t + multi_method_defs = self.find_by_creator_class( mmdef_t, unique=False ) + if None is multi_method_defs: + return + multi_method_defs = filter( lambda cc: cc.multi_method_alias == alias + , multi_method_defs ) + if multi_method_defs: + return multi_method_defs[0] + else: + return None + + def _create_impl(self): result = [] scope = declarations.algorithm.declaration_path( self.declaration ) Modified: pyplusplus_dev/pyplusplus/code_repository/ctypes_utils.py =================================================================== --- pyplusplus_dev/pyplusplus/code_repository/ctypes_utils.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/pyplusplus/code_repository/ctypes_utils.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -72,7 +72,7 @@ self.this_type = ctypes.POINTER( wrapper ) def __call__( self, name, **keywd ): - if 'argtypes' not in keywd: + if 'argtypes' not in keywd or keywd['argtypes'] is None: keywd['argtypes'] = [ self.this_type ] else: keywd['argtypes'].insert( 0, self.this_type ) Modified: pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py =================================================================== --- pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/pyplusplus/creators_factory/ctypes_creator.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -151,8 +151,26 @@ def visit_member_function( self ): self.__dependencies_manager.add_exported( self.curr_decl ) + md_cc = self.__class2methods_def[ self.curr_decl.parent ] cls_intro_cc = self.__class2introduction[ self.curr_decl.parent ] - cls_intro_cc.adopt_creator( code_creators.mem_fun_introduction_t( self.curr_decl ) ) + mem_fun_def_cc = code_creators.mem_fun_definition_t( self.curr_decl ) + #TODO: calculate only exported functions + if 0 == len( self.curr_decl.overloads): + #this is the first and the last and the only class constructor + md_cc.adopt_creator( mem_fun_def_cc ) + cls_intro_cc.adopt_creator( code_creators.mem_fun_introduction_t(self.curr_decl) ) + else: + has_introduction = cls_intro_cc.find_by_creator_class( code_creators.mem_fun_introduction_t, unique=False ) + has_introduction = filter( lambda cc: cc.alias == mem_fun_def_cc.alias, has_introduction ) + if not has_introduction: + cls_intro_cc.adopt_creator( code_creators.mem_fun_introduction_t(self.curr_decl) ) + + multi_method_def = md_cc.find_mutli_method( mem_fun_def_cc.alias ) + if not multi_method_def: + multi_method_def = code_creators.multi_method_definition_t () + md_cc.adopt_creator( multi_method_def ) + multi_method_def.adopt_creator( mem_fun_def_cc ) + #~ if self.curr_decl.virtuality == VIRTUALITY_TYPES.NOT_VIRTUAL: #~ cls_intro_cc.adopt_creator( code_creators.mem_fun_introduction_t( self.curr_decl ) ) #~ elif self.curr_decl.virtuality == VIRTUALITY_TYPES.VIRTUAL: @@ -166,24 +184,20 @@ cls_intro_cc = self.__class2introduction[ self.curr_decl.parent ] init_def_cc = code_creators.init_definition_t( self.curr_decl ) #TODO: calculate only exported constructors - if 1 == len( self.curr_decl.parent.constructors(recursive=False, allow_empty=True ) ): + if 0 == len( self.curr_decl.overloads): #this is the first and the last and the only class constructor - md_cc.adopt_creator( code_creators.init_definition_t( self.curr_decl ) ) + md_cc.adopt_creator( init_def_cc ) cls_intro_cc.adopt_creator( code_creators.init_introduction_t(self.curr_decl) ) else: - has_constructor = filter( lambda cc: isinstance( cc, code_creators.init_introduction_t ) - , cls_intro_cc.creators ) + has_constructor = cls_intro_cc.find_by_creator_class( code_creators.init_introduction_t ) if not has_constructor: cls_intro_cc.adopt_creator( code_creators.init_introduction_t(self.curr_decl) ) - multi_init_def = filter( lambda cc: isinstance( cc, code_creators.multi_init_definition_t ) - , md_cc.creators ) - if not multi_init_def: - multi_init_def = code_creators.multi_init_definition_t() - md_cc.adopt_creator( multi_init_def ) - multi_init_def.adopt_creator( init_def_cc ) - else: - multi_init_def[0].adopt_creator( init_def_cc ) + multi_method_def = md_cc.find_mutli_method( init_def_cc.alias ) + if not multi_method_def: + multi_method_def = code_creators.multi_method_definition_t () + md_cc.adopt_creator( multi_method_def ) + multi_method_def.adopt_creator( init_def_cc ) def visit_destructor( self ): self.__dependencies_manager.add_exported( self.curr_decl ) Modified: pyplusplus_dev/unittests/autoconfig.py =================================================================== --- pyplusplus_dev/unittests/autoconfig.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/unittests/autoconfig.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -29,7 +29,7 @@ class cxx_parsers_cfg: keywd = { 'working_directory' : data_directory , 'define_symbols' : [ gccxml_version ] - , 'compiler' : compiler + , 'compiler' : "msvc71" , 'gccxml_path': gccxml.executable } if 'win' in sys.platform: Modified: pyplusplus_dev/unittests/ctypes_pof_tester.py =================================================================== --- pyplusplus_dev/unittests/ctypes_pof_tester.py 2008-12-29 22:22:45 UTC (rev 1514) +++ pyplusplus_dev/unittests/ctypes_pof_tester.py 2008-12-30 11:27:00 UTC (rev 1515) @@ -26,14 +26,38 @@ #mb.code_creator.create() sys.path.append( autoconfig.build_directory ) import ctypes_pof + #the following code fails - difference in the calling conventions #TODO: the following test failes, because of the wrong calling convention used #self.failUnless( ctypes_pof.identity_cpp( int(111) ) == 111 ) + + #testing constructors n0 = ctypes_pof.pof.number_t() - n1 = ctypes_pof.pof.number_t( ctypes.c_long(1) ) - n2 = ctypes_pof.pof.number_t( ctypes.pointer(n1), 1 ) + self.failUnless( 0 == n0.get_value() ) + n1 = ctypes_pof.pof.number_t( ctypes.c_long(32) ) + self.failUnless( 32 == n1.get_value() ) + n2 = ctypes_pof.pof.number_t( ctypes.pointer(n1) ) + self.failUnless( 32 == n2.get_value() ) + #testing get/set value + n0.set_value( 1977 ) + self.failUnless( 1977 == n0.get_value() ) + #the following functionality is still missing + #~ def test_operator_assign( self ): + #~ obj1 = number_t(1) + #~ obj2 = number_t(2) + #~ x = obj1.operator_assign( obj2 ) + #~ #there are special cases, where ctypes could introduce "optimized" behaviour and not create new python object + #~ self.failUnless( x is obj1 ) + #~ self.failUnless( obj1.m_value == obj2.m_value ) + + #~ def test_clone( self ): + #~ obj1 = number_t(1) + #~ obj2 = obj1.clone() + #~ self.fail( obj1.get_value() == obj2.get_value() ) + + #~ def test_bsc( self ): #~ root = r'E:\Documents and Settings\romany\Desktop\ToInstall\bsckit70\bscsdk' #~ mb = ctypes_module_builder_t( [os.path.join( root, 'bsc.h' )] This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |