[pygccxml-commit] SF.net SVN: pygccxml: [1203] pyplusplus_dev
Brought to you by:
mbaas,
roman_yakovenko
|
From: <rom...@us...> - 2007-12-12 09:10:23
|
Revision: 1203
http://pygccxml.svn.sourceforge.net/pygccxml/?rev=1203&view=rev
Author: roman_yakovenko
Date: 2007-12-12 01:10:21 -0800 (Wed, 12 Dec 2007)
Log Message:
-----------
adding new file writer balanced_files.py
Modified Paths:
--------------
pyplusplus_dev/pyplusplus/file_writers/__init__.py
pyplusplus_dev/pyplusplus/file_writers/multiple_files.py
pyplusplus_dev/pyplusplus/module_builder/builder.py
pyplusplus_dev/pyplusplus/utils/__init__.py
pyplusplus_dev/unittests/test_all.py
Added Paths:
-----------
pyplusplus_dev/pyplusplus/file_writers/balanced_files.py
pyplusplus_dev/unittests/balanced_files_tester.py
pyplusplus_dev/unittests/data/balanced_files_to_be_exported.hpp
Modified: pyplusplus_dev/pyplusplus/file_writers/__init__.py
===================================================================
--- pyplusplus_dev/pyplusplus/file_writers/__init__.py 2007-12-11 10:21:11 UTC (rev 1202)
+++ pyplusplus_dev/pyplusplus/file_writers/__init__.py 2007-12-12 09:10:21 UTC (rev 1203)
@@ -20,6 +20,7 @@
from writer import writer_t
from single_file import single_file_t
from multiple_files import multiple_files_t
+from balanced_files import balanced_files_t
from class_multiple_files import class_multiple_files_t
from md5sum_repository import repository_t
from md5sum_repository import cached_repository_t
@@ -45,6 +46,12 @@
mfs.write()
return mfs.written_files
+def write_balanced_files( extmodule, dir_path, number_of_buckets, files_sum_repository=None, encoding='ascii' ):
+ """writes extmodule to fixed number of multiple cpp files"""
+ mfs = balanced_files_t( extmodule, dir_path, number_of_buckets, files_sum_repository=files_sum_repository, encoding=encoding )
+ mfs.write()
+ return mfs.written_files
+
def write_class_multiple_files( extmodule, dir_path, huge_classes, files_sum_repository, encoding='ascii' ):
"""writes extmodule to multiple files and splits huge classes to few source files"""
mfs = class_multiple_files_t( extmodule, dir_path, huge_classes, files_sum_repository=files_sum_repository, encoding=encoding )
Added: pyplusplus_dev/pyplusplus/file_writers/balanced_files.py
===================================================================
--- pyplusplus_dev/pyplusplus/file_writers/balanced_files.py (rev 0)
+++ pyplusplus_dev/pyplusplus/file_writers/balanced_files.py 2007-12-12 09:10:21 UTC (rev 1203)
@@ -0,0 +1,64 @@
+# Copyright 2004 Giovanni Beltrame
+# 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 a class that writes L{code_creators.module_t} to multiple files"""
+
+import os
+import math
+import multiple_files
+from pyplusplus import messages
+from pyplusplus import _logging_
+from pygccxml import declarations
+from pyplusplus import decl_wrappers
+from pyplusplus import code_creators
+from pyplusplus.utils import split_sequence
+
+#TODO: to add namespace_alias_t classes
+class balanced_files_t(multiple_files.multiple_files_t):
+ """
+ This class implements classic strategy of deviding classes to files
+ one class in one header + source files.
+ """
+ HEADER_EXT = '.pypp.hpp'
+ SOURCE_EXT = '.pypp.cpp'
+
+ def __init__( self
+ , extmodule
+ , directory_path
+ , number_of_buckets
+ , write_main=True
+ , files_sum_repository=None
+ , encoding='ascii'):
+ """Constructor.
+
+ @param extmodule: The root of a code creator tree
+ @type extmodule: module_t
+ @param directory_path: The output directory where the source files are written
+ @type directory_path: str
+
+ @param write_main: if it is True, the class will write out a main file
+ that calls all the registration methods.
+ @type write_main: boolean
+ """
+ multiple_files.multiple_files_t.__init__( self, extmodule, directory_path, write_main, files_sum_repository, encoding)
+ self.number_of_buckets = number_of_buckets
+
+ def split_classes( self ):
+ class_creators = filter( lambda x: isinstance(x, ( code_creators.class_t, code_creators.class_declaration_t ) )
+ , self.extmodule.body.creators )
+
+ class_creators = filter( lambda cc: not cc.declaration.already_exposed
+ , class_creators )
+
+ buckets = split_sequence(class_creators, len(class_creators)/self.number_of_buckets )
+ if len(buckets) > self.number_of_buckets:
+ buckets[len(buckets)-2] += buckets[len(buckets)-1]
+ buckets = buckets[:len(buckets)-1]
+
+ for index, bucket in enumerate( buckets ):
+ self.split_creators( bucket
+ , '_classes_%d' % (index+1)
+ , 'register_classes_%d' % (index+1)
+ , -1 )
Modified: pyplusplus_dev/pyplusplus/file_writers/multiple_files.py
===================================================================
--- pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2007-12-11 10:21:11 UTC (rev 1202)
+++ pyplusplus_dev/pyplusplus/file_writers/multiple_files.py 2007-12-12 09:10:21 UTC (rev 1203)
@@ -290,6 +290,13 @@
self.logger.error( os.linesep.join( msg ) )
raise
+ def split_classes( self ):
+ # Obtain a list of all class creators...
+ class_creators = filter( lambda x: isinstance(x, ( code_creators.class_t, code_creators.class_declaration_t ) )
+ , self.extmodule.body.creators )
+ # ...and write a .h/.cpp file for each class
+ map( self.split_class, class_creators )
+
def create_value_traits_header_name( self, value_class ):
return "_" + value_class.alias + "__value_traits" + self.HEADER_EXT
@@ -308,6 +315,9 @@
, value_traits.create() ) )
value_traits.create = lambda: ''
+ def split_values_traits( self ):
+ map( self.split_value_traits, self.__value_traits )
+
def split_creators( self, creators, pattern, function_name, registrator_pos ):
"""Write non-class creators into a particular .h/.cpp file.
@@ -379,14 +389,8 @@
self.extmodule.do_include_dirs_optimization()
- map( self.split_value_traits, self.__value_traits )
-
- # Obtain a list of all class creators...
- class_creators = filter( lambda x: isinstance(x, ( code_creators.class_t, code_creators.class_declaration_t ) )
- , self.extmodule.body.creators )
- # ...and write a .h/.cpp file for each class
- map( self.split_class, class_creators )
-
+ self.split_values_traits()
+ self.split_classes()
self.split_enums()
self.split_global_variables()
self.split_free_functions()
Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py
===================================================================
--- pyplusplus_dev/pyplusplus/module_builder/builder.py 2007-12-11 10:21:11 UTC (rev 1202)
+++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2007-12-12 09:10:21 UTC (rev 1203)
@@ -317,6 +317,20 @@
self.__merge_user_code()
file_writers.write_file( self.code_creator, file_name, encoding=self.encoding )
+ def __work_on_unused_files( self, dir_name, written_files, on_unused_file_found ):
+ all_files = os.listdir( dir_name )
+ all_files = map( lambda fname: os.path.join( dir_name, fname ), all_files )
+ all_files = filter( file_writers.has_pypp_extenstion, all_files )
+
+ unused_files = set( all_files ).difference( set( written_files ) )
+ for fpath in unused_files:
+ try:
+ if on_unused_file_found is os.remove:
+ self.logger.info( 'removing file "%s"' % fpath )
+ on_unused_file_found( fpath )
+ except Exception, error:
+ self.logger.exception( "Exception was catched, while executing 'on_unused_file_found' function." )
+
def split_module( self
, dir_name
, huge_classes=None
@@ -358,22 +372,49 @@
, huge_classes
, files_sum_repository=files_sum_repository
, encoding=self.encoding)
+ self.__work_on_unused_files( dir_name, written_files, on_unused_file_found )
- all_files = os.listdir( dir_name )
- all_files = map( lambda fname: os.path.join( dir_name, fname ), all_files )
- all_files = filter( file_writers.has_pypp_extenstion, all_files )
+ return written_files
- unused_files = set( all_files ).difference( set( written_files ) )
- for fpath in unused_files:
- try:
- if on_unused_file_found is os.remove:
- self.logger.info( 'removing file "%s"' % fpath )
- on_unused_file_found( fpath )
- except Exception, error:
- self.logger.exception( "Exception was catched, while executing 'on_unused_file_found' function." )
+ def balanced_split_module( self
+ , dir_name
+ , number_of_files
+ , on_unused_file_found=os.remove
+ , use_files_sum_repository=True):
+ """
+ Writes module to fixed number of multiple cpp files
+ @param number_of_files: the desired number of generated cpp files
+ @type number_of_files: int
+
+ @param dir_name: directory name
+ @type dir_name: string
+
+ @param on_unused_file_found: callable object that represents the action that should be taken on
+ file, which is no more in use
+
+ @use_files_sum_repository: Py++ can generate file, which will contain md5 sum of every generated file.
+ Next time you generate code, md5sum will be loaded from the file and compared.
+ This could speed-up code generation process by 10-15%.
+ """
+ self.__merge_user_code()
+
+ files_sum_repository = None
+ if use_files_sum_repository:
+ cache_file = os.path.join( dir_name, self.code_creator.body.name + '.md5.sum' )
+ files_sum_repository = file_writers.cached_repository_t( cache_file )
+
+ written_files = file_writers.write_balanced_files( self.code_creator
+ , dir_name
+ , number_of_buckets=number_of_files
+ , files_sum_repository=files_sum_repository
+ , encoding=self.encoding)
+
+ self.__work_on_unused_files( dir_name, written_files, on_unused_file_found )
+
return written_files
+
#select decl(s) interfaces
def decl( self, name=None, function=None, header_dir=None, header_file=None, recursive=None ):
"""Please see L{decl_wrappers.scopedef_t} class documentation"""
Modified: pyplusplus_dev/pyplusplus/utils/__init__.py
===================================================================
--- pyplusplus_dev/pyplusplus/utils/__init__.py 2007-12-11 10:21:11 UTC (rev 1202)
+++ pyplusplus_dev/pyplusplus/utils/__init__.py 2007-12-12 09:10:21 UTC (rev 1203)
@@ -40,7 +40,7 @@
creator.parent.remove_creator( creator )
def split_sequence(seq, bucket_size):
- #split sequence to buclets, where every will contain maximum bucket_size items
+ #split sequence to buckets, where every will contain maximum bucket_size items
seq_len = len( seq )
if seq_len <= bucket_size:
return [ seq ]
Added: pyplusplus_dev/unittests/balanced_files_tester.py
===================================================================
--- pyplusplus_dev/unittests/balanced_files_tester.py (rev 0)
+++ pyplusplus_dev/unittests/balanced_files_tester.py 2007-12-12 09:10:21 UTC (rev 1203)
@@ -0,0 +1,88 @@
+# Copyright 2004 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 sys
+import unittest
+import autoconfig
+from pyplusplus import utils
+import fundamental_tester_base
+from pygccxml import declarations
+from pyplusplus import module_builder
+from pyplusplus.module_builder import call_policies
+
+class tester_t(fundamental_tester_base.fundamental_tester_base_t):
+ EXTENSION_NAME = 'balanced_files'
+
+ def __init__( self, *args ):
+ fundamental_tester_base.fundamental_tester_base_t.__init__(
+ self
+ , tester_t.EXTENSION_NAME
+ , indexing_suite_version=1
+ , *args )
+ self.files = []
+
+ def customize( self, mb ):
+ mb.global_ns.exclude()
+
+ nm_t = declarations.remove_declarated( mb.global_ns.typedef( 'naive_matrix_t' ).type )
+ nm_t.include()
+
+ exposed_db = utils.exposed_decls_db_t()
+
+ exposed_db.register_decls( mb.global_ns )
+ exposed_db.save( autoconfig.build_dir )
+ mb.register_module_dependency( autoconfig.build_dir )
+
+ sm = mb.global_ns.namespace( name='split_module' )
+ sm.include()
+ sm.class_( 'op_struct' ).exclude()
+
+ mb.free_function( 'check_overload' ).add_declaration_code( '//hello check_overload' )
+ mb.free_function( 'get_opaque' ).add_declaration_code( '//hello get_opaque' )
+
+ mb.calldefs( 'check_overload' ).use_overload_macro = True
+ mb.calldefs( 'get_opaque' ).call_policies \
+ = call_policies.return_value_policy( call_policies.return_opaque_pointer )
+
+ mb.class_( 'op_struct' ).exclude()
+ item = mb.class_( 'item_t' )
+ item.add_declaration_code( '//hello world' )
+ nested = item.class_( 'nested_t' )
+ nested.add_declaration_code( '//hello nested decl' )
+ nested.add_registration_code( '//hello nested reg', False )
+ mb.free_fun( 'create_empty_mapping' ).include()
+
+ def generate_source_files( self, mb ):
+ files = mb.balanced_split_module( autoconfig.build_dir, 2, on_unused_file_found=lambda fpath: fpath )
+ self.files = filter( lambda fname: fname.endswith( 'cpp' ), files )
+
+ def get_source_files( self ):
+ return self.files
+
+ def run_tests(self, module):
+ module.get_opaque()
+ item = module.item_t()
+ item.get_opaque()
+ module.check_overload()
+ item.check_overload()
+ item = module.TestClass1()
+ if item.func() != 1: raise Exception
+ item = module.TestClass2()
+ if item.func() != 2: raise Exception
+ item = module.TestClass3()
+ if item.func() != 3: raise Exception
+
+
+def create_suite():
+ suite = unittest.TestSuite()
+ suite.addTest( unittest.makeSuite(tester_t))
+ return suite
+
+def run_suite():
+ unittest.TextTestRunner(verbosity=2).run( create_suite() )
+
+if __name__ == "__main__":
+ run_suite()
Added: pyplusplus_dev/unittests/data/balanced_files_to_be_exported.hpp
===================================================================
--- pyplusplus_dev/unittests/data/balanced_files_to_be_exported.hpp (rev 0)
+++ pyplusplus_dev/unittests/data/balanced_files_to_be_exported.hpp 2007-12-12 09:10:21 UTC (rev 1203)
@@ -0,0 +1,90 @@
+// Copyright 2004 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)
+
+#ifndef __split_module_to_be_exported_hpp__
+#define __split_module_to_be_exported_hpp__
+
+#include "boost/shared_ptr.hpp"
+//#include BOOST_HASH_MAP_HEADER
+#include <map>
+#include <vector>
+#include <string>
+
+namespace split_module{
+
+typedef std::vector< std::vector< int > > naive_matrix_t;
+
+class TestClass1 {
+
+public:
+ int func() {
+ return 1;
+ }
+
+};
+
+class TestClass2 {
+
+public:
+ int func() {
+ return 2;
+ }
+
+};
+
+class TestClass3 {
+
+public:
+ int func() {
+ return 3;
+ }
+};
+
+
+inline naive_matrix_t create_zero_matrix( unsigned int x ){
+ return naive_matrix_t();
+};
+
+
+struct op_struct{};
+
+inline op_struct* get_opaque(){
+ return 0;
+}
+
+inline void check_overload( int i=0, int j=1, int k=2 ){
+}
+
+
+struct item_t{
+
+ enum EColor{ red, blue };
+ enum EFruit{ apple, orange };
+
+ item_t(){}
+ item_t( int ){}
+
+ void do_nothing(){}
+ int do_something(){ return 1; }
+
+ op_struct* get_opaque(){ return 0; }
+
+ void check_overload( int i=0, int j=1, int k=2 ){}
+
+ int m_dummy;
+
+ struct nested_t{};
+};
+
+//typedef BOOST_STD_EXTENSION_NAMESPACE::hash_map< std::string, boost::shared_ptr< item_t > > str2item_t;
+typedef std::map< std::string, boost::shared_ptr< item_t > > str2item_t;
+inline str2item_t create_empty_mapping(){
+ return str2item_t();
+}
+
+}
+
+
+#endif//__split_module_to_be_exported_hpp__
Modified: pyplusplus_dev/unittests/test_all.py
===================================================================
--- pyplusplus_dev/unittests/test_all.py 2007-12-11 10:21:11 UTC (rev 1202)
+++ pyplusplus_dev/unittests/test_all.py 2007-12-12 09:10:21 UTC (rev 1203)
@@ -97,6 +97,7 @@
import vector_with_shared_data_tester
import constructors_bug_tester
import precompiled_header_tester
+import balanced_files_tester
testers = [
@@ -182,6 +183,7 @@
, templates_tester
, constructors_bug_tester
, precompiled_header_tester
+ , balanced_files_tester
]
class module_runner_t( object ):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|