[pygccxml-commit] SF.net SVN: pygccxml: [309] pyplusplus_dev/docs
Brought to you by:
mbaas,
roman_yakovenko
From: <rom...@us...> - 2006-07-17 19:37:31
|
Revision: 309 Author: roman_yakovenko Date: 2006-07-17 12:37:17 -0700 (Mon, 17 Jul 2006) ViewCVS: http://svn.sourceforge.net/pygccxml/?rev=309&view=rev Log Message: ----------- adding documentation to generated code Modified Paths: -------------- pyplusplus_dev/docs/pyplusplus.rest pyplusplus_dev/pyplusplus/module_builder/builder.py pyplusplus_dev/pyplusplus/module_creator/creator.py pyplusplus_dev/unittests/fundamental_tester_base.py Added Paths: ----------- pyplusplus_dev/contrib/doc_extractors/ pyplusplus_dev/contrib/doc_extractors/doxygen.py pyplusplus_dev/contrib/doc_extractors/readme.txt Added: pyplusplus_dev/contrib/doc_extractors/doxygen.py =================================================================== --- pyplusplus_dev/contrib/doc_extractors/doxygen.py (rev 0) +++ pyplusplus_dev/contrib/doc_extractors/doxygen.py 2006-07-17 19:37:17 UTC (rev 309) @@ -0,0 +1,112 @@ +""" +extracting from C++ doxygen documented file +Author G.D. +""" + +class doc_extractor: + """ + extracts doxigen styled documentation from source + or generates from description + """ + def __init__(self): + #for caching source + self.file_name = None + self.source = None + + def __call__(self, declaration): + try: + if self.file_name != declaration.location.file_name: + self.file_name = declaration.location.file_name + self.source = open(declaration.location.file_name).readlines() + + find_block_end = False + doc_lines = [] + for lcount in xrange(declaration.location.line - 1, -1, -1): + line = source[lcount] + if not find_block_end: + try: + if line.rstrip()[-2:] == "*/": + find_block_end = True + except: + pass + if find_block_end: + try: + if line.lstrip()[:2] == "/*": + find_block_end = False + except: + pass + final_str = clear_str(line) + if not find_block_end and code(line): + break + if final_str: + doc_lines.insert(0, final_str) + + if doc_lines: + doc_lines.insert(0, self.get_generic_doc()) + return ''.join(doc_lines) + + except: + pass + + return self.get_generic_doc(declaration) + + def get_generic_doc(self, declaration): + """ + generate call information about function or method + """ + try: + return "Help on %s\n" % str(declaration) + except: + pass + + return '' + + +def clear_str(str): + """ + replace */! by Space and \breaf, \fn, \param, ... + """ + clean = lambda str, sym, change2 = '': str.replace(sym, change2) + + str = reduce(clean, [str, '/', '*', '!', "\brief", "\fn",\ + "@brief", "@fn", "@ref", "\ref"]) + + str = clean(str, "@param", "Param: ") + str = clean(str, "\param", "Param: ") + str = clean(str, "@ingroup", "Group") + str = clean(str, "\ingroup", "Group") + str = clean(str, "@return", "It return") + str = clean(str, "\return", "It return") + return " " + str.lstrip() + + +def code(str): + """ + detect str is code? + """ + try: + beg = str.lstrip()[:2] + return beg != "//" and beg != "/*" + except: + pass + return False + +if __name__ == '__main__': + class loc: + def __init__(self, f, l): + self.file_name = f + self.line = l + + class x_decl: + def __init__(self, str, file_name, line): + self.str = str + self.location = loc(file_name, line) + + def __str__(self): + return self.str + + print doc_extractor()(x_decl("myfunc(int x, int y)","core.h",45)) + print doc_extractor()(x_decl("","core.h",209)) + + + Added: pyplusplus_dev/contrib/doc_extractors/readme.txt =================================================================== --- pyplusplus_dev/contrib/doc_extractors/readme.txt (rev 0) +++ pyplusplus_dev/contrib/doc_extractors/readme.txt 2006-07-17 19:37:17 UTC (rev 309) @@ -0,0 +1,19 @@ +Content: + This directory contains functionality that extracts documentation string +from C++ source files. + +How to integrate the functionality with pyplusplus? + + mb = module_builder_t( ... ) + mb.build_code_creator( ..., doc_extractor=my_doc_extractor ) + +What is "my_doc_extractor"? Well, "my_doc_extractor" is callable object, +that takes only one argument - declaration reference and returns documentation +string. Something like this: + +def my_doc_extractor( decl ): + return decl.location.file_name + str( decl.location.line ) + +Yes, every declaration contains next information: + 1. Full path to file it was defined in. + 2. Line number. Modified: pyplusplus_dev/docs/pyplusplus.rest =================================================================== --- pyplusplus_dev/docs/pyplusplus.rest 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/docs/pyplusplus.rest 2006-07-17 19:37:17 UTC (rev 309) @@ -175,6 +175,9 @@ * user license is written at the top of every file + * extracting documentation from source files and integrating it with generated + source code + * ... ------- Modified: pyplusplus_dev/pyplusplus/module_builder/builder.py =================================================================== --- pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/pyplusplus/module_builder/builder.py 2006-07-17 19:37:17 UTC (rev 309) @@ -173,7 +173,8 @@ , call_policies_resolver_=None , types_db=None , target_configuration=None - , enable_indexing_suite=True): + , enable_indexing_suite=True + , doc_extractor=None): """ Creates L{module_t} code creator. @@ -187,6 +188,10 @@ @param call_policies_resolver_: callable, that will be invoked on every calldef object. It should return call policies. @type call_policies_resolver_: callable + + @param doc_extractor: callable, that takes as argument reference to declaration + and returns documentation string + @type doc_extractor: callable or None """ creator = mcreator_package.creator_t( self.global_ns , module_name @@ -195,7 +200,8 @@ , call_policies_resolver_ , types_db , target_configuration - , enable_indexing_suite) + , enable_indexing_suite + , doc_extractor) self.__code_creator = creator.create() #I think I should ask users, what they expect #self.__code_creator.user_defined_directories.append( self.__working_dir ) Modified: pyplusplus_dev/pyplusplus/module_creator/creator.py =================================================================== --- pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/pyplusplus/module_creator/creator.py 2006-07-17 19:37:17 UTC (rev 309) @@ -3,14 +3,15 @@ # accompanying file LICENSE_1_0.txt or copy at # http://www.boost.org/LICENSE_1_0.txt) +import time +import types_database +import class_organizer +import call_policies_resolver from pygccxml import declarations +from pyplusplus import decl_wrappers from pyplusplus import code_creators -import class_organizer -import call_policies_resolver -import types_database from pyplusplus import code_repository -from sets import Set as set -from pyplusplus import decl_wrappers +from pyplusplus import _logging_ ACCESS_TYPES = declarations.ACCESS_TYPES VIRTUALITY_TYPES = declarations.VIRTUALITY_TYPES @@ -67,7 +68,8 @@ , call_policies_resolver_=None , types_db=None , target_configuration=None - , enable_indexing_suite=True): + , enable_indexing_suite=True + , doc_extractor=None): """Constructor. @param decls: Declarations that should be exposed in the final module. @@ -77,6 +79,7 @@ @param call_policies_resolver_: Callable that takes one declaration (calldef_t) as input and returns a call policy object which should be used for this declaration. @param types_db: ...todo... @param target_configuration: A target configuration object can be used to customize the generated source code to a particular compiler or a particular version of Boost.Python. + @param doc_extractor: callable, that takes as argument declaration reference and returns documentation string @type decls: list of declaration_t @type module_name: str @type boost_python_ns_name: str @@ -84,9 +87,11 @@ @type call_policies_resolver_: callable @type types_db: L{types_database_t<types_database.types_database_t>} @type target_configuration: L{target_configuration_t<code_creators.target_configuration_t>} + @type doc_extractor: callable """ declarations.decl_visitor_t.__init__(self) - + self.logger = _logging_.loggers.module_builder + self.__enable_indexing_suite = enable_indexing_suite self.__target_configuration = target_configuration if not self.__target_configuration: @@ -113,22 +118,32 @@ self.__module_body = code_creators.module_body_t( name=module_name ) self.__extmodule.adopt_creator( self.__module_body ) - decls = declarations.make_flatten( decls ) - self.__decls = self._filter_decls( self._reorder_decls( self._prepare_decls( decls ) ) ) + prepared_decls = self._prepare_decls( decls, doc_extractor ) + self.__decls = self._filter_decls( self._reorder_decls( prepared_decls ) ) self.curr_code_creator = self.__module_body self.curr_decl = None self.__cr_array_1_included = False self.__array_1_registered = set() #(type.decl_string,size) self.__free_operators = [] - - def _prepare_decls( self, decls ): + + def _prepare_decls( self, decls, doc_extractor ): + decls = declarations.make_flatten( decls ) #leave only declarations defined under namespace, but remove namespaces decls = filter( lambda x: not isinstance( x, declarations.namespace_t ) \ and isinstance( x.parent, declarations.namespace_t ) , decls ) #leave only decls that should be exported decls = filter( lambda x: not x.ignore, decls ) + if doc_extractor: + start_time = time.clock() + self.logger.debug( 'Documentation extraction process started.' ) + + for decl in decls: + decl.documentation = doc_extractor( decl ) + + self.logger.debug( 'Documentation extraction process finished in %F seconds' + % ( time.clock() - start_time ) ) return decls def _reorder_decls(self, decls ): Modified: pyplusplus_dev/unittests/fundamental_tester_base.py =================================================================== --- pyplusplus_dev/unittests/fundamental_tester_base.py 2006-07-17 18:18:24 UTC (rev 308) +++ pyplusplus_dev/unittests/fundamental_tester_base.py 2006-07-17 19:37:17 UTC (rev 309) @@ -60,8 +60,9 @@ for decl in mb.decls(): decl.documentation = '"documentation"' self.customize( mb ) + doc_extractor = lambda decl: decl.documentation if not mb.has_code_creator(): - mb.build_code_creator( self.__module_name ) + mb.build_code_creator( self.__module_name, doc_extractor=doc_extractor ) mb.code_creator.std_directories.extend( autoconfig.scons_config.cpppath ) mb.code_creator.user_defined_directories.append( autoconfig.data_directory ) mb.code_creator.precompiled_header = "boost/python.hpp" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |