def test_name_based( self ): cls = self.global_ns.class_( name='class_for_nested_enums_t' ) cls_demangled_name = cls.name self.failUnless( cls.cache.demangled_name == cls_demangled_name ) cls_full_name = declarations.full_name( cls ) self.failUnless( cls.cache.full_name == cls_full_name ) cls_declaration_path = declarations.declaration_path( cls ) self.failUnless( cls.cache.declaration_path == cls_declaration_path ) enum = cls.enum( 'ENestedPublic' ) enum_full_name = declarations.full_name( enum ) self.failUnless( enum.cache.full_name == enum_full_name ) enum_declaration_path = declarations.declaration_path( enum ) self.failUnless( enum.cache.declaration_path == enum_declaration_path ) #now we change class name, all internal decls cache should be cleared cls.name = "new_name" self.failUnless( not cls.cache.full_name ) self.failUnless( not cls.cache.demangled_name ) self.failUnless( not cls.cache.declaration_path ) self.failUnless( not enum.cache.full_name ) self.failUnless( not enum.cache.demangled_name ) self.failUnless( not enum.cache.declaration_path )
def __fix_constructor_call(self, func, arg): call_invocation = declarations.call_invocation dv = arg.default_value if not call_invocation.is_call_invocation(dv): return False base_type = declarations.base_type(arg.type) decl = base_type.declaration name, args = call_invocation.split(dv) if decl.name != name: # we have some alias to the class relevant_typedefs = [ typedef for typedef in decl.aliases if typedef.name == name] if 1 == len(relevant_typedefs): f_q_name = self.__join_names( declarations.full_name( relevant_typedefs[0].parent), name) else: # in this case we can not say which typedef user uses: f_q_name = self.__join_names( declarations.full_name( decl.parent), decl.name) else: f_q_name = self.__join_names( declarations.full_name( decl.parent), name) return call_invocation.join(f_q_name, args)
def test(self): module_builder.set_logger_level(logging.CRITICAL) messages.disable(*messages.all_warning_msgs) ogre_file = autoconfig.data_directory.replace('pyplusplus_dev', 'pygccxml_dev') ogre_file = parser.create_gccxml_fc( os.path.join(ogre_file, 'ogre.1.7.xml')) mb = module_builder.module_builder_t( [ogre_file], gccxml_path=autoconfig.gccxml.executable, indexing_suite_version=2, compiler=pygccxml.utils.native_compiler.get_gccxml_compiler()) mb.global_ns.exclude() mb.namespace('Ogre').include() x = mb.global_ns.decls( lambda d: 'Animation*' in d.name and 'MapIterator' in d.name) for y in x: print y.name print y.partial_name print declarations.full_name(y, with_defaults=False) target_dir = os.path.join(autoconfig.build_directory, 'ogre') #~ if os.path.exists( target_dir ): #~ shutil.rmtree( target_dir ) #~ os.mkdir( target_dir ) mb.build_code_creator('Ogre3d') mb.split_module(target_dir)
def test_name_based(self): cls = self.global_ns.class_(name='class_for_nested_enums_t') if "CastXML" in utils.xml_generator: self.assertRaises(Exception, lambda: cls.cache.demangled_name) elif "GCCXML" in utils.xml_generator: self.failUnless(cls.cache.demangled_name == cls.name) cls_full_name = declarations.full_name(cls) self.failUnless(cls.cache.full_name == cls_full_name) cls_declaration_path = declarations.declaration_path(cls) self.failUnless(cls.cache.declaration_path == cls_declaration_path) enum = cls.enum('ENestedPublic') enum_full_name = declarations.full_name(enum) self.failUnless(enum.cache.full_name == enum_full_name) enum_declaration_path = declarations.declaration_path(enum) self.failUnless(enum.cache.declaration_path == enum_declaration_path) # now we change class name, all internal decls cache should be cleared cls.name = "new_name" self.failUnless(not cls.cache.full_name) if "GCCXML" in utils.xml_generator: self.failUnless(not cls.cache.demangled_name) self.failUnless(not cls.cache.declaration_path) self.failUnless(not enum.cache.full_name) if "GCCXML" in utils.xml_generator: self.failUnless(not enum.cache.demangled_name) self.failUnless(not enum.cache.declaration_path)
def test_name_based(self): cls = self.global_ns.class_(name='class_for_nested_enums_t') cls_demangled_name = cls.name self.failUnless(cls.cache.demangled_name == cls_demangled_name) cls_full_name = declarations.full_name(cls) self.failUnless(cls.cache.full_name == cls_full_name) cls_declaration_path = declarations.declaration_path(cls) self.failUnless(cls.cache.declaration_path == cls_declaration_path) enum = cls.enum('ENestedPublic') enum_full_name = declarations.full_name(enum) self.failUnless(enum.cache.full_name == enum_full_name) enum_declaration_path = declarations.declaration_path(enum) self.failUnless(enum.cache.declaration_path == enum_declaration_path) #now we change class name, all internal decls cache should be cleared cls.name = "new_name" self.failUnless(not cls.cache.full_name) self.failUnless(not cls.cache.demangled_name) self.failUnless(not cls.cache.declaration_path) self.failUnless(not enum.cache.full_name) self.failUnless(not enum.cache.demangled_name) self.failUnless(not enum.cache.declaration_path)
def __str__( self ): desc = [] desc.append( 'fget=%s' % declarations.full_name( self.fget ) ) if self.fset: desc.append( ', ' ) desc.append( 'fset=%s' % declarations.full_name( self.fset ) ) return 'property "%s"[%s]' % ( self.name, ''.join( desc ) )
def __str__(self): desc = [] desc.append('fget=%s' % declarations.full_name(self.fget)) if self.fset: desc.append(', ') desc.append('fset=%s' % declarations.full_name(self.fset)) return 'property "%s"[%s]' % (self.name, ''.join(desc))
def __str__(self): desc = [] desc.append("fget=%s" % declarations.full_name(self.fget)) if self.fset: desc.append(", ") desc.append("fset=%s" % declarations.full_name(self.fset)) return 'property "%s"[%s]' % (self.name, "".join(desc))
def test_name_based(self): cls = self.global_ns.class_(name='class_for_nested_enums_t') if "CastXML" in utils.xml_generator: self.assertRaises(Exception, lambda: cls.cache.demangled_name) elif "GCCXML" in utils.xml_generator: self.assertTrue(cls.cache.demangled_name == cls.name) cls_full_name = declarations.full_name(cls) self.assertTrue(cls.cache.full_name == cls_full_name) cls_declaration_path = declarations.declaration_path(cls) self.assertTrue(cls.cache.declaration_path == cls_declaration_path) enum = cls.enum('ENestedPublic') enum_full_name = declarations.full_name(enum) self.assertTrue(enum.cache.full_name == enum_full_name) enum_declaration_path = declarations.declaration_path(enum) self.assertTrue(enum.cache.declaration_path == enum_declaration_path) # now we change class name, all internal decls cache should be cleared cls.name = "new_name" self.assertTrue(not cls.cache.full_name) if "GCCXML" in utils.xml_generator: self.assertTrue(not cls.cache.demangled_name) self.assertTrue(not cls.cache.declaration_path) self.assertTrue(not enum.cache.full_name) if "GCCXML" in utils.xml_generator: self.assertTrue(not enum.cache.demangled_name) self.assertTrue(not enum.cache.declaration_path)
def test(self): module_builder.set_logger_level( logging.CRITICAL ) messages.disable( *messages.all_warning_msgs ) ogre_file = autoconfig.data_directory.replace( 'pyplusplus_dev', 'pygccxml_dev' ) ogre_file = parser.create_gccxml_fc( os.path.join( ogre_file, 'ogre.1.7.xml' ) ) mb = module_builder.module_builder_t( [ ogre_file ] , gccxml_path=autoconfig.gccxml.executable , indexing_suite_version=2 , compiler=pygccxml.utils.native_compiler.get_gccxml_compiler()) mb.global_ns.exclude() mb.namespace('Ogre').include() x = mb.global_ns.decls( lambda d: 'Animation*' in d.name and 'MapIterator' in d.name ) for y in x: print y.name print y.partial_name print declarations.full_name( y, with_defaults=False ) target_dir = os.path.join( autoconfig.build_directory, 'ogre' ) #~ if os.path.exists( target_dir ): #~ shutil.rmtree( target_dir ) #~ os.mkdir( target_dir ) mb.build_code_creator( 'Ogre3d' ) mb.split_module( target_dir )
def test_name_based(self): cls = self.global_ns.class_(name='class_for_nested_enums_t') if self.xml_generator_from_xml_file.is_castxml: self.assertIsNone(cls.cache.demangled_name) elif self.xml_generator_from_xml_file.is_gccxml: self.assertTrue(cls.cache.demangled_name == cls.name) cls_full_name = declarations.full_name(cls) self.assertTrue(cls.cache.full_name == cls_full_name) cls_declaration_path = declarations.declaration_path(cls) self.assertTrue(cls.cache.declaration_path == cls_declaration_path) enum = cls.enumeration('ENestedPublic') enum_full_name = declarations.full_name(enum) self.assertTrue(enum.cache.full_name == enum_full_name) enum_declaration_path = declarations.declaration_path(enum) self.assertTrue(enum.cache.declaration_path == enum_declaration_path) # now we change class name, all internal decls cache should be cleared cls.name = "new_name" self.assertTrue(not cls.cache.full_name) if self.xml_generator_from_xml_file.is_gccxml: self.assertTrue(not cls.cache.demangled_name) self.assertTrue(not cls.cache.declaration_path) self.assertTrue(not enum.cache.full_name) if self.xml_generator_from_xml_file.is_gccxml: self.assertTrue(not enum.cache.demangled_name) self.assertTrue(not enum.cache.declaration_path)
def print_( extmodule ): creators = filter( missing_call_policies._selector , code_creators.make_flatten_generator( extmodule.creators ) ) for creator in creators: print creator.declaration.__class__.__name__, ': ', declarations.full_name( creator.declaration ) print ' *** MISSING CALL POLICY', creator.declaration.function_type().decl_string print
def _create_impl(self): answer = [] if self.declaration.type_qualifiers.has_static: substitutions = { 'type': self.declaration.type.decl_string, 'name': self.declaration.name, 'cls_type': declarations.full_name(self.declaration.parent) } answer.append(self.MV_STATIC_GET_TEMPLATE % substitutions) if self.has_setter: answer.append(self.MV_STATIC_SET_TEMPLATE % substitutions) else: answer.append( self.MV_GET_TEMPLATE % { 'type': self.declaration.type.decl_string, 'name': self.declaration.name, 'cls_type': self.inst_arg_type(has_const=True) }) if self.has_setter: answer.append( self.MV_SET_TEMPLATE % { 'type': self.declaration.type.decl_string, 'name': self.declaration.name, 'cls_type': self.inst_arg_type(has_const=False) }) return os.linesep.join(answer)
def add_code(self, mb): mb.classes().add_properties(exclude_accessors=True) as_number_template = 'def( "as_number", &%(class_def)s::operator %(class_def)s::value_type, bp::default_call_policies() )' classes = mb.classes() classes.always_expose_using_scope = True #better error reporting from compiler classes = mb.classes(lambda decl: decl.alias != 'local_date_time') classes.redefine_operators = True #redefine all operators found in base classes classes = mb.classes( lambda decl: decl.name.startswith('constrained_value<')) for cls in classes: cls.add_code(as_number_template % {'class_def': declarations.full_name(cls)}) classes = mb.classes( lambda decl: decl.alias in ['date_duration', 'time_duration']) for operator in ['>', '>=', '<=', '<', '+', '-']: classes.add_code('def( bp::self %s bp::self )' % operator) ptime = mb.class_(lambda decl: decl.alias == 'ptime') for operator in ['>', '>=', '<=', '<', '-']: ptime.add_code('def( bp::self %s bp::self )' % operator)
def _create_function_type_alias_code( self, exported_class_alias=None ): f_type = self.declaration.function_type() falias = self.function_type_alias fname = declarations.full_name( self.declaration, with_defaults=False ) fvalue = re.sub("_type$", "_value", falias ) return "typedef %s;\n%s %s( &%s );" % (f_type.create_typedef( falias, with_defaults=False ), falias, fvalue, fname)
def _create_function_type_alias_code(self, exported_class_alias=None): f_type = self.declaration.function_type() falias = self.function_type_alias fname = declarations.full_name(self.declaration, with_defaults=False) fvalue = re.sub("_type$", "_value", falias) return "typedef %s;\n%s %s( &%s );" % (f_type.create_typedef( falias, with_defaults=False), falias, fvalue, fname)
def create_default(self): cntrl = self.controller.default_controller make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object') make_tuple = algorithm.create_identifier(self, 'boost::python::make_tuple') tmpl_values = dict() tmpl_values['unique_function_name'] = self.default_name() tmpl_values['return_type'] = cntrl.wrapper_return_type.decl_string tmpl_values['arg_declarations'] = self.args_default_declaration() tmpl_values['wrapper_class'] = self.parent.wrapper_alias tmpl_values['wrapped_class'] = declarations.full_name( self.declaration.parent) tmpl_values['wrapped_inst'] = cntrl.inst_arg.name tmpl_values['wrapped_inst_constness'] = '' if declarations.is_const( declarations.remove_reference(cntrl.inst_arg.type)): tmpl_values['wrapped_inst_constness'] = 'const' decl_vars = cntrl.variables[:] if not declarations.is_void(self.declaration.return_type): decl_vars.append(cntrl.result_variable) tmpl_values['declare_variables'] \ = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() ) , decl_vars ) ) tmpl_values['pre_call'] = os.linesep + self.indent( os.linesep.join(cntrl.pre_call)) tmpl_values['save_result'] = '' if not declarations.is_void(self.declaration.return_type): tmpl_tmp = '%(result_var_name)s = ' if declarations.is_reference(self.declaration.return_type): tmpl_tmp = tmpl_tmp + '&' tmpl_values['save_result'] = tmpl_tmp % dict( result_var_name=cntrl.result_variable.name) tmpl_values['function_name'] = self.declaration.name tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join( cntrl.arg_expressions) return_stmt_creator = calldef_utils.return_stmt_creator_t( self, cntrl, cntrl.result_variable, cntrl.return_variables) tmpl_values['post_call'] = os.linesep + self.indent( os.linesep.join(cntrl.post_call)) if return_stmt_creator.pre_return_code: tmpl_values['post_call'] \ = os.linesep.join([ tmpl_values['post_call'] , self.indent( return_stmt_creator.pre_return_code )]) tmpl_values['return'] = os.linesep + self.indent( return_stmt_creator.statement) f_def = cntrl.template.substitute(tmpl_values) return remove_duplicate_linesep(f_def)
def _create_function_ref_code(self, use_function_alias=False): fname = declarations.full_name( self.declaration, with_defaults=False ) if use_function_alias: falias = self.function_type_alias fvalue = re.sub("_type$", "_value", falias) return fvalue elif self.declaration.create_with_signature: return '(%s)( &%s )' % ( self.declaration.function_type().partial_decl_string, fname ) else: return '&%s' % fname
def _create_function_ref_code(self, use_function_alias=False): fname = declarations.full_name(self.declaration, with_defaults=False) if use_function_alias: falias = self.function_type_alias fvalue = re.sub("_type$", "_value", falias) return fvalue elif self.declaration.create_with_signature: return '(%s)( &%s )' % ( self.declaration.function_type().partial_decl_string, fname) else: return '&%s' % fname
def __fix_constructor_call( self, func, arg ): call_invocation = declarations.call_invocation dv = arg.default_value if not call_invocation.is_call_invocation( dv ): return False base_type = declarations.base_type( arg.type ) decl = base_type.declaration name, args = call_invocation.split( dv ) if decl.name != name: #we have some alias to the class relevant_typedefs = filter( lambda typedef: typedef.name == name , decl.aliases ) if 1 == len( relevant_typedefs ): f_q_name = self.__join_names( declarations.full_name( relevant_typedefs[0].parent ) , name ) else:#in this case we can not say which typedef user uses: f_q_name = self.__join_names( declarations.full_name( decl.parent ) , decl.name ) else: f_q_name = self.__join_names( declarations.full_name( decl.parent ), name ) return call_invocation.join( f_q_name, args )
def _create_setter(self): if self.declaration.type_qualifiers.has_static: return self.MV_STATIC_SET_TEMPLATE % { 'type': self._get_var_decl_string(), 'name': self.declaration.name, 'cls_type': declarations.full_name(self.declaration.parent) } else: return self.MV_SET_TEMPLATE % { 'type': self._get_var_decl_string(), 'name': self.declaration.name, 'cls_type': self._get_class_inst_type(add_const=False) }
def _create_impl(self): if self.declaration.already_exposed: return "" answer = [self._create_namespaces_name()] answer.append(self.wrapper_type.decl_string) answer.append("".join([self.wrapper_creator_name, "(){"])) temp = "".join( ["return ", self.wrapper_type.decl_string, "( ", declarations.full_name(self.declaration), " );"] ) answer.append(self.indent(temp)) answer.append("}") answer.append("}" * len(self._create_namespaces())) return os.linesep.join(answer)
def create_default(self): cntrl = self.controller.default_controller make_object = algorithm.create_identifier( self, 'pyplusplus::call_policies::make_object' ) make_tuple = algorithm.create_identifier( self, 'boost::python::make_tuple' ) tmpl_values = dict() tmpl_values['unique_function_name'] = self.default_name() tmpl_values['return_type'] = cntrl.wrapper_return_type.decl_string tmpl_values['arg_declarations'] = self.args_default_declaration() tmpl_values['wrapper_class'] = self.parent.wrapper_alias tmpl_values['wrapped_class'] = declarations.full_name( self.declaration.parent ) tmpl_values['wrapped_inst'] = cntrl.inst_arg.name tmpl_values['wrapped_inst_constness'] = '' if declarations.is_const( declarations.remove_reference( cntrl.inst_arg.type ) ): tmpl_values['wrapped_inst_constness'] = 'const' decl_vars = cntrl.variables[:] if not declarations.is_void( self.declaration.return_type ): decl_vars.append( cntrl.result_variable ) tmpl_values['declare_variables'] \ = os.linesep + os.linesep.join( map( lambda var: self.indent( var.declare_var_string() ) , decl_vars ) ) tmpl_values['pre_call'] = os.linesep + self.indent( os.linesep.join( cntrl.pre_call ) ) tmpl_values['save_result'] = '' if not declarations.is_void( self.declaration.return_type ): tmpl_tmp = '%(result_var_name)s = ' if declarations.is_reference( self.declaration.return_type ): tmpl_tmp = tmpl_tmp + '&' tmpl_values['save_result'] = tmpl_tmp % dict( result_var_name=cntrl.result_variable.name ) tmpl_values['function_name'] = self.declaration.name tmpl_values['arg_expressions'] = self.PARAM_SEPARATOR.join( cntrl.arg_expressions ) return_stmt_creator = calldef_utils.return_stmt_creator_t( self , cntrl , cntrl.result_variable , cntrl.return_variables ) tmpl_values['post_call'] = os.linesep + self.indent( os.linesep.join( cntrl.post_call ) ) if return_stmt_creator.pre_return_code: tmpl_values['post_call'] \ = os.linesep.join([ tmpl_values['post_call'] , self.indent( return_stmt_creator.pre_return_code )]) tmpl_values['return'] = os.linesep + self.indent( return_stmt_creator.statement ) f_def = cntrl.template.substitute(tmpl_values) return remove_duplicate_linesep( f_def )
def _generate_code_with_scope(self): result = [] scope_var_name = self.alias + '_scope' base_classes, base_creators = self._exported_base_classes() result.append('typedef ' + self._generate_class_definition(base_creators) + ' ' + self.typedef_name + ';') result.append(self.typedef_name + ' ' + self.class_var_name) result[-1] = result[-1] + ' = ' class_constructor, used_init = self._generate_constructor() result[-1] = result[-1] + self.typedef_name + class_constructor result[-1] = result[-1] + ';' result.append( algorithm.create_identifier(self, '::boost::python::scope')) result[-1] = result[-1] + ' ' + scope_var_name result[-1] = result[-1] + '( %s );' % self.class_var_name creators = self.creators if self.declaration.redefine_operators: creators = self.creators + self._get_base_operators( base_classes, base_creators) for x in creators: if x is used_init: continue if isinstance(x, (calldef.calldef_t, calldef.calldef_overloads_t)): x.works_on_instance = False code = x.create() if code: result.append(code) continue if not x.works_on_instance: code = x.create() if code: result.append(code) else: result.append('%s.%s;' % (self.class_var_name, x.create())) code = os.linesep.join(result) result = [ '{ //%s' % declarations.full_name(self.declaration, with_defaults=False) ] result.append(self.indent(code)) result.append('}') return os.linesep.join(result)
def _create_impl(self): if self.declaration.already_exposed: return '' answer = [self._create_namespaces_name()] answer.append(self.wrapper_type.decl_string) answer.append(''.join([self.wrapper_creator_name, '(){'])) temp = ''.join([ 'return ', self.wrapper_type.decl_string, '( ', declarations.full_name(self.declaration), ' );' ]) answer.append(self.indent(temp)) answer.append('}') answer.append('}' * len(self._create_namespaces())) return os.linesep.join(answer)
def _create_impl( self ): if self.declaration.already_exposed: return '' answer = [self._create_namespaces_name()] answer.append( self.wrapper_type.decl_string ) answer.append( ''.join([ self.wrapper_creator_name, '(){']) ) temp = ''.join([ 'return ' , self.wrapper_type.decl_string , '( ' , declarations.full_name( self.declaration ) , ' );']) answer.append( self.indent( temp ) ) answer.append('}') answer.append( '}' * len( self._create_namespaces() ) ) return os.linesep.join( answer )
def create_accessor_code(self, f, ftype_alias): f_ref_code = '%s( &%s )' % (ftype_alias, declarations.full_name(f)) if f.call_policies and f.call_policies.is_default(): return f_ref_code result = [self.make_function_identifier] result.append('( ') result.append(os.linesep) result.append(self.indent(' ', 2)) result.append(f_ref_code) if f.call_policies: result.append(os.linesep) result.append(self.indent(', ', 2)) result.append(f.call_policies.create(self)) else: result.append(os.linesep) result.append(self.indent(' ', 2)) result.append('/* undefined call policies */') result.append(' ) ') return ''.join(result)
def create_accessor_code( self, f, ftype_alias ): f_ref_code = '%s( &%s )' % ( ftype_alias, declarations.full_name( f ) ) if f.call_policies and f.call_policies.is_default(): return f_ref_code result = [ self.make_function_identifier ] result.append( '( ' ) result.append( os.linesep ) result.append( self.indent( ' ', 2 ) ) result.append( f_ref_code ) if f.call_policies: result.append( os.linesep ) result.append( self.indent( ', ', 2 ) ) result.append( f.call_policies.create( self ) ) else: result.append( os.linesep ) result.append( self.indent( ' ', 2 ) ) result.append( '/* undefined call policies */' ) result.append( ' ) ' ) return ''.join( result )
def _generate_code_with_scope(self): result = [] scope_var_name = self.alias + '_scope' base_classes, base_creators = self._exported_base_classes() result.append( 'typedef ' + self._generate_class_definition(base_creators) + ' ' + self.typedef_name + ';') result.append( self.typedef_name + ' ' + self.class_var_name ) result[-1] = result[-1] + ' = ' class_constructor, used_init = self._generate_constructor() result[-1] = result[-1] + self.typedef_name + class_constructor result[-1] = result[-1] + ';' result.append( algorithm.create_identifier( self, '::boost::python::scope' ) ) result[-1] = result[-1] + ' ' + scope_var_name result[-1] = result[-1] + '( %s );' % self.class_var_name creators = self.creators if self.declaration.redefine_operators: creators = self.creators + self._get_base_operators(base_classes, base_creators) for x in creators: if x is used_init: continue if isinstance( x, ( calldef.calldef_t, calldef.calldef_overloads_t ) ): x.works_on_instance = False code = x.create() if code: result.append( code ) continue if not x.works_on_instance: code = x.create() if code: result.append( code ) else: result.append( '%s.%s;' % ( self.class_var_name, x.create() ) ) code = os.linesep.join( result ) result = [ '{ //%s' % declarations.full_name( self.declaration, with_defaults=False ) ] result.append( self.indent( code ) ) result.append( '}' ) return os.linesep.join( result )
def _create_impl(self): answer = [] if self.declaration.type_qualifiers.has_static: substitutions = { 'type' : self.declaration.type.decl_string , 'name' : self.declaration.name , 'cls_type' : declarations.full_name( self.declaration.parent ) } answer.append( self.MV_STATIC_GET_TEMPLATE % substitutions) if self.has_setter: answer.append( self.MV_STATIC_SET_TEMPLATE % substitutions ) else: answer.append( self.MV_GET_TEMPLATE % { 'type' : self.declaration.type.decl_string , 'name' : self.declaration.name , 'cls_type' : self.inst_arg_type( has_const=True ) }) if self.has_setter: answer.append( self.MV_SET_TEMPLATE % { 'type' : self.declaration.type.decl_string , 'name' : self.declaration.name , 'cls_type' : self.inst_arg_type( has_const=False ) }) return os.linesep.join( answer )
def add_code(self, mb): mb.classes().add_properties(exclude_accessors=True) as_number_template = ( 'def( "as_number", &%(class_def)s::operator %(class_def)s::value_type, bp::default_call_policies() )' ) classes = mb.classes() classes.always_expose_using_scope = True # better error reporting from compiler classes = mb.classes(lambda decl: decl.alias != "local_date_time") classes.redefine_operators = True # redefine all operators found in base classes classes = mb.classes(lambda decl: decl.name.startswith("constrained_value<")) for cls in classes: cls.add_code(as_number_template % {"class_def": declarations.full_name(cls)}) classes = mb.classes(lambda decl: decl.alias in ["date_duration", "time_duration"]) for operator in [">", ">=", "<=", "<", "+", "-"]: classes.add_code("def( bp::self %s bp::self )" % operator) ptime = mb.class_(lambda decl: decl.alias == "ptime") for operator in [">", ">=", "<=", "<", "-"]: ptime.add_code("def( bp::self %s bp::self )" % operator)
def parse(self): """Parse the header files and setup the known declarations. Currently this method can only be called once. This method can be called anytime after initialization and all Template() calls have been made. :rtype: Returns the root of the declaration tree @rtype: L{IDecl<declwrapper.IDecl>} @postcondition: This class can act as a wrapper for namespace("::") and all declarations are set to be ignored. """ if self.mHeaderFiles == []: raise ValueError, "No header files specified" if self.mVerbose: print "Parsing headers: ", self.mHeaderFiles # Record the time when parsing started... self.mStartTime = time.time() # Create and initialize the config object parser_cfg = parser.config_t(self.mGccXmlPath, self.mWorkingDir, self.mIncludePaths, define_symbols=self.mDefines, undefine_symbols=self.mUndefines, start_with_declarations=None) full_header_list = self.mHeaderFiles[:] # Handle template instantiation as needed temp_file, temp_filename = (None, None) template_instantiation_text = self.buildTemplateFileContents() if None != template_instantiation_text: temp_filename = pygccxml.utils.create_temp_file_name(suffix=".h") temp_file = file(temp_filename, 'w') temp_file.write(template_instantiation_text) temp_file.close() if self.mVerbose: print " creating template instantiation file: ", temp_filename full_header_list.append(temp_filename) # Create the cache object... if self.mCacheDir != None: if self.mVerbose: print "Using directory cache in '%s'" % self.mCacheDir cache = parser.directory_cache_t(self.mCacheDir) elif self.mCacheFile != None: if self.mVerbose: print "Using file cache '%s'" % self.mCacheFile cache = parser.file_cache_t(self.mCacheFile) else: if self.mVerbose: print "No cache in use" cache = None # Create the parser object... the_parser = parser.project_reader_t( config=parser_cfg, cache=cache, decl_factory=decl_wrappers.dwfactory_t()) # ...and parse the headers parsed_decls = the_parser.read_files( full_header_list, parser.project_reader.COMPILATION_MODE.FILE_BY_FILE) assert len(parsed_decls) == 1 # assume that we get root of full tree self.mDeclRoot = parsed_decls[0] # Parse the files and add to decl root # - then traverse tree setting everything to ignore self.mDeclRootWrapper = DeclWrapper(self.mDeclRoot) # Set the module builder instance (this is done here and not in the # constructor so that Allen's DeclWrapper object still work as well) self.mDeclRootWrapper.modulebuilder = self self.mDeclRootWrapper.ignore() # Cleanup if temp_filename: pygccxml.utils.remove_file_no_raise(temp_filename) typedef_decls = declarations.make_flatten(parsed_decls) typedef_decls = decls = filter( lambda x: (isinstance(x, declarations.typedef_t) and not x.name.startswith( '__') and x.location.file_name != "<internal>"), typedef_decls) self.mTypeDefMap = {} for d in typedef_decls: type_def_name = d.name full_name = declarations.full_name(d) if full_name.startswith("::"): # Remove the base namespace full_name = full_name[2:] real_type_name = d.type.decl_string if real_type_name.startswith("::"): # Remove base namespace real_type_name = real_type_name[2:] self.mTypeDefMap[full_name] = real_type_name self.mParseEndTime = time.time() if self.mVerbose: print "Completed parsing in %s." % self._time2str( self.mParseEndTime - self.mStartTime) return self.mDeclRootWrapper
dest_file.write('#ifndef {0}_hpp\n'.format(generated_header)) dest_file.write('#define {0}_hpp\n'.format(generated_header)) dest_file.write('#include <SiconosConfig.h>\n'.format(generated_header)) dest_file.write('#ifdef WITH_SERIALIZATION\n'.format(generated_header)) for header in all_headers: dest_file.write('#include "{0}"\n'.format(header)) for type_ in filter(lambda c: c.parent.name == siconos_namespace, itertools.chain( global_ns.classes(), global_ns.typedefs())): is_typedef = False if isinstance(type_, declarations.class_t): class_names[declarations.full_name(type_)] = type_ class_ = type_ elif isinstance(type_, declarations.typedef_t): try: is_typedef = True class_ = class_names['::' + str(type_.type)] except: class_ = None # with the serializable tag # (could not find friend functions with pygccxml) if class_ is not None and \ is_serializable(class_) and \ (is_typedef or not declarations.templates.is_instantiation(class_.name)): if not unwanted(class_.name):
# Print all base and derived class names for class_ in unittests.classes(): print('class "%s" hierarchy information:' % class_.name) print('\tbase classes : ', repr([base.related_class.name for base in class_.bases])) print('\tderived classes: ', repr([derive.related_class.name for derive in class_.derived])) print('\n') # Pygccxml has very powerfull query api: # Select multiple declarations run_functions = unittests.member_functions('run') print('the namespace contains %d "run" member functions' % len(run_functions)) print('they are: ') for f in run_functions: print('\t' + declarations.full_name(f)) # Select single declaration - all next statements will return same object # vector< unittests::test_case* > # You can select the class using "full" name test_container_1 = global_ns.class_('::unittests::test_suite') # You can define your own "match" criteria test_container_2 = global_ns.class_(lambda decl: 'suite' in decl.name) is_same_object = test_container_1 is test_container_2 print("Does all test_container_* refer to the same object? " + str(is_same_object))
def writeModule(self, moduleName=None, filename=None, useScope=None, multiFile=None, multiCreateMain=True): """ Create the module and write it out. Automatically calls createCreators() and filterExposed() if needed. @param moduleName: The name of the module being created. @param filename: The file or directory to create the code. @param useScope: If true the creators all use scope in their code. @param multiFile: If true use the multifile writer. @param multiCreateMain: If true and using multifile then create main reg method. """ if not self.mExtModule: self.buildCreators(moduleName, filename, useScope) extmodule = self.mExtModule assert extmodule startTime = time.time() if filename == None: filename = self.mOutput if multiFile == None: multiFile = self.mMultiFile # Check for missing policies... if self.mVerbose: print "Sanity check..." creators = code_creators.make_flatten(self.mExtModule) fmfunctions = filter( lambda creator: isinstance( creator, code_creators.calldef.calldef_t) and not isinstance( creator, code_creators.calldef.constructor_t), creators) missing_flag = False sanity_failed = [] for creator in fmfunctions: if not creator.declaration.call_policies: print "Missing policy:", declarations.full_name( creator.declaration) missing_flag = True if not self._declSanityCheck(creator.declaration): sanity_failed.append(creator.declaration) if len(sanity_failed) > 0: f = file("problems.log", "wt") print "***Warning*** The following %d declarations may produce code that compiles, but" % len( sanity_failed) print >> f, "***Warning*** The following %d declarations may produce code that compiles, but" % len( sanity_failed) print "that does not have the desired effect in Python:" print >> f, "that does not have the desired effect in Python:" for decl in sanity_failed: print " ", decl print >> f, " ", decl print >> f, " ", decl.location.line, decl.location.file_name if missing_flag: print "*** Aborting because of missing policies!" return if self.mVerbose: print "Writing out files (%s)..." % filename # Write out the file(s) if not multiFile: file_writers.write_file(extmodule, filename) # Let the arg policy manager write its files... self.mArgPolicyManager.writeFiles(os.path.dirname(filename)) else: mfs = file_writers.multiple_files_t(extmodule, filename, write_main=multiCreateMain) mfs.write() self.split_header_names = mfs.split_header_names self.split_method_names = mfs.split_method_names # Let the arg policy manager write its files... self.mArgPolicyManager.writeFiles(filename) if self.mVerbose: print "Module written in %s" % self._time2str(time.time() - startTime) print "Module generation complete." print "Total time: %s" % self._time2str(time.time() - self.mStartTime)
def parse(self): """Parse the header files and setup the known declarations. Currently this method can only be called once. This method can be called anytime after initialization and all Template() calls have been made. @returns: Returns the root of the declaration tree @rtype: L{IDecl<declwrapper.IDecl>} @postcondition: This class can act as a wrapper for namespace("::") and all declarations are set to be ignored. """ if self.mHeaderFiles==[]: raise ValueError, "No header files specified" if self.mVerbose: print "Parsing headers: ", self.mHeaderFiles # Record the time when parsing started... self.mStartTime = time.time() # Create and initialize the config object parser_cfg = parser.config_t(self.mGccXmlPath, self.mWorkingDir, self.mIncludePaths, define_symbols=self.mDefines, undefine_symbols=self.mUndefines, start_with_declarations=None) full_header_list = self.mHeaderFiles[:] # Handle template instantiation as needed temp_file, temp_filename = (None,None) template_instantiation_text = self.buildTemplateFileContents() if None != template_instantiation_text: temp_filename = pygccxml.utils.create_temp_file_name(suffix=".h") temp_file = file(temp_filename, 'w') temp_file.write(template_instantiation_text) temp_file.close() if self.mVerbose: print " creating template instantiation file: ", temp_filename full_header_list.append(temp_filename) # Create the cache object... if self.mCacheDir!=None: if self.mVerbose: print "Using directory cache in '%s'"%self.mCacheDir cache = parser.directory_cache_t(self.mCacheDir) elif self.mCacheFile!=None: if self.mVerbose: print "Using file cache '%s'"%self.mCacheFile cache = parser.file_cache_t(self.mCacheFile) else: if self.mVerbose: print "No cache in use" cache = None # Create the parser object... the_parser = parser.project_reader_t(config=parser_cfg, cache=cache, decl_factory=decl_wrappers.dwfactory_t()) # ...and parse the headers parsed_decls = the_parser.read_files(full_header_list, parser.project_reader.COMPILATION_MODE.FILE_BY_FILE) assert len(parsed_decls) == 1 # assume that we get root of full tree self.mDeclRoot = parsed_decls[0] # Parse the files and add to decl root # - then traverse tree setting everything to ignore self.mDeclRootWrapper = DeclWrapper(self.mDeclRoot) # Set the module builder instance (this is done here and not in the # constructor so that Allen's DeclWrapper object still work as well) self.mDeclRootWrapper.modulebuilder = self self.mDeclRootWrapper.ignore() # Cleanup if temp_filename: pygccxml.utils.remove_file_no_raise( temp_filename ) typedef_decls = declarations.make_flatten(parsed_decls) typedef_decls = decls = filter( lambda x: (isinstance( x, declarations.typedef_t ) and not x.name.startswith('__') and x.location.file_name != "<internal>") , typedef_decls ) self.mTypeDefMap = {} for d in typedef_decls: type_def_name = d.name full_name = declarations.full_name(d) if full_name.startswith("::"): # Remove the base namespace full_name = full_name[2:] real_type_name = d.type.decl_string if real_type_name.startswith("::"): # Remove base namespace real_type_name = real_type_name[2:] self.mTypeDefMap[full_name] = real_type_name self.mParseEndTime = time.time() if self.mVerbose: print "Completed parsing in %s."%self._time2str(self.mParseEndTime-self.mStartTime) return self.mDeclRootWrapper
def wrap_const_ref_params(cls): """ Find all member functions of cls and if they take a const& to a class that does not have a destructor, then create a thin wrapper for them. This works around an issue with boost.python where it needs a destructor. """ #[Roman] Obviously, this will only work, if the function does not need other #wrapper, I think, this is a new use case for Matthias "arguments policies" #functionality. calldefs = cls.calldefs() if None == calldefs: return for c in calldefs: # Skip constructors if isinstance(c, pd.constructor_t): continue # Find arguments that need replacing args_to_replace = [ ] # List of indices to args to replace with wrapping args = c.arguments for i in range(len(args)): arg = args[i] if is_const_ref(arg.type): naked_arg = tt.remove_cv(tt.remove_reference(arg.type)) if tt.is_class(naked_arg): class_type = naked_arg.declaration if not tt.has_public_destructor(class_type): print "Found indestructible const& arg: [%s]:[%s] " % ( str(c), str(arg)) args_to_replace.append(i) # Now replace arguments if len(args_to_replace): if isinstance( c, pd.operator_t) and c.symbol in ["<", "==", "!=", "="]: c.exclude() continue new_args = copy.copy( args ) # Make new copy of args so we don't modify the existing method for i in args_to_replace: old_arg_type = args[i].type if tt.is_reference(old_arg_type) and tt.is_const( old_arg_type.base): new_args[i].type = cpptypes.reference_t( tt.remove_const(old_arg_type.base)) elif tt.is_const(old_arg): new_args[i].type = tt.remove_const(old_arg_type) wrapper_name = "%s_const_ref_wrapper" % c.name args_str = [str(a) for a in new_args] arg_names_str = [str(a.name) for a in new_args] new_sig = "static %s %s(%s& self_arg, %s)" % ( c.return_type, wrapper_name, pd.full_name(cls), ",".join(args_str)) new_method = """%s { return self_arg.%s(%s); } """ % (new_sig, c.name, ",".join(arg_names_str)) # Add it all c.exclude() #[Roman] you can use cls.add_declaration_code, this could simplify the #wrapper you created, because it will generate the code within the source #file, the class is generated cls.add_declaration_code(new_method) cls.add_registration_code('def("%s", &%s)' % (c.name, wrapper_name), works_on_instance=True)
def resolve_function_ref(self): if self.controller.inst_arg: return self.controller.inst_arg.name + '.' + self.declaration.name else: return declarations.full_name(self.declaration)
def wrapped_class_identifier( self ): return algorithm.create_identifier( self, declarations.full_name( self.declaration.parent ) )
def resolve_function_ref( self ): if self.controller.inst_arg: return self.controller.inst_arg.name + '.' + self.declaration.name else: return declarations.full_name( self.declaration )
def is_excluded( decl ): fullname = declarations.full_name( decl ) return fullname in to_be_excluded or is_deprecated( decl )
# Print all base and derived class names for class_ in unittests.classes(): print('class "%s" hierarchy information:' % class_.name) print('\tbase classes : ', repr([ base.related_class.name for base in class_.bases])) print('\tderived classes: ', repr([ derive.related_class.name for derive in class_.derived])) print('\n') # Pygccxml has very powerfull query api: # Select multiple declarations run_functions = unittests.member_functions('run') print('the namespace contains %d "run" member functions' % len(run_functions)) print('they are: ') for f in run_functions: print('\t' + declarations.full_name(f)) # Select single declaration - all next statements will return same object # vector< unittests::test_case* > # You can select the class using "full" name test_container_1 = global_ns.class_('::unittests::test_suite') # You can define your own "match" criteria test_container_2 = global_ns.class_(lambda decl: 'suite' in decl.name) is_same_object = test_container_1 is test_container_2 print( "Does all test_container_* refer to the same object? " + str(is_same_object))
def wrapped_class_identifier(self): return algorithm.create_identifier( self, declarations.full_name(self.declaration.parent))
def resolve_function_ref(self): return declarations.full_name(self.declaration)
def writeModule(self, moduleName=None, filename=None, useScope=None, multiFile=None, multiCreateMain=True): """ Create the module and write it out. Automatically calls createCreators() and filterExposed() if needed. @param moduleName: The name of the module being created. @param filename: The file or directory to create the code. @param useScope: If true the creators all use scope in their code. @param multiFile: If true use the multifile writer. @param multiCreateMain: If true and using multifile then create main reg method. """ if not self.mExtModule: self.buildCreators(moduleName, filename, useScope) extmodule = self.mExtModule assert extmodule startTime = time.time() if filename==None: filename = self.mOutput if multiFile==None: multiFile = self.mMultiFile # Check for missing policies... if self.mVerbose: print "Sanity check..." creators = code_creators.make_flatten(self.mExtModule) fmfunctions = filter(lambda creator: isinstance(creator, code_creators.calldef.calldef_t) and not isinstance(creator, code_creators.calldef.constructor_t), creators) missing_flag = False sanity_failed = [] for creator in fmfunctions: if not creator.declaration.call_policies: print "Missing policy:", declarations.full_name(creator.declaration) missing_flag = True if not self._declSanityCheck(creator.declaration): sanity_failed.append(creator.declaration) if len(sanity_failed)>0: f = file("problems.log", "wt") print "***Warning*** The following %d declarations may produce code that compiles, but"%len(sanity_failed) print >>f, "***Warning*** The following %d declarations may produce code that compiles, but"%len(sanity_failed) print "that does not have the desired effect in Python:" print >>f, "that does not have the desired effect in Python:" for decl in sanity_failed: print " ",decl print >>f, " ",decl print >>f, " ",decl.location.line, decl.location.file_name if missing_flag: print "*** Aborting because of missing policies!" return if self.mVerbose: print "Writing out files (%s)..."%filename # Write out the file(s) if not multiFile: file_writers.write_file(extmodule, filename) # Let the arg policy manager write its files... self.mArgPolicyManager.writeFiles(os.path.dirname(filename)) else: mfs = file_writers.multiple_files_t(extmodule, filename, write_main=multiCreateMain) mfs.write() self.split_header_names = mfs.split_header_names self.split_method_names = mfs.split_method_names # Let the arg policy manager write its files... self.mArgPolicyManager.writeFiles(filename) if self.mVerbose: print "Module written in %s"%self._time2str(time.time()-startTime) print "Module generation complete." print "Total time: %s"%self._time2str(time.time()-self.mStartTime)
dest_file.write('#ifndef {0}_hpp\n'.format(generated_header)) dest_file.write('#define {0}_hpp\n'.format(generated_header)) dest_file.write('#include <SiconosConfig.h>\n'.format(generated_header)) dest_file.write('#ifdef WITH_SERIALIZATION\n'.format(generated_header)) for header in all_headers: dest_file.write('#include "{0}"\n'.format(header)) for type_ in filter( lambda c: c.parent.name == siconos_namespace, itertools.chain(global_ns.classes(), global_ns.typedefs())): is_typedef = False if isinstance(type_, declarations.class_t): class_names[declarations.full_name(type_)] = type_ class_ = type_ elif isinstance(type_, declarations.typedef_t): try: is_typedef = True class_ = class_names['::' + str(type_.type)] except: class_ = None # with the serializable tag # (could not find friend functions with pygccxml) if class_ is not None and \ is_serializable(class_) and \ (is_typedef or not declarations.templates.is_instantiation(class_.name)): if not unwanted(class_.name):
def _create_impl(self): template = 'add_property( "%(name)s", &%(getter)s, &%(setter)s )' property_name = self.__get_function.name[4:] #get_ return template % dict( name=property_name , getter=declarations.full_name( self.__get_function ) , setter=declarations.full_name( self.__set_function ) )
def resolve_function_ref( self ): return declarations.full_name( self.declaration )
def wrap_const_ref_params(cls): """ Find all member functions of cls and if they take a const& to a class that does not have a destructor, then create a thin wrapper for them. This works around an issue with boost.python where it needs a destructor. """ #[Roman] Obviously, this will only work, if the function does not need other #wrapper, I think, this is a new use case for Matthias "arguments policies" #functionality. calldefs = cls.calldefs() if None == calldefs: return for c in calldefs: # Skip constructors if isinstance(c, pd.constructor_t): continue # Find arguments that need replacing args_to_replace = [] # List of indices to args to replace with wrapping args = c.arguments for i in range(len(args)): arg = args[i] if is_const_ref(arg.type): naked_arg = tt.remove_cv(tt.remove_reference(arg.type)) if tt.is_class(naked_arg): class_type = naked_arg.declaration if not tt.has_public_destructor(class_type): print "Found indestructible const& arg: [%s]:[%s] "%(str(c), str(arg)) args_to_replace.append(i) # Now replace arguments if len(args_to_replace): if isinstance(c, pd.operator_t) and c.symbol in ["<","==","!=","="]: c.exclude() continue new_args = copy.copy(args) # Make new copy of args so we don't modify the existing method for i in args_to_replace: old_arg_type = args[i].type if tt.is_reference(old_arg_type) and tt.is_const(old_arg_type.base): new_args[i].type = cpptypes.reference_t(tt.remove_const(old_arg_type.base)) elif tt.is_const(old_arg): new_args[i].type = tt.remove_const(old_arg_type) wrapper_name = "%s_const_ref_wrapper"%c.name args_str = [str(a) for a in new_args] arg_names_str = [str(a.name) for a in new_args] new_sig = "static %s %s(%s& self_arg, %s)"%(c.return_type, wrapper_name, pd.full_name(cls), ",".join(args_str)) new_method = """%s { return self_arg.%s(%s); } """%(new_sig,c.name,",".join(arg_names_str)) # Add it all c.exclude() #[Roman] you can use cls.add_declaration_code, this could simplify the #wrapper you created, because it will generate the code within the source #file, the class is generated cls.add_declaration_code(new_method) cls.add_registration_code('def("%s", &%s)'%(c.name, wrapper_name), works_on_instance=True)