diff --git a/py++/build_header.py b/py++/build_header.py new file mode 100644 index 0000000000000000000000000000000000000000..44f161c5b6042cfaeb67c04a878a9f6ebdf46976 --- /dev/null +++ b/py++/build_header.py @@ -0,0 +1,91 @@ +###### +## Generate Py++ inclusion header +###### + +import wrapper_config + +# Set the paths to be searched for header files +header_paths = [ + wrapper_config.niflib_path + "/include", + wrapper_config.niflib_path + "/include/gen", + wrapper_config.niflib_path + "/include/obj" +] + +# Set explicit includes +header_include = [ + wrapper_config.niflib_path + "/include/niflib.h", + wrapper_config.niflib_path + "/include/Ref.h", + wrapper_config.niflib_path + "/include/Type.h", + wrapper_config.niflib_path + "/include/nif_math.h", + wrapper_config.niflib_path + "/include/Key.h", + wrapper_config.niflib_path + "/include/nif_basic_types.h" +] + +# Set the regexps for file exclusion +header_exclude = [ + "niflib/include/[a-zA-Z\.\_\-]+\.h" +] + +#### + +import os, re + +def hasExtension(file, ext): + fext = file.rsplit('.', -1)[-1] + return (fext in ext) + +header = [] +pattern = "|".join(header_exclude) +p = re.compile(pattern) + +for path in header_paths: + dir_files = os.listdir(path) + for file in dir_files: + m = p.match(path + '/' + file) + if m: + continue + if hasExtension(file, ['h', 'hpp']): + header_include.append(path +'/' + file) + +for file in header_include: + header.append("#include \"%s\"\n" % file) + +#header.append("using namespace Niflib;\n\n"); +header.append("\n"); +header.append("/* This namespace is not going to be exported */\n") +header.append("namespace NoExport {\n\n") +header.append(" /* Auxiliary function for template export */\n") +header.append(" inline void export_obj_templates() {\n") +header.append(" Niflib::NiObjectRef CastObj;\n\n") + +NiObjects = [] +for obj in os.listdir(wrapper_config.niflib_path + "/include/obj"): + obj_ = obj.split('.', 2)[0] + if hasExtension(obj, 'h') and not obj_ in NiObjects: + NiObjects.append(obj_) + +for obj in NiObjects: + header.append(" /* Object %s */\n" % obj) + #header.append(" typedef Niflib::Ref<Niflib::%s> %sRef;\n" % (obj, obj)) + #header.append(" sizeof(%sRef);\n" % obj) + header.append(" sizeof(Niflib::Ref<Niflib::%s>);\n" % obj) + header.append(" Niflib::DynamicCast<Niflib::%s>(CastObj);\n" % obj) + header.append(" Niflib::StaticCast <Niflib::%s>(CastObj);\n" % obj) + header.append(" \n") + +header.append(" /* Internal Containers */\n") +for int_cont in wrapper_config.internal_containers: + header.append(" sizeof(%s);\n" % int_cont) +header.append("\n") + +header.append(" }\n\n") +header.append("}\n\n") + +headerfile = open("pyNiflib.h","w") +headerfile.writelines(header) +headerfile.close() + +project_files = [ r"pyNiflib.h" ] +for hfile in header_include: + basename = hfile.rsplit(".", 2)[0] + #project_files.append(r"%s.cpp" % basename) diff --git a/py++/build_wrapper.py b/py++/build_wrapper.py new file mode 100644 index 0000000000000000000000000000000000000000..a6e38ccb9dd821e2bef41404b77c5d3bcb1ba66b --- /dev/null +++ b/py++/build_wrapper.py @@ -0,0 +1,104 @@ +###### +## Build boost::python wrapper file +###### + +import os, re +from pyplusplus import module_builder +from pygccxml import declarations + +import wrapper_config + +# The Niflib license +niflib_license = \ +"""/* +Copyright (c) 2005, NIF File Format Library and Tools +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + * Neither the name of the NIF File Format Library and Tools + project nor the names of its contributors may be used to endorse + or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +*/ +""" + +#### + +# Function to get the type name of a template function +def TypeName( decl_string ): + return declarations.templates.args(decl_string)[0].rsplit('::', 2)[-1] + +# Function to rename the Cast<T> functions +def rename_casts( cast ): + cast.rename( cast.name + 'To' + TypeName(cast.decl_string) ) + cast.name = cast.demangled_name + +# Function to rename the Ref<T> functions +def rename_refs( ref ): + ref.rename( TypeName(ref.decl_string) + "Ref" ) + +#### + +# Creating an instance of class that will help you to expose your declarations +mb = module_builder.module_builder_t( [r"pyNiflib.h"] + , include_paths = [wrapper_config.niflib_path + '/include', wrapper_config.niflib_path + '/include/gen', wrapper_config.niflib_path + '/include/obj'] + , indexing_suite_version = 2 ) + +# Set the max. number of template arguments +mb.BOOST_PYTHON_MAX_ARITY = 20 + +# Rename the Ref<T> templates +refs = mb.classes ( lambda decl: ( decl.name.startswith('Ref<') ) ) +map( rename_refs, refs ) + +# Rename the DynamicCast<T> and StaticCast<T> templates +casts = mb.free_functions ( lambda decl: ( decl.name == 'DynamicCast' or decl.name == 'StaticCast' ) ) +map( rename_casts, casts ) + +# Get all operators +mb.member_operators().exclude() + +# Optimize the queries +mb.run_query_optimizer() + +# Exclude everything +mb.global_ns.exclude() + +# Include the main Niflib namespace +mb.namespace('Niflib').include() + +# Create code creator. After this step you should not modify/customize declarations. +mb.build_code_creator( module_name='pyNiflib' ) + +# Set the Niflib license for the output +mb.code_creator.license = niflib_license + +# Well, don't you want to see what is going on? +mb.print_declarations(mb.namespace('Niflib')) + +# Writing code to file. +mb.write_module( './pyNiflib.cpp' ) diff --git a/py++/wrapper_config.py b/py++/wrapper_config.py new file mode 100644 index 0000000000000000000000000000000000000000..e06aa46e055f30e101e102712b9eb7a43fd5a887 --- /dev/null +++ b/py++/wrapper_config.py @@ -0,0 +1,13 @@ +###### +## Configure pyNiflib +###### + +# The path to the Niflib folder +niflib_path = "../niflib" + +# Internal containers - those are not typedef'd +internal_containers = \ +[ + "std::map<Niflib::Ref<Niflib::NiObject>,unsigned int,std::less<Niflib::Ref<Niflib::NiObject> >,std::allocator<std::pair<const Niflib::Ref<Niflib::NiObject>, unsigned int> > >", + "std::list<unsigned int,std::allocator<unsigned int> >" +] \ No newline at end of file