mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
Beginning of the implementation of linphone_core_new() wrapper + Allow setting log handler from python.
This commit is contained in:
parent
a4c2f0ef36
commit
1a2990a8b6
4 changed files with 134 additions and 77 deletions
|
|
@ -72,13 +72,12 @@ blacklisted_functions = [
|
|||
'linphone_core_get_supported_video_sizes',
|
||||
'linphone_core_get_video_codecs',
|
||||
'linphone_core_get_video_policy',
|
||||
'linphone_core_new',
|
||||
'linphone_core_new_with_config',
|
||||
'linphone_core_payload_type_enabled',
|
||||
'linphone_core_payload_type_is_vbr',
|
||||
'linphone_core_publish',
|
||||
'linphone_core_set_log_file',
|
||||
'linphone_core_set_log_handler',
|
||||
'linphone_core_set_log_handler', # Hand-written but put directly in the linphone module
|
||||
'linphone_core_set_log_level',
|
||||
'linphone_core_set_payload_type_bitrate',
|
||||
'linphone_core_set_preferred_video_size',
|
||||
|
|
@ -107,12 +106,16 @@ blacklisted_functions = [
|
|||
'lp_config_load_dict_to_section',
|
||||
'lp_config_section_to_dict'
|
||||
]
|
||||
hand_written_functions = [
|
||||
'linphone_core_new'
|
||||
]
|
||||
|
||||
def generate(apixmlfile):
|
||||
tree = ET.parse(apixmlfile)
|
||||
renderer = pystache.Renderer()
|
||||
m = LinphoneModule(tree, blacklisted_classes, blacklisted_functions)
|
||||
m = LinphoneModule(tree, blacklisted_classes, blacklisted_functions, hand_written_functions)
|
||||
f = open("linphone.c", "w")
|
||||
os.chdir('apixml2python')
|
||||
f.write(renderer.render(m))
|
||||
|
||||
|
||||
|
|
|
|||
108
tools/python/apixml2python/handwritten.mustache
Normal file
108
tools/python/apixml2python/handwritten.mustache
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
static void pylinphone_log(const char *level, int indent, const char *fmt, va_list args) {
|
||||
static int current_indent = 1;
|
||||
PyObject *linphone_module = PyImport_ImportModule("linphone");
|
||||
if ((linphone_module != NULL) && PyObject_HasAttrString(linphone_module, "__log_handler")) {
|
||||
PyObject *log_handler = PyObject_GetAttrString(linphone_module, "__log_handler");
|
||||
if ((log_handler != NULL) && PyFunction_Check(log_handler)) {
|
||||
char logstr[4096];
|
||||
int i = 0;
|
||||
if (indent == -1) current_indent--;
|
||||
if (current_indent < 1) current_indent = 1;
|
||||
if ((indent >= -1) && (indent <= 1)) {
|
||||
for (i = 0; i < current_indent; i++) {
|
||||
logstr[i] = '\t';
|
||||
}
|
||||
}
|
||||
if (indent == 1) current_indent++;
|
||||
if (vsnprintf(logstr + i, sizeof(logstr) - i, fmt, args) > 0) {
|
||||
PyEval_CallFunction(log_handler, "ss", level, logstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PYLINPHONE_INLINE void pylinphone_trace(int indent, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
pylinphone_log("debug", indent, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static const char * pylinphone_ortp_log_level_to_string(OrtpLogLevel lev) {
|
||||
switch (lev) {
|
||||
default:
|
||||
case ORTP_DEBUG:
|
||||
return "debug";
|
||||
case ORTP_MESSAGE:
|
||||
return "info";
|
||||
case ORTP_WARNING:
|
||||
return "warning";
|
||||
case ORTP_ERROR:
|
||||
return "error";
|
||||
case ORTP_FATAL:
|
||||
return "critical";
|
||||
case ORTP_TRACE:
|
||||
return "debug";
|
||||
}
|
||||
}
|
||||
|
||||
static void pylinphone_module_log_handler(OrtpLogLevel lev, const char *fmt, va_list args) {
|
||||
PyObject *linphone_module = PyImport_ImportModule("linphone");
|
||||
const char *level = pylinphone_ortp_log_level_to_string(lev);
|
||||
if ((linphone_module != NULL) && PyObject_HasAttrString(linphone_module, "__log_handler")) {
|
||||
PyObject *log_handler = PyObject_GetAttrString(linphone_module, "__log_handler");
|
||||
if ((log_handler != NULL) && PyFunction_Check(log_handler)) {
|
||||
char logstr[4096];
|
||||
if (vsnprintf(logstr, sizeof(logstr), fmt, args) > 0) {
|
||||
PyEval_CallFunction(log_handler, "ss", level, logstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void pylinphone_init_logging(void) {
|
||||
linphone_core_set_log_handler(pylinphone_module_log_handler);
|
||||
linphone_core_set_log_level(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
|
||||
}
|
||||
|
||||
|
||||
static PyObject * pylinphone_module_method_set_log_handler(PyObject *self, PyObject *args) {
|
||||
PyObject *linphone_module = PyImport_ImportModule("linphone");
|
||||
PyObject *callback;
|
||||
if (!PyArg_ParseTuple(args, "O", &callback)) {
|
||||
return NULL;
|
||||
}
|
||||
if (linphone_module != NULL) {
|
||||
Py_INCREF(callback);
|
||||
PyObject_SetAttrString(linphone_module, "__log_handler", callback);
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject * pylinphone_Core_class_method_new(PyObject *cls, PyObject *args) {
|
||||
LinphoneCore * cresult;
|
||||
pylinphone_CoreObject *self;
|
||||
PyObject * pyret;
|
||||
LinphoneCoreVTable _vtable = { 0 };
|
||||
const char * _config_path;
|
||||
const char * _factory_config_path;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "zz", &_config_path, &_factory_config_path)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = (pylinphone_CoreObject *)PyObject_New(pylinphone_CoreObject, &pylinphone_CoreType);
|
||||
if (self == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pylinphone_trace(1, "[PYLINPHONE] >>> %s(\"%s\", \"%s\")", __FUNCTION__, _config_path, _factory_config_path);
|
||||
cresult = linphone_core_new(&_vtable, _config_path, _factory_config_path, self);
|
||||
self->native_ptr = cresult;
|
||||
|
||||
pyret = Py_BuildValue("O", self);
|
||||
|
||||
pylinphone_trace(-1, "[PYLINPHONE] <<< %s -> %p", __FUNCTION__, pyret);
|
||||
Py_DECREF(self);
|
||||
return pyret;
|
||||
}
|
||||
|
|
@ -537,7 +537,7 @@ class SetterMethodDefinition(MethodDefinition):
|
|||
|
||||
|
||||
class LinphoneModule(object):
|
||||
def __init__(self, tree, blacklisted_classes, blacklisted_functions):
|
||||
def __init__(self, tree, blacklisted_classes, blacklisted_functions, hand_written_functions):
|
||||
self.internal_instance_method_names = ['destroy', 'ref', 'unref']
|
||||
self.internal_property_names = ['user_data']
|
||||
self.enums = []
|
||||
|
|
@ -577,6 +577,7 @@ class LinphoneModule(object):
|
|||
c['class_destroyable'] = (xml_class.get('destroyable') == 'true')
|
||||
c['class_has_user_data'] = False
|
||||
c['class_type_methods'] = []
|
||||
c['class_type_hand_written_methods'] = []
|
||||
xml_type_methods = xml_class.findall("./classmethods/classmethod")
|
||||
for xml_type_method in xml_type_methods:
|
||||
if xml_type_method.get('deprecated') == 'true':
|
||||
|
|
@ -586,8 +587,11 @@ class LinphoneModule(object):
|
|||
continue
|
||||
m = {}
|
||||
m['method_name'] = method_name.replace(c['class_c_function_prefix'], '')
|
||||
m['method_xml_node'] = xml_type_method
|
||||
c['class_type_methods'].append(m)
|
||||
if method_name in hand_written_functions:
|
||||
c['class_type_hand_written_methods'].append(m)
|
||||
else:
|
||||
m['method_xml_node'] = xml_type_method
|
||||
c['class_type_methods'].append(m)
|
||||
c['class_instance_methods'] = []
|
||||
xml_instance_methods = xml_class.findall("./instancemethods/instancemethod")
|
||||
for xml_instance_method in xml_instance_methods:
|
||||
|
|
|
|||
|
|
@ -30,76 +30,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#endif
|
||||
|
||||
|
||||
static PyObject *logging_module = NULL;
|
||||
static int current_indent = 1;
|
||||
|
||||
|
||||
static void init_logging(void) {
|
||||
logging_module = PyImport_ImportModule("logging");
|
||||
if (logging_module != NULL) {
|
||||
PyObject *constant;
|
||||
PyObject *func;
|
||||
PyObject *kws;
|
||||
long level = 0;
|
||||
|
||||
constant = PyObject_GetAttrString(logging_module, "DEBUG");
|
||||
if (PyInt_Check(constant)) {
|
||||
level = PyInt_AsLong(constant);
|
||||
}
|
||||
Py_DECREF(constant);
|
||||
func = PyObject_GetAttrString(logging_module, "basicConfig");
|
||||
kws = Py_BuildValue("{s:i,s:s}", "level", level, "format", "%(levelname)s: %(message)s");
|
||||
PyEval_CallObjectWithKeywords(func, NULL, kws);
|
||||
Py_DECREF(kws);
|
||||
Py_DECREF(func);
|
||||
}
|
||||
}
|
||||
|
||||
static void pylinphone_log(const char *level, int indent, const char *fmt, va_list args) {
|
||||
if (logging_module != NULL) {
|
||||
char logstr[4096];
|
||||
int i = 0;
|
||||
if (indent == -1) current_indent--;
|
||||
if (current_indent < 1) current_indent = 1;
|
||||
if ((indent >= -1) && (indent <= 1)) {
|
||||
for (i = 0; i < current_indent; i++) {
|
||||
logstr[i] = '\t';
|
||||
}
|
||||
}
|
||||
if (indent == 1) current_indent++;
|
||||
if (vsnprintf(logstr + i, sizeof(logstr) - i, fmt, args) > 0) {
|
||||
PyEval_CallMethod(logging_module, level, "(s)", logstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static PYLINPHONE_INLINE void pylinphone_debug(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
pylinphone_log("debug", 0xff, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static PYLINPHONE_INLINE void pylinphone_info(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
pylinphone_log("info", 0xff, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static PYLINPHONE_INLINE void pylinphone_warning(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
pylinphone_log("warning", 0xff, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
static PYLINPHONE_INLINE void pylinphone_trace(int indent, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
pylinphone_log("debug", indent, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
static PYLINPHONE_INLINE void pylinphone_trace(int indent, const char *fmt, ...);
|
||||
|
||||
|
||||
{{#classes}}
|
||||
|
|
@ -118,6 +49,9 @@ typedef struct {
|
|||
{{#classes}}
|
||||
static {{class_cname}} * pylinphone_{{class_name}}_get_native_ptr(PyObject *self);
|
||||
static PyObject * pylinphone_{{class_name}}_new_from_native_ptr(PyTypeObject *type, const {{class_cname}} *native_ptr);
|
||||
{{#class_type_hand_written_methods}}
|
||||
static PyObject * pylinphone_{{class_name}}_class_method_{{method_name}}(PyObject *cls, PyObject *args);
|
||||
{{/class_type_hand_written_methods}}
|
||||
{{/classes}}
|
||||
|
||||
{{#classes}}
|
||||
|
|
@ -157,6 +91,9 @@ static PyObject * pylinphone_{{class_name}}_instance_method_{{method_name}}(PyOb
|
|||
static PyMethodDef pylinphone_{{class_name}}_instance_methods[] = {
|
||||
// TODO: Handle doc
|
||||
/* Class methods */
|
||||
{{#class_type_hand_written_methods}}
|
||||
{ "{{method_name}}", pylinphone_{{class_name}}_class_method_{{method_name}}, METH_VARARGS | METH_CLASS, "" },
|
||||
{{/class_type_hand_written_methods}}
|
||||
{{#class_type_methods}}
|
||||
{ "{{method_name}}", pylinphone_{{class_name}}_class_method_{{method_name}}, METH_VARARGS | METH_CLASS, "" },
|
||||
{{/class_type_methods}}
|
||||
|
|
@ -234,8 +171,13 @@ static PyTypeObject pylinphone_{{class_name}}Type = {
|
|||
|
||||
{{/classes}}
|
||||
|
||||
|
||||
{{> handwritten}}
|
||||
|
||||
|
||||
static PyMethodDef pylinphone_ModuleMethods[] = {
|
||||
/* Sentinel */
|
||||
{ "set_log_handler", pylinphone_module_method_set_log_handler, METH_VARARGS, "" },
|
||||
{ NULL, NULL, 0, NULL }
|
||||
};
|
||||
|
||||
|
|
@ -248,7 +190,7 @@ PyMODINIT_FUNC initlinphone(void) {
|
|||
PyObject *m;
|
||||
PyObject *menum;
|
||||
|
||||
init_logging();
|
||||
pylinphone_init_logging();
|
||||
|
||||
{{#classes}}
|
||||
if (PyType_Ready(&pylinphone_{{class_name}}Type) < 0) return;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue