11#!/usr/bin/python
22# ----------------- BEGIN LICENSE BLOCK ---------------------------------
33#
4- # Copyright (c) 2019-2020 Intel Corporation
4+ # Copyright (c) 2019-2022 Intel Corporation
55#
66# ----------------- END LICENSE BLOCK -----------------------------------
77
@@ -33,15 +33,15 @@ def get_list_of_files(directory, ignore_files):
3333 for ignore_file in ignore_files :
3434 if full_path .find (ignore_file ) != - 1 :
3535 skip = True
36- print ("Skipping file: " + full_path )
36+ print ("Skipping file: " + full_path )
3737 if not skip :
3838 if full_path .endswith (".h" ) or full_path .endswith (".hpp" ):
3939 all_files .append (full_path )
4040
4141 return all_files
4242
4343
44- def generate_python_wrapper (header_directories , include_paths , library_name , cpp_filename , declarations , main_namespace = "" , ignore_declarations = {}, ignore_files = {}):
44+ def generate_python_wrapper (header_directories , include_paths , library_name , cpp_filename , declarations , main_namespace = "" , ignore_declarations = {}, ignore_files = {}, add_declarations = {} ):
4545 """
4646 Function to generate Python-C++ binding code by calling pygccxml and py++
4747
@@ -60,27 +60,30 @@ def generate_python_wrapper(header_directories, include_paths, library_name, cpp
6060 :type ignore_declarations: list<string>
6161 :param ignore_files: a list of files to be ignored
6262 :type ignore_files: list<string>
63+ :param add_declarations: a list of declarations to be explicitly enabled searched for in
64+ against the full declaration string resulting from '"{}".format(decl)' output
65+ (useful e.g. for typedefs to template types which are not as such visible in the delcarations)
66+ :type add_declarations: list<string>
6367 :return:
6468 """
6569
6670 warnings .filterwarnings (action = "once" , category = DeprecationWarning )
6771
6872 # Find out the xml generator (gccxml or castxml)
6973 generator_path , generator_name = utils .find_xml_generator ()
70- compiler = "g++"
71- compiler_path = "/usr/bin/g++"
74+ compiler = "@CXX@"
7275
7376 # Create configuration for CastXML
7477 xml_generator_config = parser .xml_generator_configuration_t (
7578 xml_generator_path = generator_path ,
7679 xml_generator = generator_name ,
7780 compiler = compiler ,
78- compiler_path = compiler_path ,
7981 start_with_declarations = declarations )
8082
8183 # Set include dirs and cflags to avoid warnings and errors
8284 xml_generator_config .append_cflags ("-std=c++@CMAKE_CXX_STANDARD@" )
8385 xml_generator_config .append_cflags ("-Wno-error=invalid-constexpr" )
86+ xml_generator_config .append_cflags ("-DSAFE_DATATYPES_EXPLICIT_CONVERSION=1" )
8487
8588 for inc_dir in include_paths :
8689 xml_generator_config .include_paths .append (inc_dir )
@@ -124,32 +127,57 @@ def generate_python_wrapper(header_directories, include_paths, library_name, cpp
124127 top_namespace , main_namespace ))
125128
126129 for decl in builder .decls ():
127- for ignore_declaration in ignore_declarations :
128- if ignore_declaration in decl .name or ignore_declaration in decl .alias :
129- decl .exclude ()
130- decl .ignore = True
131- decl .already_exposed = True
132- # print("declaration to ignore found: {} (alias {})".format(decl, decl.alias))
133- break
130+ decl_full_string_and_type = "{}" .format (decl )
131+ # print("declaration {} (alias {}, full {})".format(decl.name, decl.alias, decl_full_string_and_type))
134132 if main_namespace != "" :
135- if isinstance (decl , decl_wrappers .class_wrapper .class_t ) or isinstance (decl , decl_wrappers .class_wrapper .class_declaration_t ) or isinstance (decl , decl_wrappers .typedef_wrapper .typedef_t ):
136- decl_full_string = "{}" . format ( decl )
133+ if isinstance (decl , decl_wrappers .class_wrapper .class_t ) or isinstance (decl , decl_wrappers .class_wrapper .class_declaration_t ) or isinstance (decl , decl_wrappers .typedef_wrapper .typedef_t ) or isinstance ( decl , decl_wrappers . enumeration_wrapper . enumeration_t ) :
134+ decl_full_string = decl_full_string_and_type . split ( " " )[ 0 ]
137135 if main_namespace in decl_full_string :
138136 # namespace present, ok
139- # print("typedef/class main namespace found: {}".format(decl_full_string))
140- continue
141- if decl_full_string in main_namespace :
137+ # print("typedef/class/enum main namespace found [ignore-{},exposed-{}]:
138+ # {}".format(decl.ignore, decl.already_exposed,
139+ # decl_full_string_and_type))
140+ pass
141+ elif decl_full_string in main_namespace :
142142 # declaration is a parent of main namespace, ok
143- # print("typedef/class declaration of upper level namespace found: {}".format(decl_full_string))
144- continue
145- if top_namespace != "" and not top_namespace in decl_full_string :
143+ # print("typedef/class/enum declaration of upper level namespace found
144+ # [ignore{},exposed{}]: {}".format(decl.ignore, decl.already_exposed,
145+ # decl_full_string_and_type))
146+ pass
147+ elif top_namespace != "" and not top_namespace in decl_full_string :
146148 # global or std defaults, ok
147- # print("typedef/class outside top namespace found: {}".format(decl_full_string))
148- continue
149- # print("typedef/class outside of main namespace found. Ignoring: {}".format(decl_full_string))
149+ # print("typedef/class/enum outside top namespace found
150+ # [ignore-{},exposed-{}]: {}".format(decl.ignore, decl.already_exposed,
151+ # decl_full_string_and_type))
152+ pass
153+ else :
154+ # print("typedef/class/enum outside of main namespace found
155+ # [ignore-{},exposed-{}]. Ignoring: {}".format(decl.ignore,
156+ # decl.already_exposed, decl_full_string_and_type))
157+ decl .exclude ()
158+ decl .ignore = True
159+ # try to enforce that it's not exported anymore
160+ decl .already_exposed = True
161+
162+ if decl .ignore :
163+ if decl_full_string in declarations :
164+ decl .ignore = False
165+ decl .already_exposed = False
166+ # print("Ignored typedef/class/enum explicitly listed in delclarations
167+ # found. Reenable {}".format(decl_full_string_and_type))
168+ for add_declaration in add_declarations :
169+ if (add_declaration in decl .name ) or (add_declaration in decl .alias ) or (add_declaration in decl_full_string_and_type ):
170+ decl .ignore = False
171+ decl .already_exposed = False
172+ # print("declaration to explicitly add found: {} (alias {})".format(decl, decl.alias))
173+ break
174+ for ignore_declaration in ignore_declarations :
175+ if (ignore_declaration in decl .name ) or (ignore_declaration in decl .alias ) or (ignore_declaration in decl_full_string_and_type ):
150176 decl .exclude ()
151177 decl .ignore = True
152178 decl .already_exposed = True
179+ # print("declaration to ignore found: {} (alias {})".format(decl, decl.alias))
180+ break
153181
154182 # debug declarations
155183 # builder.print_declarations()
@@ -168,7 +196,7 @@ def generate_python_wrapper(header_directories, include_paths, library_name, cpp
168196 print ("generate_python_wrapper(): {} written." .format (cpp_filename ))
169197
170198
171- def post_process_python_wrapper (header_directories , cpp_filename_in , cpp_filename_out , additional_replacements = {} , additional_includes = {}, spdx_license = "MIT" , fix_include_directives = True , fix_enum_class = True ):
199+ def post_process_python_wrapper (header_directories , cpp_filename_in , cpp_filename_out , additional_replacements = [] , additional_includes = {}, spdx_license = "MIT" , fix_include_directives = True , fix_enum_class = True ):
172200 """
173201 Post process generated binding code
174202
@@ -204,7 +232,7 @@ def post_process_python_wrapper(header_directories, cpp_filename_in, cpp_filenam
204232 file_output .write ("/*\n "
205233 " * ----------------- BEGIN LICENSE BLOCK ---------------------------------\n "
206234 " *\n "
207- " * Copyright (c) 2020 Intel Corporation\n "
235+ " * Copyright (c) 2020-2021 Intel Corporation\n "
208236 " *\n "
209237 " * SPDX-License-Identifier: " + spdx_license + "\n "
210238 " *\n "
@@ -228,15 +256,15 @@ def post_process_python_wrapper(header_directories, cpp_filename_in, cpp_filenam
228256 for header_dir in header_directories :
229257 if not header_dir .endswith ("/" ):
230258 header_dir = header_dir + "/"
231- line = line .replace (header_dir , "" )
259+ line = str .replace (line , header_dir , "" )
232260
233261 # Fix C++ enum classes
234262 if fix_enum_class :
235263 if enum_started :
236264 if line .find ("export_values()" ) != - 1 :
237265 enum_started = False
238266 else :
239- line = line .replace (enum_namespace , enum_namespace_full )
267+ line = str .replace (line , enum_namespace , enum_namespace_full )
240268 else :
241269 match = enum_declaration_start .match (line )
242270 if match :
@@ -246,7 +274,7 @@ def post_process_python_wrapper(header_directories, cpp_filename_in, cpp_filenam
246274 enum_namespace_full = match .group (1 ) + "::"
247275
248276 for replacement in additional_replacements :
249- line = line .replace (replacement [0 ], replacement [1 ])
277+ line = str .replace (line , replacement [0 ], replacement [1 ])
250278
251279 file_output .write (line )
252280
0 commit comments