From 3773668d8a6c40f64ba9b5330bf48caf5258ac87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Tue, 4 Apr 2017 14:55:28 +0200 Subject: [PATCH 1/9] Fix Java headers generation --- java/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/CMakeLists.txt b/java/CMakeLists.txt index 94c8c1796..5e331966e 100644 --- a/java/CMakeLists.txt +++ b/java/CMakeLists.txt @@ -58,6 +58,6 @@ if(ANDROID) # HACK: accessing mediastreamer2 source directory from here is just wrong! add_custom_target(linphonecore-jni-header - COMMAND ${Java_JAVAH_EXECUTABLE} -o "${CMAKE_CURRENT_BINARY_DIR}/linphonecore_jni.h" -classpath "${CMAKE_CURRENT_SOURCE_DIR}/impl:${CMAKE_CURRENT_SOURCE_DIR}/common:${CMAKE_CURRENT_SOURCE_DIR}/../mediastreamer2/java/src" ${JNI_CLASSES} + COMMAND ${Java_JAVAH_EXECUTABLE} -o "${CMAKE_CURRENT_BINARY_DIR}/linphonecore_jni.h" -classpath "${CMAKE_CURRENT_SOURCE_DIR}/impl:${CMAKE_CURRENT_SOURCE_DIR}/common:${CMAKE_CURRENT_SOURCE_DIR}/../../mediastreamer2/java/src" ${JNI_CLASSES} ) endif() From 274ff16b4196c100521a92866b7d2f82740b92c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Wed, 5 Apr 2017 10:18:25 +0200 Subject: [PATCH 2/9] Fix double free --- coreapi/callbacks.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 1e0e3b165..867f493d5 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -347,8 +347,6 @@ static void call_received(SalOp *h){ linphone_error_info_set(ei, LinphoneReasonBusy, 486, "Busy - duplicated call", NULL); linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); sal_op_release(h); - linphone_address_unref(from_addr); - linphone_address_unref(to_addr); linphone_address_unref(from_address_to_search_if_me); ms_free(addr); return; From e4f3a9a56bfe0290766c93358bf72e4a881334d3 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 5 Apr 2017 17:41:30 +0200 Subject: [PATCH 3/9] Support C++ wrapper generation with Python 3. --- CMakeLists.txt | 1 - wrappers/cpp/abstractapi.py | 71 +++++------ wrappers/cpp/genwrapper.py | 230 +++++++++++++++++++----------------- 3 files changed, 160 insertions(+), 142 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d64ef8f1b..7c4ede766 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,7 +175,6 @@ if(ENABLE_LIME) set(HAVE_LIME 1) endif() if(ENABLE_CXX_WRAPPER) - set(Python_ADDITIONAL_VERSIONS 2) find_package(PythonInterp REQUIRED) endif() diff --git a/wrappers/cpp/abstractapi.py b/wrappers/cpp/abstractapi.py index 34537e345..edae4d92c 100644 --- a/wrappers/cpp/abstractapi.py +++ b/wrappers/cpp/abstractapi.py @@ -170,12 +170,12 @@ class MethodName(Name): def to_c(self): suffix = ('_' + str(self.overloadRef)) if self.overloadRef > 0 else '' - return Name.to_snake_case(self, fullName=True) + suffix + return self.to_snake_case(fullName=True) + suffix class ArgName(Name): def to_c(self): - return Name.to_snake_case(self) + return self.to_snake_case() class PropertyName(ArgName): @@ -478,16 +478,16 @@ class CParser(object): def parse_all(self): for enum in self.cProject.enums: - CParser.parse_enum(self, enum) + self.parse_enum(enum) for _class in self.cProject.classes: try: - CParser.parse_class(self, _class) + self.parse_class(_class) except BlacklistedException: pass except Error as e: print('Could not parse \'{0}\' class: {1}'.format(_class.name, e.args[0])) - CParser._fix_all_types(self) + self._fix_all_types() def _class_is_refcountable(self, _class): @@ -499,33 +499,38 @@ class CParser(object): return True return False + def _fix_all_types_in_class_or_interface(self, _class): + if _class is not None: + if type(_class) is Class: + self._fix_all_types_in_class(_class) + else: + self._fix_all_types_in_interface(_class) + def _fix_all_types(self): - for _class in self.classesIndex.values() + self.interfacesIndex.values(): - if _class is not None: - if type(_class) is Class: - CParser._fix_all_types_in_class(self, _class) - else: - CParser._fix_all_types_in_interface(self, _class) + for _class in self.interfacesIndex.values(): + self._fix_all_types_in_class_or_interface(_class) + for _class in self.classesIndex.values(): + self._fix_all_types_in_class_or_interface(_class) def _fix_all_types_in_class(self, _class): for property in _class.properties: if property.setter is not None: - CParser._fix_all_types_in_method(self, property.setter) + self._fix_all_types_in_method(property.setter) if property.getter is not None: - CParser._fix_all_types_in_method(self, property.getter) + self._fix_all_types_in_method(property.getter) for method in (_class.instanceMethods + _class.classMethods): - CParser._fix_all_types_in_method(self, method) + self._fix_all_types_in_method(method) def _fix_all_types_in_interface(self, interface): for method in interface.methods: - CParser._fix_all_types_in_method(self, method) + self._fix_all_types_in_method(method) def _fix_all_types_in_method(self, method): try: - CParser._fix_type(self, method.returnType) + self._fix_type(method.returnType) for arg in method.args: - CParser._fix_type(self, arg.type) + self._fix_type(arg.type) except Error as e: print('warning: some types could not be fixed in {0}() function: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) @@ -546,7 +551,7 @@ class CParser(object): _type.containedTypeDesc = EnumType(_type.containedTypeName, enumDesc=self.enumsIndex[_type.containedTypeName]) else: if _type.containedTypeName is not None: - _type.containedTypeDesc = CParser.parse_c_base_type(self, _type.containedTypeName) + _type.containedTypeDesc = self.parse_c_base_type(_type.containedTypeName) else: raise Error('bctbx_list_t type without specified contained type') @@ -575,10 +580,10 @@ class CParser(object): raise BlacklistedException('{0} is blacklisted'.format(cclass.name)); if cclass.name.endswith('Cbs'): - _class = CParser._parse_listener(self, cclass) + _class = self._parse_listener(cclass) self.interfacesIndex[cclass.name] = _class else: - _class = CParser._parse_class(self, cclass) + _class = self._parse_class(cclass) self.classesIndex[cclass.name] = _class self.namespace.add_child(_class) return _class @@ -587,12 +592,12 @@ class CParser(object): name = ClassName() name.from_camel_case(cclass.name, namespace=self.namespace.name) _class = Class(name) - _class.refcountable = CParser._class_is_refcountable(self, cclass) + _class.refcountable = self._class_is_refcountable(cclass) for cproperty in cclass.properties.values(): try: if cproperty.name != 'callbacks': - absProperty = CParser._parse_property(self, cproperty, namespace=name) + absProperty = self._parse_property(cproperty, namespace=name) _class.add_property(absProperty) else: _class.listenerInterface = self.interfacesIndex[cproperty.getter.returnArgument.ctype] @@ -601,7 +606,7 @@ class CParser(object): for cMethod in cclass.instanceMethods.values(): try: - method = CParser.parse_method(self, cMethod, namespace=name) + method = self.parse_method(cMethod, namespace=name) if method.name.to_snake_case() == 'add_callbacks' or method.name.to_snake_case() == 'remove_callbacks': if _class.listenerInterface is None or not _class.multilistener: _class.multilistener = True @@ -618,7 +623,7 @@ class CParser(object): for cMethod in cclass.classMethods.values(): try: - method = CParser.parse_method(self, cMethod, type=Method.Type.Class, namespace=name) + method = self.parse_method(cMethod, type=Method.Type.Class, namespace=name) _class.add_class_method(method) except BlacklistedException: pass @@ -636,10 +641,10 @@ class CParser(object): methodType = Method.Type.Instance aproperty = Property(name) if cproperty.setter is not None: - method = CParser.parse_method(self, cproperty.setter, namespace=namespace, type=methodType) + method = self.parse_method(cproperty.setter, namespace=namespace, type=methodType) aproperty.setter = method if cproperty.getter is not None: - method = CParser.parse_method(self, cproperty.getter, namespace=namespace, type=methodType) + method = self.parse_method(cproperty.getter, namespace=namespace, type=methodType) aproperty.getter = method return aproperty @@ -658,7 +663,7 @@ class CParser(object): for property in cclass.properties.values(): if property.name != 'user_data': try: - method = CParser._parse_listener_property(self, property, listener, cclass.events) + method = self._parse_listener_property(property, listener, cclass.events) listener.add_method(method) except Error as e: print('Could not parse property \'{0}\' of listener \'{1}\': {2}'.format(property.name, cclass.name, e.args[0])) @@ -684,11 +689,11 @@ class CParser(object): raise Error('invalid event name \'{0}\''.format(eventName)) method = Method(methodName) - method.returnType = CParser.parse_type(self, event.returnArgument) + method.returnType = self.parse_type(event.returnArgument) for arg in event.arguments: argName = ArgName() argName.from_snake_case(arg.name) - argument = Argument(argName, CParser.parse_type(self, arg)) + argument = Argument(argName, self.parse_type(arg)) method.add_arguments(argument) return method @@ -697,18 +702,18 @@ class CParser(object): name = MethodName() name.from_snake_case(cfunction.name, namespace=namespace) - if CParser._is_blacklisted(self, name): + if self._is_blacklisted(name): raise BlacklistedException('{0} is blacklisted'.format(name.to_c())); method = Method(name, type=type) method.deprecated = cfunction.deprecated - method.returnType = CParser.parse_type(self, cfunction.returnArgument) + method.returnType = self.parse_type(cfunction.returnArgument) for arg in cfunction.arguments: if type == Method.Type.Instance and arg is cfunction.arguments[0]: method.constMethod = ('const' in arg.completeType.split(' ')) else: - aType = CParser.parse_type(self, arg) + aType = self.parse_type(arg) argName = ArgName() argName.from_snake_case(arg.name) absArg = Argument(argName, aType) @@ -718,7 +723,7 @@ class CParser(object): def parse_type(self, cType): if cType.ctype in self.cBaseType or re.match(self.regexFixedSizeInteger, cType.ctype): - absType = CParser.parse_c_base_type(self, cType.completeType) + absType = self.parse_c_base_type(cType.completeType) elif cType.ctype in self.enumsIndex: absType = EnumType(cType.ctype, enumDesc=self.enumsIndex[cType.ctype]) elif cType.ctype in self.classesIndex or cType.ctype in self.interfacesIndex: diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py index f363c3d0d..caf8eec6b 100755 --- a/wrappers/cpp/genwrapper.py +++ b/wrappers/cpp/genwrapper.py @@ -36,7 +36,7 @@ class CppTranslator(object): self.ambigousTypes = ['LinphonePayloadType'] def is_ambigous_type(self, _type): - return _type.name in self.ambigousTypes or (_type.name == 'list' and CppTranslator.is_ambigous_type(self, _type.containedTypeDesc)) + return _type.name in self.ambigousTypes or (_type.name == 'list' and self.is_ambigous_type(_type.containedTypeDesc)) @staticmethod def translate_enum(enum): @@ -92,7 +92,7 @@ class CppTranslator(object): classDict['cListenerName'] = _class.listenerInterface.name.to_c() classDict['cppListenerName'] = CppTranslator.translate_class_name(_class.listenerInterface.name) for method in _class.listenerInterface.methods: - classDict['wrapperCbs'].append(CppTranslator._generate_wrapper_callback(self, _class, method)) + classDict['wrapperCbs'].append(self._generate_wrapper_callback(_class, method)) if ismonolistenable: classDict['cCbsGetter'] = _class.name.to_snake_case(fullName=True) + '_get_callbacks' @@ -106,22 +106,22 @@ class CppTranslator(object): classDict['userDataGetter'] = _class.listenerInterface.name.to_snake_case(fullName=True)[:-len('_listener')] + '_cbs_get_user_data' classDict['currentCallbacksGetter'] = _class.name.to_snake_case(fullName=True) + '_get_current_callbacks' - for property in _class.properties: + for _property in _class.properties: try: - classDict['methods'] += CppTranslator.translate_property(self, property) + classDict['methods'] += self.translate_property(_property) except AbsApi.Error as e: - print('error while translating {0} property: {1}'.format(property.name.to_snake_case(), e.args[0])) + print('error while translating {0} property: {1}'.format(_property.name.to_snake_case(), e.args[0])) for method in _class.instanceMethods: try: - methodDict = CppTranslator.translate_method(self, method) + methodDict = self.translate_method(method) classDict['methods'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) for method in _class.classMethods: try: - methodDict = CppTranslator.translate_method(self, method) + methodDict = self.translate_method(method) classDict['staticMethods'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) @@ -138,7 +138,7 @@ class CppTranslator(object): wrappedArgs = [] for arg in method.args: args.append(arg.type.cname + ' ' + arg.name.to_c()) - wrappedArgs.append(CppTranslator._wrap_c_expression_to_cpp(self, arg.name.to_c(), arg.type, usedNamespace=namespace)) + wrappedArgs.append(self._wrap_c_expression_to_cpp(arg.name.to_c(), arg.type, usedNamespace=namespace)) params['params'] = ', '.join(args) params['returnType'] = method.returnType.cname @@ -153,9 +153,7 @@ class CppTranslator(object): wrapperCbDict['cppMethodCallingLine'] = 'listener->{methodName}({wrappedArgs})'.format( methodName=method.name.to_camel_case(lower=True), wrappedArgs=', '.join(wrappedArgs)) - wrapperCbDict['cppMethodCallingLine'] = CppTranslator._wrap_cpp_expression_to_c(self, - wrapperCbDict['cppMethodCallingLine'], - method.returnType) + wrapperCbDict['cppMethodCallingLine'] = self._wrap_cpp_expression_to_c(wrapperCbDict['cppMethodCallingLine'], method.returnType) return wrapperCbDict def translate_interface(self, interface): @@ -171,19 +169,19 @@ class CppTranslator(object): intDict['methods'] = [] for method in interface.methods: try: - methodDict = CppTranslator.translate_method(self, method, genImpl=False) + methodDict = self.translate_method(method, genImpl=False) intDict['methods'].append(methodDict) except AbsApi.Error as e: print('Could not translate {0}: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) return intDict - def translate_property(self, property): + def translate_property(self, _property): res = [] - if property.getter is not None: - res.append(CppTranslator.translate_method(self, property.getter)) - if property.setter is not None: - res.append(CppTranslator.translate_method(self, property.setter)) + if _property.getter is not None: + res.append(self.translate_method(_property.getter)) + if _property.setter is not None: + res.append(self.translate_method(_property.setter)) return res def translate_method(self, method, genImpl=True): @@ -193,14 +191,14 @@ class CppTranslator(object): namespace = method.find_first_ancestor_by_type(AbsApi.Namespace) methodElems = {} - methodElems['return'] = CppTranslator.translate_type(self, method.returnType) + methodElems['return'] = self.translate_type(method.returnType) methodElems['name'] = CppTranslator.translate_method_name(method.name) methodElems['params'] = '' for arg in method.args: if arg is not method.args[0]: methodElems['params'] += ', ' - methodElems['params'] += CppTranslator.translate_argument(self, arg) + methodElems['params'] += self.translate_argument(arg) methodElems['const'] = ' const' if method.constMethod else '' methodElems['semicolon'] = ';' @@ -221,20 +219,20 @@ class CppTranslator(object): methodDict['prototype'] = 'LINPHONECXX_PUBLIC {deprecated}{methodType}{return} {name}({params}){const}{semicolon}'.format(**methodElems) if genImpl: - if not CppTranslator.is_ambigous_type(self, method.returnType): - methodElems['implReturn'] = CppTranslator.translate_type(self, method.returnType, namespace=namespace) + if not self.is_ambigous_type(method.returnType): + methodElems['implReturn'] = self.translate_type(method.returnType, namespace=namespace) else: - methodElems['implReturn'] = CppTranslator.translate_type(self, method.returnType, namespace=None) + methodElems['implReturn'] = self.translate_type(method.returnType, namespace=None) methodElems['longname'] = CppTranslator.translate_method_name(method.name, recursive=True) methodElems['implParams'] = '' for arg in method.args: if arg is not method.args[0]: methodElems['implParams'] += ', ' - methodElems['implParams'] += CppTranslator.translate_argument(self, arg, namespace=namespace) + methodElems['implParams'] += self.translate_argument(arg, namespace=namespace) methodDict['implPrototype'] = '{implReturn} {longname}({implParams}){const}'.format(**methodElems) - methodDict['sourceCode' ] = CppTranslator._generate_source_code(self, method, usedNamespace=namespace) + methodDict['sourceCode' ] = self._generate_source_code(method, usedNamespace=namespace) return methodDict @@ -242,12 +240,12 @@ class CppTranslator(object): nsName = usedNamespace.name if usedNamespace is not None else None params = { 'functionName': method.name.to_c(), - 'args': CppTranslator._generate_wrapped_arguments(self, method, usedNamespace=usedNamespace) + 'args': self._generate_wrapped_arguments(method, usedNamespace=usedNamespace) } if method.name.to_camel_case(lower=True) != 'setListener': cExpr = '{functionName}({args})'.format(**params) - cppExpr = CppTranslator._wrap_c_expression_to_cpp(self, cExpr, method.returnType, usedNamespace=usedNamespace) + cppExpr = self._wrap_c_expression_to_cpp(cExpr, method.returnType, usedNamespace=usedNamespace) else: cppExpr = 'ListenableObject::setListener(std::static_pointer_cast({0}))'.format(method.args[0].name.to_snake_case()) @@ -265,7 +263,7 @@ class CppTranslator(object): for arg in method.args: paramName = arg.name.to_camel_case(lower=True) - args.append(CppTranslator._wrap_cpp_expression_to_c(self, paramName, arg.type, usedNamespace=usedNamespace)) + args.append(self._wrap_cpp_expression_to_c(paramName, arg.type, usedNamespace=usedNamespace)) return ', '.join(args) @@ -280,7 +278,7 @@ class CppTranslator(object): elif type(exprtype) is AbsApi.ClassType: cPtrType = exprtype.desc.name.to_c() if exprtype.desc.refcountable: - ptrType = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace) + ptrType = self.translate_class_type(exprtype, namespace=usedNamespace) ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2) param = { 'ptrType' : ptrType, @@ -298,7 +296,7 @@ class CppTranslator(object): if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': cExpr = 'StringBctbxListWrapper({0}).c_list()'.format(cppExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: - ptrType = CppTranslator.translate_class_type(self, exprtype.containedTypeDesc, namespace=usedNamespace) + ptrType = self.translate_class_type(exprtype.containedTypeDesc, namespace=usedNamespace) if exprtype.containedTypeDesc.desc.refcountable: ptrType = CppTranslator.sharedPtrTypeExtractor.match(ptrType).group(2) cExpr = 'ObjectBctbxListWrapper<{0}>({1}).c_list()'.format(ptrType, cppExpr) @@ -324,10 +322,10 @@ class CppTranslator(object): else: return cExpr elif type(exprtype) is AbsApi.EnumType: - cppEnumName = CppTranslator.translate_enum_type(self, exprtype, namespace=usedNamespace) + cppEnumName = self.translate_enum_type(exprtype, namespace=usedNamespace) return '({0}){1}'.format(cppEnumName, cExpr) elif type(exprtype) is AbsApi.ClassType: - cppReturnType = CppTranslator.translate_class_type(self, exprtype, namespace=usedNamespace) + cppReturnType = self.translate_class_type(exprtype, namespace=usedNamespace) if exprtype.desc.refcountable: cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) @@ -347,7 +345,7 @@ class CppTranslator(object): if type(exprtype.containedTypeDesc) is AbsApi.BaseType and exprtype.containedTypeDesc.name == 'string': return 'StringBctbxListWrapper::bctbxListToCppList({0})'.format(cExpr) elif type(exprtype.containedTypeDesc) is AbsApi.ClassType: - cppReturnType = CppTranslator.translate_class_type(self, exprtype.containedTypeDesc, namespace=usedNamespace) + cppReturnType = self.translate_class_type(exprtype.containedTypeDesc, namespace=usedNamespace) if exprtype.containedTypeDesc.desc.refcountable: cppReturnType = CppTranslator.sharedPtrTypeExtractor.match(cppReturnType).group(2) return 'ObjectBctbxListWrapper<{0}>::bctbxListToCppList({1})'.format(cppReturnType, cExpr) @@ -360,17 +358,17 @@ class CppTranslator(object): return cExpr def translate_argument(self, arg, **params): - return '{0} {1}'.format(CppTranslator.translate_type(self, arg.type, **params), CppTranslator.translate_argument_name(arg.name)) + return '{0} {1}'.format(self.translate_type(arg.type, **params), CppTranslator.translate_argument_name(arg.name)) def translate_type(self, aType, **params): if type(aType) is AbsApi.BaseType: - return CppTranslator.translate_base_type(self, aType) + return self.translate_base_type(aType) elif type(aType) is AbsApi.EnumType: - return CppTranslator.translate_enum_type(self, aType, **params) + return self.translate_enum_type(aType, **params) elif type(aType) is AbsApi.ClassType: - return CppTranslator.translate_class_type(self, aType, **params) + return self.translate_class_type(aType, **params) elif type(aType) is AbsApi.ListType: - return CppTranslator.translate_list_type(self, aType, **params) + return self.translate_list_type(aType, **params) else: CppTranslator.fail(aType) @@ -473,9 +471,9 @@ class CppTranslator(object): if _type.containedTypeDesc is None: raise AbsApi.Error('{0} has not been fixed'.format(_type.containedTypeName)) elif isinstance(_type.containedTypeDesc, AbsApi.BaseType): - res = CppTranslator.translate_type(self, _type.containedTypeDesc) + res = self.translate_type(_type.containedTypeDesc) else: - res = CppTranslator.translate_type(self, _type.containedTypeDesc, **params) + res = self.translate_type(_type.containedTypeDesc, **params) if type(_type.parent) is AbsApi.Argument: return 'const std::list<{0} > &'.format(res) @@ -576,7 +574,7 @@ class ClassHeader(object): self.private_type = _class.name.to_camel_case(fullName=True) self.includes = {'internal': [], 'external': []} - includes = ClassHeader.needed_includes(self, _class) + includes = self.needed_includes(_class) for include in includes['internal']: if _class.name.to_camel_case(fullName=True) == 'LinphoneCore' or (isinstance(_class, AbsApi.Interface) and _class.listenedClass is not None and include == _class.listenedClass.name.to_snake_case()): if include == 'enums': @@ -592,16 +590,16 @@ class ClassHeader(object): self.includes['external'].append({'name': include}) def needed_includes(self, _class): - includes = {'internal': set(), 'external': set()} + includes = {'internal': [], 'external': []} if type(_class) is AbsApi.Class: - includes['internal'].add('object') + self._add_include(includes, 'internal', 'object') - for property in _class.properties: - if property.setter is not None: - ClassHeader._needed_includes_from_method(self, property.setter, includes) - if property.getter is not None: - ClassHeader._needed_includes_from_method(self, property.getter, includes) + for _property in _class.properties: + if _property.setter is not None: + self._needed_includes_from_method(_property.setter, includes) + if _property.getter is not None: + self._needed_includes_from_method(_property.getter, includes) if type(_class) is AbsApi.Class: methods = _class.classMethods + _class.instanceMethods @@ -609,12 +607,12 @@ class ClassHeader(object): methods = _class.methods for method in methods: - ClassHeader._needed_includes_from_type(self, method.returnType, includes) + self._needed_includes_from_type(method.returnType, includes) for arg in method.args: - ClassHeader._needed_includes_from_type(self, arg.type, includes) + self._needed_includes_from_type(arg.type, includes) if isinstance(_class, AbsApi.Class) and _class.listenerInterface is not None: - includes['internal'].add(_class.listenerInterface.name.to_snake_case()) + self._add_include(includes, 'internal', _class.listenerInterface.name.to_snake_case()) currentClassInclude = _class.name.to_snake_case() if currentClassInclude in includes['internal']: @@ -623,25 +621,29 @@ class ClassHeader(object): return includes def _needed_includes_from_method(self, method, includes): - ClassHeader._needed_includes_from_type(self, method.returnType, includes) + self._needed_includes_from_type(method.returnType, includes) for arg in method.args: - ClassHeader._needed_includes_from_type(self, arg.type, includes) + self._needed_includes_from_type(arg.type, includes) def _needed_includes_from_type(self, _type, includes): if isinstance(_type, AbsApi.ClassType): - includes['external'].add('memory') + self._add_include(includes, 'external', 'memory') if _type.desc is not None: - includes['internal'].add(_type.desc.name.to_snake_case()) + self._add_include(includes, 'internal', _type.desc.name.to_snake_case()) elif isinstance(_type, AbsApi.EnumType): - includes['internal'].add('enums') + self._add_include(includes, 'internal', 'enums') elif isinstance(_type, AbsApi.BaseType): if _type.name == 'integer' and isinstance(_type.size, int): - includes['external'].add('cstdint') + self._add_include(includes, 'external', 'cstdint') elif _type.name == 'string': - includes['external'].add('string') + self._add_include(includes, 'external', 'string') elif isinstance(_type, AbsApi.ListType): - includes['external'].add('list') - ClassHeader._needed_includes_from_type(self, _type.containedTypeDesc, includes) + self._add_include(includes, 'external', 'list') + self._needed_includes_from_type(_type.containedTypeDesc, includes) + + def _add_include(self, includes, location, name): + if not name in includes[location]: + includes[location].append(name) class MainHeader(object): @@ -658,16 +660,65 @@ class ClassImpl(object): self.classes = [] self.namespace = 'linphone' -def render(renderer, item, path): - tmppath = path + '.tmp' - content = '' - with open(tmppath, mode='w') as f: - f.write(renderer.render(item)) - with open(tmppath, mode='rU') as f: - content = f.read() - with open(path, mode='w') as f: - f.write(content) - os.unlink(tmppath) +class GenWrapper(object): + def __init__(self, includedir, srcdir, xmldir): + self.includedir = includedir + self.srcdir = srcdir + + project = CApi.Project() + project.initFromDir(xmldir) + project.check() + + self.parser = AbsApi.CParser(project) + self.parser.parse_all() + self.translator = CppTranslator() + self.renderer = pystache.Renderer() + self.mainHeader = MainHeader() + self.impl = ClassImpl() + + def render_all(self): + header = EnumsHeader(self.translator) + for item in self.parser.enumsIndex.items(): + if item[1] is not None: + header.add_enum(item[1]) + else: + print('warning: {0} enum won\'t be translated because of parsing errors'.format(item[0])) + + self.render(header, self.includedir + '/enums.hh') + self.mainHeader.add_include('enums.hh') + + for _class in self.parser.interfacesIndex.values(): + self.render_header(_class) + for _class in self.parser.classesIndex.values(): + self.render_header(_class) + + self.render(self.mainHeader, self.includedir + '/linphone.hh') + self.render(self.impl, self.srcdir + '/linphone++.cc') + + def render(self, item, path): + tmppath = path + '.tmp' + content = '' + with open(tmppath, mode='w') as f: + f.write(self.renderer.render(item)) + with open(tmppath, mode='rU') as f: + content = f.read() + with open(path, mode='w') as f: + f.write(content) + os.unlink(tmppath) + + def render_header(self, _class): + if _class is not None: + try: + header = ClassHeader(_class, self.translator) + headerName = _class.name.to_snake_case() + '.hh' + self.mainHeader.add_include(headerName) + self.render(header, self.includedir + '/' + header.filename) + + if type(_class) is not AbsApi.Interface: + self.impl.classes.append(header._class) + + except AbsApi.Error as e: + print('Could not translate {0}: {1}'.format(_class.name.to_camel_case(fullName=True), e.args[0])) def main(): argparser = argparse.ArgumentParser(description='Generate source files for the C++ wrapper') @@ -692,45 +743,8 @@ def main(): print("Cannot create '{0}' dircetory: {1}".format(srcdir, e.strerror)) sys.exit(1) - project = CApi.Project() - project.initFromDir(args.xmldir) - project.check() - - parser = AbsApi.CParser(project) - parser.parse_all() - translator = CppTranslator() - renderer = pystache.Renderer() - - header = EnumsHeader(translator) - for item in parser.enumsIndex.items(): - if item[1] is not None: - header.add_enum(item[1]) - else: - print('warning: {0} enum won\'t be translated because of parsing errors'.format(item[0])) - - render(renderer, header, includedir + '/enums.hh') - - mainHeader = MainHeader() - mainHeader.add_include('enums.hh') - - impl = ClassImpl() - - for _class in parser.classesIndex.values() + parser.interfacesIndex.values(): - if _class is not None: - try: - header = ClassHeader(_class, translator) - headerName = _class.name.to_snake_case() + '.hh' - mainHeader.add_include(headerName) - render(renderer, header, includedir + '/' + header.filename) - - if type(_class) is not AbsApi.Interface: - impl.classes.append(header._class) - - except AbsApi.Error as e: - print('Could not translate {0}: {1}'.format(_class.name.to_camel_case(fullName=True), e.args[0])) - - render(renderer, mainHeader, includedir + '/linphone.hh') - render(renderer, impl, srcdir + '/linphone++.cc') + genwrapper = GenWrapper(includedir, srcdir, args.xmldir) + genwrapper.render_all() if __name__ == '__main__': From dfca1faff43d12ebbefbdffb37b99d3f5f1b58b3 Mon Sep 17 00:00:00 2001 From: Christophe Deschamps Date: Thu, 6 Apr 2017 09:01:54 +0200 Subject: [PATCH 4/9] Use default config settings (proxy_default_values) for default account creator constructor call back - linphone_account_creator_constructor_linphone --- coreapi/account_creator.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index 3ec020f9b..8096fe99a 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -627,10 +627,14 @@ LinphoneAccountCreatorStatus linphone_account_creator_update_account(LinphoneAcc LinphoneAccountCreatorStatus linphone_account_creator_constructor_linphone(LinphoneAccountCreator *creator) { LinphoneAddress *addr; - linphone_proxy_config_set_realm(creator->proxy_cfg, "sip.linphone.org"); - linphone_proxy_config_set_route(creator->proxy_cfg, "sip.linphone.org"); - linphone_proxy_config_set_server_addr(creator->proxy_cfg, "sip.linphone.org"); - addr = linphone_address_new("sip:username@sip.linphone.org"); + const char *identity = lp_config_get_default_string(creator->core->config, "proxy", "reg_identity", NULL); + const char *proxy = lp_config_get_default_string(creator->core->config, "proxy", "reg_proxy", NULL); + const char *route = lp_config_get_default_string(creator->core->config, "proxy", "reg_route", NULL); + const char *realm = lp_config_get_default_string(creator->core->config, "proxy", "realm", NULL); + linphone_proxy_config_set_realm(creator->proxy_cfg, realm ? realm : "sip.linphone.org"); + linphone_proxy_config_set_route(creator->proxy_cfg, route ? route : "sip.linphone.org"); + linphone_proxy_config_set_server_addr(creator->proxy_cfg, proxy ? proxy : "sip.linphone.org"); + addr = linphone_address_new(identity ? identity : "sip:username@sip.linphone.org"); linphone_proxy_config_set_identity_address(creator->proxy_cfg, addr); linphone_address_unref(addr); return LinphoneAccountCreatorStatusRequestOk; From e8b4dd21eef0c3696ede68f4e47e1fd1ffa7749c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 6 Apr 2017 09:06:40 +0200 Subject: [PATCH 5/9] Remove all calls to 'using namespace' from headers --- coreapi/vcard.cc | 1 + tools/software-desc.hh | 50 +++++++++++++++----------------- wrappers/cpp/class_impl.mustache | 1 + 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 92da60aac..0e3f9ade5 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define VCARD_MD5_HASH_SIZE 16 +using namespace std; struct _LinphoneVcardContext { shared_ptr parser; diff --git a/tools/software-desc.hh b/tools/software-desc.hh index 4063b8097..c20b22425 100644 --- a/tools/software-desc.hh +++ b/tools/software-desc.hh @@ -33,8 +33,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include -using namespace::std; - class Type{ public: @@ -50,7 +48,7 @@ public: Array }; static const char *sBasicTypeNames[]; - static Type* addType(BasicType bt, const string &name){ + static Type* addType(BasicType bt, const std::string &name){ Type* ret; if ((ret=mTypes[name])==0){ //cout<<"Adding new "< mTypes; + static std::map mTypes; }; class Argument{ public: - Argument(Type *type, const string &argname, bool isConst, bool isPointer) : mType(type), mName(argname), mConst(isConst), mPointer(isPointer){ + Argument(Type *type, const std::string &argname, bool isConst, bool isPointer) : mType(type), mName(argname), mConst(isConst), mPointer(isPointer){ if (!isPointer) mConst=false; } Type *getType()const{ @@ -134,23 +132,23 @@ public: bool isConst()const{ return mConst; } - const string &getName()const{ + const std::string &getName()const{ return mName; } bool isPointer()const{ return mPointer; } - const string &getHelp()const{ + const std::string &getHelp()const{ return mHelp; } - void setHelp(const string &help){ + void setHelp(const std::string &help){ mHelp=help; } private: Type *mType; - string mName; - string mHelp; + std::string mName; + std::string mHelp; bool mConst; bool mPointer; }; diff --git a/wrappers/cpp/class_impl.mustache b/wrappers/cpp/class_impl.mustache index 142413ff9..ec0c55c07 100644 --- a/wrappers/cpp/class_impl.mustache +++ b/wrappers/cpp/class_impl.mustache @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone++/linphone.hh" #include "tools.hh" +using namespace std; using namespace {{{namespace}}}; {{#classes}} From 13b127caa24f036871e3e8b2b0051ab93d7be646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 6 Apr 2017 11:01:04 +0200 Subject: [PATCH 6/9] C++ wrapper: systematically include object.hh in each generated header file --- wrappers/cpp/class_header.mustache | 1 + wrappers/cpp/genwrapper.py | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/wrappers/cpp/class_header.mustache b/wrappers/cpp/class_header.mustache index d3ed12f23..b228eb93f 100644 --- a/wrappers/cpp/class_header.mustache +++ b/wrappers/cpp/class_header.mustache @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "{{name}}.hh" {{/internal}} {{/includes}} +#include "object.hh" {{#_class}}{{#isVcard}} #include diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py index caf8eec6b..2a0080a93 100755 --- a/wrappers/cpp/genwrapper.py +++ b/wrappers/cpp/genwrapper.py @@ -593,8 +593,6 @@ class ClassHeader(object): includes = {'internal': [], 'external': []} if type(_class) is AbsApi.Class: - self._add_include(includes, 'internal', 'object') - for _property in _class.properties: if _property.setter is not None: self._needed_includes_from_method(_property.setter, includes) From d8568491eb9d571b1fba761f11308950eb79eb65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 6 Apr 2017 12:02:03 +0200 Subject: [PATCH 7/9] Add linphone_core_create_account_creator() --- coreapi/account_creator.c | 10 +++++++++- include/linphone/core.h | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index 8096fe99a..0c6a3abd8 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -314,7 +314,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneAccountCreator, belle_sip_object_t, FALSE ); -LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url) { +LinphoneAccountCreator * _linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url) { LinphoneAccountCreator *creator; const char* domain = lp_config_get_string(core->config, "assistant", "domain", NULL); creator = belle_sip_object_new(LinphoneAccountCreator); @@ -331,6 +331,14 @@ LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const return creator; } +LinphoneAccountCreator * linphone_account_creator_new(LinphoneCore *core, const char *xmlrpc_url) { + return _linphone_account_creator_new(core, xmlrpc_url); +} + +LinphoneAccountCreator * linphone_core_create_account_creator(LinphoneCore *core, const char *xmlrpc_url) { + return _linphone_account_creator_new(core, xmlrpc_url); +} + LinphoneAccountCreator * linphone_account_creator_ref(LinphoneAccountCreator *creator) { belle_sip_object_ref(creator); return creator; diff --git a/include/linphone/core.h b/include/linphone/core.h index 3669b438f..d98c4a33f 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -4890,6 +4890,16 @@ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_core_create_nat_policy(LinphoneCore LINPHONE_PUBLIC LinphoneNatPolicy * linphone_core_create_nat_policy_from_config(LinphoneCore *lc, const char *ref); +/** + * Create a LinphoneAccountCreator and set Linphone Request callbacks. + * @param[in] core The LinphoneCore used for the XML-RPC communication + * @param[in] xmlrpc_url The URL to the XML-RPC server. Must be NON NULL. + * @return The new LinphoneAccountCreator object. + * @ingroup account_creator +**/ +LINPHONE_PUBLIC LinphoneAccountCreator * linphone_core_create_account_creator(LinphoneCore *core, const char *xmlrpc_url); + + #ifdef __cplusplus } #endif From ed813724f7c87424d544ebde74a266ac17bec3e6 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Thu, 6 Apr 2017 12:08:24 +0200 Subject: [PATCH 8/9] Fix wakelock possible leak in android on Linphone destroy --- java/impl/org/linphone/core/LinphoneCoreImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index 4220601f4..f1e2f6da6 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -333,8 +333,8 @@ class LinphoneCoreImpl implements LinphoneCore { return new LinphoneCallLogImpl(callLog); } public synchronized void destroy() { - setAndroidPowerManager(null); delete(nativePtr); + setAndroidPowerManager(null); nativePtr=0; } From a1fe7e4b0430dfd5b49d4c757b7dbe2128ea5f83 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Thu, 6 Apr 2017 14:04:25 +0200 Subject: [PATCH 9/9] Add linphone chat method resend to JNI --- coreapi/linphonecore_jni.cc | 6 ++++++ java/common/org/linphone/core/LinphoneChatMessage.java | 4 ++++ java/impl/org/linphone/core/LinphoneChatMessageImpl.java | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 75a41eead..9a40acbc7 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -4575,6 +4575,12 @@ extern "C" jboolean Java_org_linphone_core_LinphoneChatMessageImpl_isSecured(JNI return linphone_chat_message_is_secured((LinphoneChatMessage*)ptr); } +extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_resend(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + linphone_chat_message_resend((LinphoneChatMessage*)ptr); +} + static void message_state_changed(LinphoneChatMessage* msg, LinphoneChatMessageState state) { JNIEnv *env = 0; jint result = jvm->AttachCurrentThread(&env,NULL); diff --git a/java/common/org/linphone/core/LinphoneChatMessage.java b/java/common/org/linphone/core/LinphoneChatMessage.java index 2c384c897..aeec09645 100644 --- a/java/common/org/linphone/core/LinphoneChatMessage.java +++ b/java/common/org/linphone/core/LinphoneChatMessage.java @@ -252,4 +252,8 @@ public interface LinphoneChatMessage { */ boolean isSecured(); + /** + * Resend the message + */ + void reSend(); } diff --git a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java index bc3ba3c3c..9ca40a269 100644 --- a/java/impl/org/linphone/core/LinphoneChatMessageImpl.java +++ b/java/impl/org/linphone/core/LinphoneChatMessageImpl.java @@ -172,4 +172,10 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage { public boolean isSecured() { return isSecured(nativePtr); } + + private native void reSend(long nativePtr); + @Override + public void reSend() { + reSend(nativePtr); + } }