Update of /cvsroot/pygccxml/source/pyplusplus/examples/py_easybmp
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11604/pyplusplus/examples/py_easybmp
Modified Files:
create_easybmp.py
Log Message:
updating EasyBMP example to use new interface
Index: create_easybmp.py
===================================================================
RCS file: /cvsroot/pygccxml/source/pyplusplus/examples/py_easybmp/create_easybmp.py,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** create_easybmp.py 28 Feb 2006 07:31:33 -0000 1.11
--- create_easybmp.py 16 Mar 2006 06:35:41 -0000 1.12
***************
*** 8,15 ****
from environment import settings
from pygccxml import parser
- from pygccxml import declarations
from pyplusplus import code_creators
! from pyplusplus import module_creator
! from pyplusplus import file_writers
--- 8,14 ----
from environment import settings
from pygccxml import parser
from pyplusplus import code_creators
! from pyplusplus import decl_wrappers
! from pyplusplus import module_builder
***************
*** 22,196 ****
"""
! def identify_call_policies( decl ):
! """
! pyplusplus built-in call policies resolver can not and will not guess call
! policies for functions. Nevertheless, it is easy to setup custom call
! policies resolver. The only requirement on custom call policy resolver is
! to be callable, that takes 1 argument - C++ "callable" declaration. It could
! be constructor, member or free function, regular or casting operators.
!
! In this example I reuse built-in call policies resolver, and if it can not
! fiind out call policies I choose call policies based on some fact.
! """
! built_in_resolver = module_creator.built_in_resolver_t()
! policy = built_in_resolver( decl )
! if policy:
! return policy
!
! if isinstance( decl, declarations.member_operator_t ) \
! and decl.symbol == '()' \
! and decl.parent.name == 'BMP':
! return code_creators.return_internal_reference()
! return None
!
! class easybmp_exporter_t:
! def __init__(self):
! self.__header_file = os.path.join( settings.easybmp_path, 'EasyBMP.h' )
!
! def read_declarations(self):
! """
! The first step in creating C++ - Python bindings is to read declarations
! from source files. This step is done by using pygccxml. First thing that
! you should do is to setup parser ( GCC-XML ). pygccxml.parser.config_t
! class is responsible for parser configuration. Basicaly, using config_t
! class you can setup:
! * GCC-XML binary path
! * include directories
! * working directory
! * [un]defined symbols
! See that class definition for more information.
!
! After you setup parser configuration you can read declarations from
! source files. There are 2 declaration readers:
! * pygccxml.parser.source_reader_t
! * pygccxml.parser.project_reader_t
! If you have to parse single file, then use source_reader_t, otherwise
! you'd better use project_reader_t. Please refere to pygccxml documentation
! for full explanation about those classes.
!
! In this example I read all declarations found in EasyBMP.h file and files
! that are included from it.
! """
! config = parser.config_t( gccxml_path=settings.gccxml_path
! , working_directory=settings.easybmp_path )
! reader = parser.source_reader_t( config )
! return reader.read_file( self.__header_file )
!
! def filter_declarations(self, decls ):
! """
! After you read declarations, you should leave only declarations, that
! you want to export to Python. I call this process "filtering". There are
! a lot of ways to filter out declarations:
! * by phisical location
! you can specify a list of files and directories, and all declarations
! that are not declared within those files will be removed
! * by namespace
! return declarations.find_declaration( decls
! , name="geometry"
! , type=declarations.namespace_t )
! * by defining some custom filter
! while defining custom filter, be careful in excluding namespaces,
! because thus you exclude all declarations defined in this namespace.s
! """
! return declarations.filtering.by_location( decls, [settings.easybmp_path] )
! def create_extmodule(self, decls):
! """
! 3'th step. In this step pyplusplus creates "code creators" tree from
! the set of declarations, you want to export. This step creates mapping
! between C++ declaration and instance of the pyplusplus class that will
! create code, needed to export the declaration.
! pyplusplus.module_creator.creator_t class is responsible for this step.
! In most cases you do not need to use this class at all. Instead of
! using this class consider to use pyplusplus.module_creator.create function.
! This function takes 2 arguments: module name and a list of declarations.
!
! In my case I should use this class in order to setup custom call policies
! resolver. creator.create() returns "main" code creator -
! pyplusplus.code_creators.module_t class instance. This code creator keeps
! all other code creators.
!
! This step is the most complex in the whole process.
! """
! creator = module_creator.creator_t( decls=decls
! , module_name=settings.module_name
! , create_castinig_constructor=True
! , call_policies_resolver_=identify_call_policies)
! return creator.create()
! def customize_extmodule( self, extmodule ):
! """
! Nobody is perfect, pyplusplus too. After you created
! pyplusplus.code_creators.module_t class instance it's time to do all
! customization on the yet generated code, before you actualy write the
! code to files.
!
! First and most common customization in open source project is to setup
! license. License text will apear as is within every generated file.
!
! Second common customization is to setup include directories. This will
! cause pyplusplus to generate code with relative include directives.
!
! You can also to setup precompiled header.
!
! Almost every code_creator has set of properties that could be changed.
!
! An other cool feature of pyplusplus is namespace aliasing.
! bpalias = code_creators.namespace_alias_t( alias="bp"
! , full_namespace_name="::boost::python")
! extmodule.adopt_creator( bpalias, extmodule.last_include_index() + 1 )
! All code that will be generated after "namespace bp = ::boost::python;"
! will use "bp" instead of "::boost::python". Nice!
!
! Last and may be the most important thing that you can do at this step
! is to create custom code creators and inject them into right place, within
! module_t code creator instance. Remember: you should be able to modify,
! add or delete almost every piece of yet not generated code. If you are
! not, just send me a mail.
! """
! global license
! extmodule.license = license
! #butifying include code generation
! extmodule.user_defined_directories.append( settings.easybmp_path )
! extmodule.precompiled_header = 'boost/python.hpp'
! #Adding EasyBMP.h as first include. It comes because of internal structure of EasyBMP
! extmodule.adopt_creator( code_creators.include_t( header=self.__header_file ), 2 )
! body_index = extmodule.creators.index( extmodule.body )
! bmp_call = code_creators.creator_finder.find_by_declaration_single(
! declarations.match_declaration_t( fullname='::BMP::operator()' )
! , extmodule.body )
! bmp_call.alias = 'GetRGBAPixel'
!
! def write_files( self, extmodule ):
! """
! Last step: to create file(s) with generated code. There are few options
! here:
! * you can write all generated code to single file. In this case you
! should specify destination file name.
! pyplusplus.file_writers.write_file function is your friend. It takes
! 2 arguments:
! * pyplusplus.code_creators.module_t instance
! * destination file name
!
! * you can write all generated code to multiple files. In this case
! you should specify destination directory name. In this case pyplusplus
! generates files as recomended here:
! www.boost.org/libs/python/doc/tutorial/doc/html/python/techniques.html#python.reducing_compiling_time
! If you don't like the way I do it, you can always write your own file writer.
! """
! file_writers.write_file(extmodule
! , os.path.join(settings.generated_files_dir
! , settings.module_name + '.cpp') )
!
! def create(self):
! decls_all = self.read_declarations()
! decls = self.filter_declarations(decls_all)
! extmodule = self.create_extmodule( decls )
! self.customize_extmodule( extmodule )
! self.write_files( extmodule )
!
! def export():
! exporter = easybmp_exporter_t()
! exporter.create()
if __name__ == '__main__':
--- 21,46 ----
"""
! def export():
! global license
! header_file = os.path.join( settings.easybmp_path, 'EasyBMP.h' )
! #create configuration for GCC-XML parser
! parser_config = parser.config_t( gccxml_path=settings.gccxml_path
! , working_directory=settings.easybmp_path )
! #initialize module builder
! mb = module_builder.module_builder_t( settings.module_name
! , [ header_file ]
! , parser_config )
! bmp_class = mb.class_( 'BMP' )
! call_operator = bmp_class.operator( symbol='()', recursive=False )
! call_operator.alias = 'GetRGBAPixel'
! call_operator.call_policies = decl_wrappers.return_internal_reference()
! #customizing code, before generation
! mb.module_creator.license = license
! mb.module_creator.user_defined_directories.append( settings.easybmp_path )
! mb.module_creator.precompiled_header = 'boost/python.hpp'
! mb.module_creator.adopt_creator( code_creators.include_t( header=header_file ), 2 )
! mb.write_file( os.path.join( settings.generated_files_dir, settings.module_name + '.cpp') )
if __name__ == '__main__':
|