def generate_exception_info(self, out: FileGenerator): with WatchdogScope( out, '{0}_EXCEPTION_INFO_DEFINED'.format( self.params.beautiful_capi_namespace.upper())): out.put_line('struct {0}'.format(self.__exception_info_t())) with IndentScope(out, '};'): out.put_line( 'uint32_t code; /* value from {0} enumeration */'.format( self.__exception_code_t())) out.put_line( 'void* object_pointer; /* exception object pointer */') out.put_line('') out.put_line('enum {0}'.format(self.__exception_code_t())) with IndentScope(out, '};'): out.put_line('no_exception = 0,') out.put_line('unknown_exception = 1,') out.put_line('copy_exception_error = 2,') code_to_exception = [[ exception_class.exception_code, exception_class ] for exception_class in self.exception_classes] code_to_exception.sort(key=lambda except_info: except_info[0]) for exception_info in code_to_exception[:-1]: out.put_line('{0} = {1},'.format( exception_info[1].full_c_name, exception_info[0])) exception_info = code_to_exception[-1] out.put_line('{0} = {1}'.format(exception_info[1].full_c_name, exception_info[0]))
def __generate_caught_call(self, out: FileGenerator, return_type, method_calls: [str], catch_generator): self.__remember_exception_classes() out.put_line('{exception_info_type} {exception_info}_default;'.format( exception_info_type=self.__exception_info_t(), exception_info=self.params.exception_info_argument_name)) out.put_line('if (!{exception_info})'.format( exception_info=self.params.exception_info_argument_name)) with IndentScope(out): out.put_line( '{exception_info} = &{exception_info}_default;'.format( exception_info=self.params.exception_info_argument_name)) out.put_line('try') with IndentScope(out): out.put_line('{exception_info}->code = 0;'.format( exception_info=self.params.exception_info_argument_name)) out.put_line('{exception_info}->object_pointer = 0;'.format( exception_info=self.params.exception_info_argument_name)) out.put_lines(method_calls) for exception_class_generator in self.exception_classes: catch_generator(out, exception_class_generator) out.put_line('catch (...)') with IndentScope(out): out.put_line('{exception_info}->code = 1;'.format( exception_info=self.params.exception_info_argument_name)) return_type.generate_c_default_return_value(out)
def generate_c_functions(self, class_generator): add_ref_c_function_body = FileGenerator(None) with IndentScope(add_ref_c_function_body): add_ref_call = 'intrusive_ptr_add_ref({to_impl_cast});'.format( to_impl_cast=ThisArgumentGenerator( class_generator).c_2_implementation()) self.init_method_exception_traits.generate_implementation_call( add_ref_c_function_body, BuiltinTypeGenerator('void*'), [add_ref_call]) argument_list = ['void* object_pointer'] self.init_method_exception_traits.modify_c_arguments(argument_list) class_generator.capi_generator.add_c_function( class_generator.full_name_array, 'void', class_generator.add_ref_method, ', '.join(argument_list), add_ref_c_function_body) release_c_function_body = FileGenerator(None) with IndentScope(release_c_function_body): release_call = 'intrusive_ptr_release({to_impl_cast});'.format( to_impl_cast=ThisArgumentGenerator( class_generator).c_2_implementation()) self.finish_method_exception_traits.generate_implementation_call( release_c_function_body, BuiltinTypeGenerator('void'), [release_call]) argument_list = ['void* object_pointer'] self.finish_method_exception_traits.modify_c_arguments(argument_list) class_generator.capi_generator.add_c_function( class_generator.full_name_array, 'void', class_generator.release_method, ', '.join(argument_list), release_c_function_body)
def generate_std_methods_definitions(self, out: FileGenerator, class_generator): self.__generate_copy_constructor_definition(out, class_generator) out.put_line('') super().generate_move_constructor_definition(out, class_generator) out.put_line('') self.__generate_raw_copy_constructor_definition(out, class_generator) out.put_line('') self.__generate_destructor(out, class_generator) out.put_line('') self.__generate_assignment_operator(out, class_generator) out.put_line('') self.__generate_move_assignment_definition(out, class_generator) out.put_line('') super().generate_std_methods_definitions(out, class_generator) out.put_line('') out.put_line('inline {class_name}* {class_name}::operator->()'.format( class_name=class_generator.full_wrap_name)) with IndentScope(out): out.put_line('return this;') out.put_line('') out.put_line( 'inline const {class_name}* {class_name}::operator->() const'. format(class_name=class_generator.full_wrap_name)) with IndentScope(out): out.put_line('return this;')
def __generate_load_module(self, out: FileGenerator): out.put_line('void load_module(const char* shared_library_name)') with IndentScope(out): out.put_line( 'if (!shared_library_name) throw std::runtime_error("Null library name was passed");' ) if_def_then_else( out, '_WIN32', DynamicLoaderGenerator.__generate_load_module_windows, DynamicLoaderGenerator.__generate_load_module_posix) out.put_line('if (!handle)') with IndentScope(out): out.put_line('std::stringstream error_message;') out.put_line( 'error_message << "Can\'t load shared library " << shared_library_name;' ) out.put_line('throw std::runtime_error(error_message.str());') for c_function in self.namespace_info.c_functions: self.cur_c_function_name = c_function.name if_def_then_else( out, "{0}_load_function_call".format(c_function.name), self.__generate_secure_load, self.__generate_open_load) generate_check_version(out, self.namespace_info.namespace_name_array[0], 'shared_library_name') out.put_line('')
def __generate_root_initializer(self, out: FileGenerator, namespace_generators: []): out.put_line('class {0}'.format(self.params_description.root_header_initializer)) with IndentScope(out, '};'): member_names = [] for namespace_generator in namespace_generators: member_name = namespace_generator.wrap_name.lower() + '_module_init' out.put_line('{namespace}::Initialization {member};'.format( namespace=namespace_generator.wrap_name, member=member_name)) member_names.append(member_name) out.put_line('') if not self.params_description.shared_library_name: out.put_line('{0}();'.format(self.params_description.root_header_initializer)) with Unindent(out): out.put_line('public:') if member_names: with IfDefScope(out, '{0}_LIBRARY_USE_DYNAMIC_LOADER'.format( self.api_description.project_name.upper()), False): out.put_line('{0}(const char* shared_library_name) :'.format( self.params_description.root_header_initializer)) with Indent(out): for member_name in member_names[:-1]: out.put_line('{member_name}(shared_library_name),'.format(member_name=member_name)) out.put_line('{member_name}(shared_library_name)'.format(member_name=member_names[-1])) with IndentScope(out): pass if self.params_description.shared_library_name: out.put_line('{0}()'.format(self.params_description.root_header_initializer)) with IndentScope(out): pass
def __generate_constructor(self, out: FileGenerator): out.put_line('Initialization(const char* shared_library_name)') with IndentScope(out): out.put_line('load_module(shared_library_name);') if self.params.shared_library_name: out.put_line('Initialization()') with IndentScope(out): out.put_line('#ifdef _WIN32') with Indent(out): out.put_line( 'load_module("{shared_library_name}.dll");'.format( shared_library_name=self.params.shared_library_name )) out.put_line('#elif __APPLE__') with Indent(out): out.put_line( 'load_module("lib{shared_library_name}.dylib");'. format(shared_library_name=self.params. shared_library_name)) out.put_line('#else') with Indent(out): out.put_line( 'load_module("lib{shared_library_name}.so");'.format( shared_library_name=self.params.shared_library_name )) out.put_line('#endif')
def __generate_down_cast_c_function(self): if self.__should_generate_down_cast(): for cur_base_class_generator in self.base_class_generator.__get_all_base_classes( ): base_class_argument_generator = ArgumentGenerator( ClassTypeGenerator(cur_base_class_generator), 'source_object') body = FileGenerator(None) with IndentScope(body): body.put_line('if ({base_object})'.format( base_object=base_class_argument_generator.name)) with IndentScope(body): cast_str = 'return dynamic_cast<{cast_to}*>({cast_from});' if base_class_argument_generator.type_generator.class_argument_generator.class_object.custom_down_cast_filled: cast_str = base_class_argument_generator.type_generator.class_argument_generator.class_object.custom_down_cast body.put_line( cast_str.format( cast_to=self.class_object. implementation_class_name, cast_from=base_class_argument_generator. c_2_implementation_pointer())) body.put_line('else') with IndentScope(body): body.put_line('return 0;') self.capi_generator.add_c_function( self.full_name_array, 'void*', self.cast_from_base(cur_base_class_generator), base_class_argument_generator.c_argument_declaration(), body)
def generate_check_and_throw_exception_for_impl(self, out: FileGenerator): out.put_line('namespace {0}'.format(self.params.beautiful_capi_namespace)) with IndentScope(out): out.put_line( 'inline void check_and_throw_exception(uint32_t exception_code, void* exception_object)') with IndentScope(out): self.__create_check_and_throw_exceptions_body(out, ByFirstArgument.__generate_throw_impl)
def generate_c_functions(self, class_generator): if self.generate_copy_constructor(class_generator): copy_c_function_body = FileGenerator(None) with IndentScope(copy_c_function_body): copy_constructor_call = 'return new {impl_name}(*{to_impl_cast});'.format( impl_name=class_generator.class_object. implementation_class_name, to_impl_cast=ThisArgumentGenerator( class_generator).c_2_implementation()) self.init_method_exception_traits.generate_implementation_call( copy_c_function_body, BuiltinTypeGenerator('void*'), [copy_constructor_call]) argument_list = ['void* object_pointer'] self.init_method_exception_traits.modify_c_arguments(argument_list) class_generator.capi_generator.add_c_function( class_generator.full_name_array, 'void*', class_generator.copy_method, ', '.join(argument_list), copy_c_function_body) delete_c_function_body = FileGenerator(None) with IndentScope(delete_c_function_body): delete_call = 'delete {to_impl_cast};'.format( to_impl_cast=ThisArgumentGenerator( class_generator).c_2_implementation()) self.finish_method_exception_traits.generate_implementation_call( delete_c_function_body, BuiltinTypeGenerator('void'), [delete_call]) argument_list = ['void* object_pointer'] self.finish_method_exception_traits.modify_c_arguments(argument_list) class_generator.capi_generator.add_c_function( class_generator.full_name_array, 'void', class_generator.delete_method, ', '.join(argument_list), delete_c_function_body)
def generate_test( self, cur_class: Parser.TClass, c_generator_to_properties: ClassToProperties.CGeneratorToProperties ): full_type = format_type( c_generator_to_properties.class_generator.full_wrap_name) full_c_type = format_type( c_generator_to_properties.class_generator.full_c_name) test_declaration = 'BOOST_AUTO_TEST_CASE({0}_test)'.format( full_c_type.replace('::', '_').lower()) is_copy_semantic = cur_class.lifecycle == Parser.TLifecycle.copy_semantic is_raw_pointer = cur_class.lifecycle == Parser.TLifecycle.raw_pointer_semantic if is_copy_semantic: self.__gen_code_equal_method(c_generator_to_properties, full_type) self.test_generator.main_generator.put_line(test_declaration) with IndentScope(self.test_generator.main_generator, ending='}\n'): self.__gen_code_for_missing_arguments( cur_class, c_generator_to_properties.class_generator, 'test_class') for c_property in c_generator_to_properties.properties: with IndentScope(self.test_generator.main_generator): return_type_generator = c_property.get_method_generator.return_type_generator if type(return_type_generator) is BuiltinTypeGenerator: self.__gen_code_for_test_builtin_type(c_property) elif type(return_type_generator) is EnumTypeGenerator: self.__gen_code_for_test_enum(c_property) elif type(return_type_generator) is CClassTypeGenerator: self.__gen_code_for_test_class(c_property) if is_raw_pointer: self.test_generator.main_generator.put_line( 'test_class.{del_method_name}();'.format( del_method_name=self.params.delete_method_name))
def __generate_assignment_operator(self, out: FileGenerator, class_generator): out.put_line( 'inline {class_name}& {class_name}::operator=(const {class_name}& other)' .format(class_name=class_generator.full_wrap_name)) with IndentScope(out): out.put_line('if (this != &other)') with IndentScope(out): out.put_line('SetObject(other.{get_raw}());'.format( get_raw=self.params.get_raw_pointer_method_name)) out.put_line('return *this;')
def generate_callback_implementation_destructor_body(out: FileGenerator, class_generator, callback_function_name): with IndentScope(out): out.put_line('if (mObject && {0})'.format(callback_function_name)) with IndentScope(out): exception_traits = class_generator.callback_lifecycle_traits.finish_method_exception_traits return_expression = exception_traits.generate_c_call_from_impl( out, BuiltinTypeGenerator('void'), callback_function_name, ['mObject']) if return_expression: out.put_line('{return_expression};'.format( return_expression=return_expression))
def generate_callback_implementation_set_c_functions_for_copy_semantic( out: FileGenerator, class_generator): out.put_line( 'void SetCFunctionForCopy({callback_type} c_function_pointer)'.format( callback_type=class_generator.base_class_generator. copy_callback_type)) with IndentScope(out): out.put_line('copy_callback = c_function_pointer;') out.put_line( 'void SetCFunctionForDelete({callback_type} c_function_pointer)'. format(callback_type=class_generator.base_class_generator. delete_callback_type)) with IndentScope(out): out.put_line('delete_callback = c_function_pointer;')
def generate_callback_implementation_set_c_functions_for_add_ref_semantic( out: FileGenerator, class_generator): out.put_line( 'void SetCFunctionForAddRef({callback_type} c_function_pointer)'. format(callback_type=class_generator.base_class_generator. add_ref_callback_type)) with IndentScope(out): out.put_line('add_ref_callback = c_function_pointer;') out.put_line( 'void SetCFunctionForRelease({callback_type} c_function_pointer)'. format(callback_type=class_generator.base_class_generator. release_callback_type)) with IndentScope(out): out.put_line('release_callback = c_function_pointer;')
def generate_raw_copy_constructor_body_definition(self, out: FileGenerator, class_generator, copy_object): out.put_line('if (object_pointer && {copy_object})'.format( copy_object=copy_object)) with IndentScope(out): copy_result = self.init_method_exception_traits.generate_c_call( out, BuiltinTypeGenerator('void*'), class_generator.copy_method, ['object_pointer']) out.put_line( 'SetObject({copy_result});'.format(copy_result=copy_result)) out.put_line('else') with IndentScope(out): out.put_line('SetObject(object_pointer);')
def __gen_code_equal_method(self, c_generator_to_properties: ClassToProperties. CGeneratorToProperties, full_type: str): method_declaration = 'inline bool equal(const {type_name}& first, const {type_name}& second){is_declaration}' self.equal_generator.declaration_section.put_line( method_declaration.format(type_name=full_type, is_declaration=';')) self.equal_generator.main_generator.put_line( method_declaration.format(type_name=full_type, is_declaration='')) with IndentScope(self.equal_generator.main_generator, ending='}\n'): generator = self.equal_generator.main_generator for c_property in c_generator_to_properties.properties: equal_code = 'if ({equal_method}first.{method_name}(){raw_method}{action}' \ 'second.{method_name}(){raw_method}{close_br})' property_type = c_property.get_method_generator.return_type_generator typeof_property_type = type(property_type) need_raw_pointer = False need_equal_method = (False, '') if typeof_property_type in [ MappedTypeGenerator, BuiltinTypeGenerator, EnumTypeGenerator ]: need_equal_method = (True, 'builtin_equal') elif typeof_property_type is CClassTypeGenerator: lifecycle_property_type = property_type.class_argument_generator.class_object.lifecycle if lifecycle_property_type in [ Parser.TLifecycle.reference_counted, Parser.TLifecycle.raw_pointer_semantic ]: need_raw_pointer = True elif lifecycle_property_type == Parser.TLifecycle.copy_semantic: need_equal_method = (True, 'equal') else: raise Exception('Unknown LifeCycle type') else: raise Exception('Unknown TypeGenerator') raw_method_name = c_generator_to_properties.class_generator.params.get_raw_pointer_method_name equal_code = equal_code.format( method_name=c_property.get_method.name, raw_method='.{0}()'.format(raw_method_name) if need_raw_pointer else '', equal_method='!{0}('.format(need_equal_method[1]) if need_equal_method[0] else '', close_br=')' if need_equal_method[0] else '', action=', ' if need_equal_method[0] else ' != ') generator.put_line(equal_code) with IndentScope(generator): generator.put_line('return false;') generator.put_line('return true;')
def __generate_delete_method(self, out: FileGenerator, class_generator): out.put_line('inline void {class_name}::{delete_method}()'.format( class_name=class_generator.full_wrap_name, delete_method=self.params.delete_method_name)) with IndentScope(out): out.put_line('if ({get_raw}())'.format( get_raw=self.params.get_raw_pointer_method_name)) with IndentScope(out): self.finish_method_exception_traits.generate_c_call( out, BuiltinTypeGenerator('void'), class_generator.delete_method, [ '{get_raw}()'.format( get_raw=self.params.get_raw_pointer_method_name) ]) out.put_line('SetObject(0);')
def generate_method_callback_definition(first_flag, out: FileGenerator, cur_method_generator) -> bool: add_method_callback_typedef(cur_method_generator) first_flag = if_required_then_add_empty_line(first_flag, out) c_argument_declaration_list = [ arg_gen.c_argument_declaration() for arg_gen in cur_method_generator.c_arguments_list] cur_method_generator.exception_traits.modify_c_arguments(c_argument_declaration_list) out.put_line('template<typename ImplementationClass>') out.put_line('{return_type} {top_ns}_API_CONVENTION {callback_name}({arguments})'.format( top_ns=cur_method_generator.parent_class_generator.full_name_array[0].upper(), return_type=cur_method_generator.return_type_generator.c_argument_declaration(), callback_name=get_method_callback_name(cur_method_generator), arguments=', '.join(c_argument_declaration_list) )) with IndentScope(out): out.put_line( '{const}ImplementationClass* self = static_cast<ImplementationClass*>(object_pointer);'.format( const='const ' if cur_method_generator.method_object.const else '' )) wrap_arg_call = [arg_gen.c_2_wrap() for arg_gen in cur_method_generator.argument_generators] method_call = 'self->{0}({1})'.format( cur_method_generator.wrap_name, ', '.join(wrap_arg_call)) calling_instructions, return_expression = cur_method_generator.return_type_generator.wrap_2_c_var( '', method_call) if return_expression: calling_instructions.append('return {0};'.format(return_expression)) cur_method_generator.exception_traits.generate_callback_call( out, cur_method_generator.return_type_generator, calling_instructions) return first_flag
def generate_c_function(self, capi_generator: CapiGenerator): c_arguments_list = [ argument_generator.c_argument_declaration() for argument_generator in self.argument_generators ] self.exception_traits.modify_c_arguments(c_arguments_list) c_arguments = ', '.join(c_arguments_list) implementation_arguments = ', '.join([ argument_generator.c_2_implementation() for argument_generator in self.argument_generators ]) c_function_body = FileGenerator(None) with IndentScope(c_function_body): function_name = self.function_object.implementation_name if not function_name: function_name = self.function_object.name implementation_call = '{function_name}({arguments})'.format( function_name=function_name, arguments=implementation_arguments) calling_instructions, return_expression = self.return_type_generator.implementation_2_c_var( '', implementation_call) if return_expression: calling_instructions.append( 'return {0};'.format(return_expression)) self.exception_traits.generate_implementation_call( c_function_body, self.return_type_generator, calling_instructions) capi_generator.add_c_function( self.parent_namespace_generator.full_name_array, self.return_type_generator.c_argument_declaration(), self.full_c_name, c_arguments, c_function_body)
def __generate_down_cast_definitions(self, definition_header): if self.__should_generate_down_cast(): for cur_base_class_generator in self.base_class_generator.__get_all_base_classes( ): the_most_parent_namespace = cur_base_class_generator.parent_namespace.the_most_parent definition_header.put_line('') definition_header.put_line( the_most_parent_namespace.one_line_namespace_begin) definition_header.put_line('') base_class_argument_generator = ArgumentGenerator( ClassTypeGenerator(cur_base_class_generator), 'source_object') definition_header.put_line('template<>') definition_header.put_line( 'inline {cast_to} down_cast<{cast_to} >({cast_from_ref})'. format(cast_to=self.full_wrap_name, cast_from_ref=base_class_argument_generator. wrap_argument_declaration())) with IndentScope(definition_header): this_class_as_return_type = ClassTypeGenerator(self) this_class_as_return_type.copy_or_add_ref_when_c_2_wrap = True casting_c_call = '{cast_from_base}({base_arg})'.format( cast_from_base=self.cast_from_base( cur_base_class_generator), base_arg=base_class_argument_generator.wrap_2_c()) instructions, return_expression = this_class_as_return_type.c_2_wrap_var( '', casting_c_call) definition_header.put_lines(instructions) definition_header.put_return_cpp_statement( return_expression) definition_header.put_line('') definition_header.put_line( the_most_parent_namespace.one_line_namespace_end)
def __generate_constructor(self, out: FileGenerator): out.put_line('Initialization()') with IndentScope(out): generate_check_version( out, self.namespace_info.namespace_name_array[0], '"{0}"'.format(self.params.shared_library_name) if self.params.shared_library_name else '')
def __generate_root_header(self, namespace_generators: [], file_cache: FileCache): if self.params_description.root_header and self.api_description.project_name: root_header = FileGenerator(os.path.join(self.output_folder, self.params_description.root_header)) root_header.put_begin_cpp_comments(self.params_description) with WatchdogScope(root_header, self.api_description.project_name.upper() + '_LIBRARY_ROOT_INCLUDED'): with IfDefScope(root_header, '{0}_LIBRARY_USE_DYNAMIC_LOADER'.format( self.api_description.project_name.upper()), False): for namespace_generator in namespace_generators: root_header.put_line('#define {0}_CAPI_USE_DYNAMIC_LOADER'.format( namespace_generator.wrap_name.upper())) root_header.put_line('') with IfDefScope(root_header, '{0}_LIBRARY_DEFINE_FUNCTION_POINTERS'.format( self.api_description.project_name.upper()), False): for namespace_generator in namespace_generators: root_header.put_line('#define {0}_CAPI_DEFINE_FUNCTION_POINTERS'.format( namespace_generator.wrap_name.upper())) root_header.put_line('') root_header.put_include_files(False) for namespace_generator in namespace_generators: root_header.include_user_header(file_cache.namespace_header(namespace_generator.full_name_array)) if self.params_description.root_header_initializer: root_header.put_line('') with IfDefScope(root_header, '__cplusplus'): if self.params_description.root_header_namespace: root_header.put_line('namespace {0}'.format(self.params_description.root_header_namespace)) with IndentScope(root_header): self.__generate_root_initializer(root_header, namespace_generators) else: self.__generate_root_initializer(root_header, namespace_generators)
def generate_wrap_definition(self, out: FileGenerator, capi_generator: CapiGenerator): self.exception_traits = capi_generator.get_exception_traits( self.constructor_object.noexcept) arguments = ', '.join([ argument_generator.wrap_argument_declaration() for argument_generator in self.argument_generators ]) arguments_call = [ argument_generator.wrap_2_c() for argument_generator in self.argument_generators ] out.put_line( 'inline {namespace}::{class_name}({arguments}){base_init}'.format( namespace=self.parent_class_generator.full_wrap_name, class_name=self.parent_class_generator.wrap_short_name, arguments=arguments, base_init=get_base_init(self.parent_class_generator))) with IndentScope(out): result_expression = self.exception_traits.generate_c_call( out, self.parent_class_as_argument_type, self.full_c_name, arguments_call) out.put_line('SetObject({result_expression}.{detach}());'.format( result_expression=result_expression, detach=self.params.detach_method_name))
def generate_c_function(self, capi_generator: CapiGenerator): argument_declaration_list = [ argument_generator.c_argument_declaration() for argument_generator in self.argument_generators ] self.exception_traits.modify_c_arguments(argument_declaration_list) arguments_declaration = ', '.join(argument_declaration_list) implementation_arguments = ', '.join([ argument_generator.c_2_implementation() for argument_generator in self.argument_generators ]) c_function_body = FileGenerator(None) with IndentScope(c_function_body): if self.constructor_object.implementation_codes: calling_instructions = generate_custom_implementation_code( self.constructor_object.implementation_codes[0], self.argument_generators, self.parent_class_as_argument_type) else: implementation_call = 'return new {impl_class}({arguments});'.format( impl_class=self.parent_class_generator.class_object. implementation_class_name, arguments=implementation_arguments) calling_instructions = [implementation_call] self.exception_traits.generate_implementation_call( c_function_body, self.parent_class_as_argument_type, calling_instructions) capi_generator.add_c_function( self.parent_class_generator.full_name_array, self.parent_class_as_argument_type.c_argument_declaration(), self.full_c_name, arguments_declaration, c_function_body)
def generate_callback_implementation_set_object_pointer_method( out: FileGenerator, callback, class_generator): out.put_line('void SetObjectPointer(void* object_pointer)') with IndentScope(out): out.put_line('mObject = object_pointer;') generate_callback_implementation_copy_constructor_body( out, callback, class_generator)
def __create_check_and_throw_exceptions_body(self, out: FileGenerator, throw_generator): out.put_line('switch (exception_code)') with IndentScope(out): out.put_line('case 0:') with Indent(out): out.put_line('return;') out.put_line('case 1:') with Indent(out): out.put_line('throw std::runtime_error("unknown exception");') out.put_line('case 2:') with Indent(out): out.put_line( 'throw std::runtime_error("exception during copying exception object");' ) code_to_exception = { exception_class.exception_code: exception_class for exception_class in self.exception_classes } for code, exception_class in code_to_exception.items(): out.put_line('case {0}:'.format(code)) with Indent(out): throw_generator(out, exception_class) out.put_line('default:') with Indent(out): out.put_line('assert(false);') out.put_line( 'throw std::runtime_error("unknown exception code");')
def __generate_class_declaration(self, declaration_header: FileGenerator): DoxygenCppGenerator().generate_for_class(declaration_header, self) put_template_line(declaration_header, self.class_object) if self.base_class_generator: declaration_header.put_line( 'class {name} : public {base_class}'.format( name=self.wrap_name, base_class=self.base_class_generator.full_wrap_name)) declaration_header.include_user_header( self.file_cache.class_header_decl( self.base_class_generator.full_name_array)) else: declaration_header.put_line( 'class {name}'.format(name=self.wrap_name)) with IndentScope(declaration_header, '};'): self.__generate_class_body(declaration_header) if self.class_object.typedef_name: declaration_header.put_line( 'typedef {wrap_name} {typedef}{suffix};'.format( wrap_name=self.wrap_name, typedef=self.class_object.typedef_name, suffix=self.lifecycle_traits.suffix)) for template_argument_generator in self.template_argument_generators: template_argument_generator.include_dependent_declaration_headers( declaration_header, self.file_cache) self.__generate_callback_lifecycle_traits() generate_callbacks_on_client_side_declarations(declaration_header, self)
def generate_callbacks_on_library_side(class_generator, capi_generator): if class_generator.is_callback: callback = class_generator.base_class_generator.class_object.callbacks[ 0] if callback.implementation_class_header_filled: capi_generator.additional_includes.include_user_header( callback.implementation_class_header) callback_impl = FileGenerator(None) callback_impl.put_line( class_generator.parent_namespace.one_line_namespace_begin) callback_impl.put_line('') impl_class_name = get_callback_impl_name( class_generator.base_class_generator) callback_impl.put_line('class {0} : public {1}'.format( impl_class_name, callback.implementation_class_name)) with IndentScope(callback_impl, '};'): generate_callback_implementation_body(callback_impl, callback, class_generator, impl_class_name) callback_impl.put_line('') callback_impl.put_line( class_generator.parent_namespace.one_line_namespace_end) capi_generator.callback_implementations.append(callback_impl)
def generate_check_version(out: FileGenerator, namespace_name: str, shared_library_name: str): out.put_line('const int major_version = {ns}_get_major_version();'.format( ns=get_c_name(namespace_name))) out.put_line('const int minor_version = {ns}_get_minor_version();'.format( ns=get_c_name(namespace_name))) out.put_line('const int patch_version = {ns}_get_patch_version();'.format( ns=get_c_name(namespace_name))) expected_major = '{ns}_MAJOR_VERSION'.format(ns=namespace_name.upper()) expected_minor = '{ns}_MINOR_VERSION'.format(ns=namespace_name.upper()) expected_patch = '{ns}_PATCH_VERSION'.format(ns=namespace_name.upper()) major_compare = 'major_version != {expected_major}'.format( expected_major=expected_major) minor_compare = 'minor_version != {expected_minor}'.format( expected_minor=expected_minor) patch_compare = 'patch_version != {expected_patch}'.format( expected_patch=expected_patch) out.put_line('if ({major} || {minor} || {patch})'.format( major=major_compare, minor=minor_compare, patch=patch_compare)) with IndentScope(out): out.put_line('std::stringstream error_message;') if shared_library_name: out.put_line( 'error_message << "Incorrect version of " << {0} << " library. ";' .format(shared_library_name)) else: out.put_line('error_message << "Incorrect version of library. ";') out.put_line( 'error_message << "Expected version is " << {0} << "." << {1} << "." << {2} << ". ";' .format(expected_major, expected_minor, expected_patch)) out.put_line( 'error_message << "Found version is " << {0} << "." << {1} << "." << {2} << ".";' .format('major_version', 'minor_version', 'patch_version')) out.put_line('throw std::runtime_error(error_message.str());')