diff options
| author | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-01-04 09:13:36 +0000 |
|---|---|---|
| committer | Benjamin Dauvergne <bdauvergne@entrouvert.com> | 2010-01-04 09:13:36 +0000 |
| commit | 5224c7cf675d6c8b2df9b3f4b43f8cd8d4eb8184 (patch) | |
| tree | fc571c8d011bd0b73d932601e0b026f338e5d675 /bindings/php5 | |
| parent | 42062ff986a344f3f33a4465e106fede10aeaa6a (diff) | |
| download | lasso-5224c7cf675d6c8b2df9b3f4b43f8cd8d4eb8184.tar.gz lasso-5224c7cf675d6c8b2df9b3f4b43f8cd8d4eb8184.tar.xz lasso-5224c7cf675d6c8b2df9b3f4b43f8cd8d4eb8184.zip | |
Bindings: make the binding infrastructure understand GObject-introspections annotations
* bindings/bindings.py
* bindings/utils.py:
add convenience function to treat arguments tuple:
(type,name,{annotations}).
introduce new argument options, fix that arguments are 3-tuple of the
form (type,name,annotations), where annotations is a dictionary.
Key of this dictionnary can be:
- optional, wheter the argument is necessary, it means it has a
default value.
- out, means that the pointer is a pointer of pointer, for bindings
that can return exceptions, it will be returned instead of the
integer error code, the only way to access error codes will be
exceptions.
- element-type, contained type of a list or an array,
- key-type, value-type, type of respectively the key and value of a
GHashTable.
- transfer, wheter a the callee(for arguments)/caller(for return
values) owns the values passed, it can be none,container(if the
callee/caller only owns the container not the contained value) or
full.
doc.parameters is now a 3-tuple of (attribute-name,
attribute-description, attribute-annotations) where
attribute-annotations is a string of the form '(option1)(option2
option-arguments) etc.'.
- add predicates for xml, list and time_t values. improve predicates
for cstring and const modifier.
* bindings/overrides.xml:
'out' arguments are not well supported for java, so skip functions
using them.
* bindings/java/lang.py bindings/php5/php_code.py
bindings/php5/wrapper_source.py bindings/python/lang.py:
- update language specifig binding generators for handling new
annotations.
- improve python method declaration, handle optional arguments with
default values, factorize this chode in two methods,
get_python_arg_decl and defval_to_python_value.
* bindings/python/tests/Makefile.am
bindings/python/tests/idwsf1_tests.py
bindings/python/tests/idwsf2_tests.py:
make test work with out of source build dir.
Diffstat (limited to 'bindings/php5')
| -rw-r--r-- | bindings/php5/php_code.py | 21 | ||||
| -rw-r--r-- | bindings/php5/wrapper_source.py | 100 |
2 files changed, 106 insertions, 15 deletions
diff --git a/bindings/php5/php_code.py b/bindings/php5/php_code.py index 76bae23d..64439778 100644 --- a/bindings/php5/php_code.py +++ b/bindings/php5/php_code.py @@ -22,7 +22,7 @@ import re import sys -import utils +from utils import * class PhpCode: def __init__(self, binding_data, fd): @@ -135,7 +135,7 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { print >> self.fd, '' def generate_constructors(self, klass): - method_prefix = utils.format_as_underscored(klass.name) + '_' + method_prefix = format_as_underscored(klass.name) + '_' for m in self.binding_data.functions: if m.name == method_prefix + 'new': php_args = [] @@ -183,7 +183,7 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { for m in klass.members: mtype = m[0] - mname = utils.format_as_camelcase(m[1]) + mname = format_as_camelcase(m[1]) options = m[2] # Getters @@ -253,7 +253,7 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { except IndexError: setter = None mname = re.match(r'lasso_.*_get_(\w+)', meth_name).group(1) - mname =utils.format_as_camelcase(mname) + mname = format_as_camelcase(mname) print >> self.fd, ' /**' print >> self.fd, ' * @return %s' % self.get_docstring_return_type(m.return_type) @@ -278,7 +278,7 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { print >> self.fd, '' # second pass on methods, real methods - method_prefix = utils.format_as_underscored(klass.name) + '_' + method_prefix = format_as_underscored(klass.name) + '_' for m in methods: if m.name.endswith('_new') or m.name.endswith('_new_from_dump') or \ m.name.endswith('_new_full'): @@ -295,9 +295,13 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { mname = mname[len(method_prefix):] php_args = [] c_args = [] + outarg = None for arg in m.args[1:]: arg_type, arg_name, arg_options = arg arg_name = '$' + arg_name + if is_out(arg): + assert not outarg + outarg = arg if arg_options.get('optional'): if arg_options.get('default'): defval = arg_options.get('default') @@ -318,6 +322,11 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { c_args.append(arg_name) else: c_args.append('%s._cptr' % arg_name) + if is_out(arg): + php_args.pop() + php_args.append(arg_name) + c_args.pop() + c_args.append(arg_name) if php_args: php_args = ', '.join(php_args) @@ -331,7 +340,7 @@ function lassoRegisterIdWsf2DstService($prefix, $href) { if m.docstring: print >> self.fd, self.generate_docstring(m, mname, 4) print >> self.fd, ' public function %s(%s) {' % ( - utils.format_underscore_as_camelcase(mname), php_args) + format_underscore_as_camelcase(mname), php_args) if m.return_type == 'void': print >> self.fd, ' %s($this->_cptr%s);' % (cname, c_args) elif m.return_type in ('gint', 'int'): diff --git a/bindings/php5/wrapper_source.py b/bindings/php5/wrapper_source.py index 690c4adb..5775b7be 100644 --- a/bindings/php5/wrapper_source.py +++ b/bindings/php5/wrapper_source.py @@ -22,7 +22,7 @@ import sys import os -import utils +from utils import * class WrapperSource: def __init__(self, binding_data, fd): @@ -32,7 +32,7 @@ class WrapperSource: self.src_dir = os.path.dirname(__file__) def is_object(self, t): - return t not in ['char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', + return t not in ['char*', 'const char*', 'gchar*', 'const gchar*', 'GList*', 'GHashTable*', 'GType', 'xmlNode*', 'int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums def generate(self): @@ -101,12 +101,81 @@ PHP_MSHUTDOWN_FUNCTION(lasso) ''' + def set_zval(self, zval_name, c_variable, type, free = False): + '''Emit code to set a zval* of name zval_name, from the value of the C variable called c_variable type, type. + ''' + # first we free the previous value + p = (zval_name, c_variable) + q = { 'zval_name' : zval_name, 'c_variable' : c_variable } + print >> self.fd, ' zval_dtor(%s);' % zval_name + if is_pointer(type): + print >> self.fd, ' if (! %s) {' % c_variable + print >> self.fd, ' ZVAL_NULL(%s);' % zval_name + print >> self.fd, ' } else {' + if is_int(type, self.binding_data): + print >> self.fd, ' ZVAL_LONG(%s, %s);' % p + elif is_boolean(type): + print >> self.fd, ' ZVAL_BOOL(%s, %s);' % p + elif is_cstring(type): + print >> self.fd, ' ZVAL_STRING(%s, %s, 1);' % p + if free and not is_const(type): + print >> self.fd, 'g_free(%s)' % c_variable + elif arg_type(type) == 'xmlNode*': + print >> self.fd, '''\ + { + char* xmlString = get_string_from_xml_node(%(c_variable)s); + if (xmlString) { + ZVAL_STRING(%(zval_name)s, xmlString, 0); + } else { + ZVAL_NULL(%(zval_name)s); + } + } +''' % q + elif arg_type(type) == 'GList*': + elem_type = make_arg(element_type(type)) + if not arg_type(elem_type): + raise Exception('unknown elem_type: ' + repr(type)) + if is_cstring(elem_type): + function = 'set_array_from_list_of_strings' + free_function = 'free_glist(%(c_variable)s, (GFunc)free);' + elif arg_type(elem_type).startswith('xmlNode'): + function = 'set_array_from_list_of_xmlnodes' + free_function = 'free_glist(%(c_variable)s, (GFunc)xmlFree);' + elif is_object(elem_type): + function = 'set_array_from_list_of_objects' + free_function = 'g_list_free(%(c_variable)s);' + else: + raise Exception('unknown elem_type: ' + repr(type)) + print >> self.fd, ' %s(%s, &%s);' % (function, c_variable, zval_name) + if free: + print >> self.fd, ' ', free_function % q + elif is_object(type): + print >> self.fd, '''\ + if (G_IS_OBJECT(%(c_variable)s)) { + PhpGObjectPtr *obj = PhpGObjectPtr_New(G_OBJECT(%(c_variable)s)); + ZEND_REGISTER_RESOURCE(%(zval_name)s, obj, le_lasso_server); + } else { + ZVAL_NULL(%(zval_name)s); + }''' % q + if free: + print >> self.fd, '''\ + if (%(c_variable)s) { + g_object_unref(%(c_variable)s); // If constructor ref is off by one' + }''' % q + + else: + raise Exception('unknown type: ' + repr(type) + unconstify(arg_type(type))) + if is_pointer(type): + print >> self.fd, ' }' + + + def return_value(self, vtype, options, free = False): if vtype is None: return elif vtype == 'gboolean': print >> self.fd, ' RETVAL_BOOL(return_c_value);' - elif vtype in ['int', 'gint'] + self.binding_data.enums: + elif vtype in ['int', 'gint', 'GType', ] + self.binding_data.enums: print >> self.fd, ' RETVAL_LONG(return_c_value);' elif vtype in ('char*', 'gchar*'): print >> self.fd, '''\ @@ -186,7 +255,12 @@ PHP_MSHUTDOWN_FUNCTION(lasso) parse_tuple_args = [] for arg in m.args: arg_type, arg_name, arg_options = arg - if arg_type in ('char*', 'const char*', 'gchar*', 'const gchar*'): + if is_out(arg): + print >> self.fd, ' zval *php_out_%s = NULL;' % arg_name + print >> self.fd, ' %s %s;' % (var_type(arg), arg_name) + parse_tuple_format.append('z!') + parse_tuple_args.append('&php_out_%s' % arg_name) + elif arg_type in ('char*', 'const char*', 'gchar*', 'const gchar*'): arg_type = arg_type.replace('const ', '') parse_tuple_format.append('s!') parse_tuple_args.append('&%s_str, &%s_len' % (arg_name, arg_name)) @@ -232,7 +306,9 @@ PHP_MSHUTDOWN_FUNCTION(lasso) ''' % (''.join(parse_tuple_format), parse_tuple_args) for f, arg in zip(parse_tuple_format, m.args): - if arg[0] == 'xmlNode*': + if is_out(arg): + continue + elif arg[0] == 'xmlNode*': print >> self.fd, '''\ %(name)s = get_xml_node_from_string(%(name)s_str);''' % {'name': arg[1]} elif f.startswith('s'): @@ -259,12 +335,18 @@ PHP_MSHUTDOWN_FUNCTION(lasso) print >> self.fd, '(%s)' % m.return_type, else: print >> self.fd, ' ', - print >> self.fd, '%s(%s);' % (m.name, ', '.join([x[1] for x in m.args])) + print >> self.fd, '%s(%s);' % (m.name, ', '.join([ref_name(x) for x in m.args])) # Free the converted arguments for f, arg in zip(parse_tuple_format, m.args): argtype, argname, argoptions = arg - if argtype == 'xmlNode*': + if is_out(arg): + # export the returned variable + free = is_transfer_full(unref_type(arg)) + print m + self.set_zval('php_out_%s' % argname, argname, unref_type(arg), free = free) + pass + elif argtype == 'xmlNode*': print >> self.fd, ' xmlFree(%s);' % argname elif f.startswith('a'): elem_type = arg[2].get('elem_type') @@ -289,7 +371,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('elem_type')) return - function_name = '%s_%s_get' % (klassname, utils.format_as_camelcase(m_name)) + function_name = '%s_%s_get' % (klassname, format_as_camelcase(m_name)) print >> self.fd, '''PHP_FUNCTION(%s) {''' % function_name self.functions_list.append(function_name) @@ -333,7 +415,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso) print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('elem_type')) return - function_name = '%s_%s_set' % (klassname, utils.format_as_camelcase(m_name)) + function_name = '%s_%s_set' % (klassname, format_as_camelcase(m_name)) print >> self.fd, '''PHP_FUNCTION(%s) {''' % function_name self.functions_list.append(function_name) |
