summaryrefslogtreecommitdiffstats
path: root/bindings
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-04 09:13:36 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-04 09:13:36 +0000
commit5224c7cf675d6c8b2df9b3f4b43f8cd8d4eb8184 (patch)
treefc571c8d011bd0b73d932601e0b026f338e5d675 /bindings
parent42062ff986a344f3f33a4465e106fede10aeaa6a (diff)
downloadlasso-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')
-rw-r--r--bindings/bindings.py80
-rw-r--r--bindings/java/lang.py57
-rw-r--r--bindings/overrides.xml14
-rw-r--r--bindings/php5/php_code.py21
-rw-r--r--bindings/php5/wrapper_source.py100
-rw-r--r--bindings/python/lang.py211
-rw-r--r--bindings/python/tests/Makefile.am2
-rwxr-xr-xbindings/python/tests/idwsf1_tests.py41
-rwxr-xr-xbindings/python/tests/idwsf2_tests.py2
-rw-r--r--bindings/utils.py111
10 files changed, 481 insertions, 158 deletions
diff --git a/bindings/bindings.py b/bindings/bindings.py
index a00b8cea..eaa69a37 100644
--- a/bindings/bindings.py
+++ b/bindings/bindings.py
@@ -25,7 +25,7 @@
import os
import re
import sys
-import utils
+from utils import *
from optparse import OptionParser
@@ -241,12 +241,14 @@ class Function:
class DocString:
orig_docstring = None
- parameters = []
+ parameters = None
return_value = None
description = None
def __init__(self, function, docstring):
self.orig_docstring = docstring
+ self.parameters = []
+ self.params = {}
lines = docstring.splitlines()
# ignore the first line, it has the symbol name
lines = lines[1:]
@@ -260,8 +262,52 @@ class DocString:
self.parameters = []
if lines[0][0] == '@':
- param_name, param_desc = lines[0][1:].split(':', 1)
- self.parameters.append([param_name, param_desc])
+
+ splits = lines[0][1:].split(':', 2)
+ param_name = splits[0]
+ if len(splits) > 2:
+ param_options = splits[1]
+ param_desc = splits[2]
+ self.parameters.append([param_name, param_desc, param_options])
+ self.params[param_name] = { 'desc': param_desc, 'options': param_options }
+ for a in function.args:
+ if a[1] == param_name:
+ arg = a
+ break
+ else:
+ raise Exception('should not happen ' + param_name + ' ' + lines[0] + repr(function))
+ if 'allow-none' in param_options:
+ arg[2]['optional'] = True
+ if re.search('\(\s*out\s*\)', param_options):
+ arg[2]['out'] = True
+ if arg[2].get('optional'):
+ m = re.search('\(\s*default\s*(.*)\s*\)', param_options)
+ if m:
+ prefix = ''
+ if is_boolean(arg):
+ prefix = 'b:'
+ elif is_int(arg):
+ prefix = 'c:'
+ else:
+ raise Exception('should not happen: could not found type for default: ' + param_options)
+ arg[2]['default'] = prefix + m.group(1)
+ m = re.search('\(\s*element-type\s+(\w+)(?:\s+(\w+))?', param_options)
+ if m:
+ if len(m.groups()) > 2:
+ arg[2]['key-type'] = \
+ convert_type_from_gobject_annotation(m.group(1))
+ arg[2]['value-type'] = \
+ convert_type_from_gobject_annotation(m.group(2))
+ else:
+ arg[2]['element-type'] = \
+ convert_type_from_gobject_annotation(m.group(1))
+ m = re.search('\(\s*transfer\s+(\w+)', param_options)
+ if m:
+ arg[2]['transfer'] = m.group(1)
+ else:
+ param_desc = splits[1]
+ self.parameters.append([param_name, param_desc])
+ self.params[param_name] = { 'desc': param_desc }
else:
# continuation of previous description
self.parameters[-1][1] = self.parameters[-1][1] + ' ' + lines[0].strip()
@@ -359,9 +405,7 @@ def parse_header(header_file):
elif line.startswith('struct _'):
m = re.match('struct ([a-zA-Z0-9_]+)', line)
struct_name = m.group(1)
- #print struct_name
if struct_name in struct_names:
- #print struct_name
in_struct = Struct(struct_name)
in_struct_private = False
elif in_struct:
@@ -399,23 +443,21 @@ def parse_header(header_file):
i += 1
line = line[:-1] + lines[i].lstrip()
- m = re.match(r'LASSO_EXPORT\s+((?:const |)[\w]+\s*\*?)\s+(OFTYPE\(.*?\)\s*)?(\*?\w+)\s*\((.*?)\)', line)
- if m and not m.group(3).endswith('_get_type'):
- return_type, oftype, function_name, args = m.groups()
+ m = re.match(r'LASSO_EXPORT(.*(?:\s|\*))(\w+)\s*\((.*?)\)', line)
+ if m and not m.group(2).endswith('_get_type'):
+ return_type, function_name, args = m.groups()
return_type = return_type.strip()
f = Function()
if function_name[0] == '*':
return_type += '*'
function_name = function_name[1:]
if binding.functions_toskip.get(function_name) != 1:
+ if re.search('\<const\>', return_type):
+ f.return_owner = False
+ # clean the type
+ return_type = clean_type(return_type)
if return_type != 'void':
f.return_type = return_type
- if return_type.startswith('const'):
- f.return_owner = False
- if oftype:
- oftype_parse = re.match(r'OFTYPE\((.*)\)', oftype)
- if oftype_parse:
- f.return_type_qualifier = oftype_parse.group(1)
if function_name.endswith('_destroy'):
# skip the _destroy functions, they are just wrapper over
# g_object_unref
@@ -424,12 +466,14 @@ def parse_header(header_file):
f.name = function_name
f.args = []
for arg in [x.strip() for x in args.split(',')]:
+ arg = clean_type(arg)
if arg == 'void' or arg == '':
continue
- m = re.match(r'((const\s+)?\w+\*?)\s+(\*?\w+)', arg)
- # TODO: Add parsing of OFTYPE
+ m = re.match(r'(.*(?:\s|\*))(\w+)', arg)
+ type, name = m.groups()
+ type = clean_type(type)
if m:
- f.args.append(list(normalise_var(m.group(1), m.group(3))) + [{}])
+ f.args.append(list((type, name, {})))
else:
print >>sys.stderr, 'failed to process:', arg, 'in line:', line
f.apply_overrides()
diff --git a/bindings/java/lang.py b/bindings/java/lang.py
index c854ff85..21fb5bd5 100644
--- a/bindings/java/lang.py
+++ b/bindings/java/lang.py
@@ -24,7 +24,7 @@ import sys
import re
import textwrap
-import utils
+from utils import *
lasso_package_name = 'com.entrouvert.lasso'
lasso_java_path = 'com/entrouvert/lasso/'
@@ -39,15 +39,25 @@ def with_return_owner(d):
def generate_arg_list(self,args):
def arg_to_decl(arg):
type, name, option = arg
- return self.JNI_arg_type(type) + ' ' + utils.format_as_camelcase(name)
- return ', '.join([ arg_to_decl(x) for x in args ])
+ return self.JNI_arg_type(type) + ' ' + format_as_camelcase(name)
+ return ', '.join([ arg_to_decl(x) for x in args if not is_out(x)])
def generate_arg_list2(args):
def arg_to_decl(arg):
type, name, option = arg
- return utils.format_as_camelcase(name)
+ if is_out(arg):
+ return 'output'
+ return format_as_camelcase(name)
return ', '.join([ arg_to_decl(x) for x in args ])
+def generate_arg_list3(self,args):
+ def arg_to_decl(arg):
+ type, name, option = arg
+ if is_out(arg):
+ return 'Object[] output'
+ return self.JNI_arg_type(type) + ' ' + format_as_camelcase(name)
+ return ', '.join([ arg_to_decl(x) for x in args])
+
def convert_class_name(lasso_name):
return lasso_name[5:]
@@ -85,8 +95,8 @@ def error_to_exception(error_name):
super = 'Lasso'
else:
super, name = re.match('LASSO(_.*)_ERROR(_.*)', error_name).groups()
- super = utils.format_as_camelcase(super.lower())
- name = utils.format_as_camelcase(name.lower())
+ super = format_as_camelcase(super.lower())
+ name = format_as_camelcase(name.lower())
return (super+name+'Exception',super+'Exception')
def wrapper_decl(name, jnitype, fd):
@@ -274,17 +284,17 @@ protected static native void destroy(long cptr);
else:
jtype = self.JNI_return_type(m.return_type)
name = self.JNI_function_name(m)
- print >> fd, ' public static native %s %s(%s);' % (jtype,name, generate_arg_list(self,m.args))
+ print >> fd, ' public static native %s %s(%s);' % (jtype,name, generate_arg_list3(self,m.args))
def JNI_member_function_prefix(self,c,m):
klassname = c.name[5:]
- mname = utils.format_as_camelcase(m[1])
+ mname = format_as_camelcase(m[1])
return '%s_%s' % (klassname,mname)
def generate_JNI_member(self, c, fd):
for m in c.members:
prefix = self.JNI_member_function_prefix(c,m)
- mname = utils.format_as_camelcase(m[1])
+ mname = format_as_camelcase(m[1])
mtype = m[0]
jtype = self.JNI_member_type(m)
@@ -691,7 +701,7 @@ protected static native void destroy(long cptr);
continue
name, = re.match('LASSO_ERROR(.*)',orig).groups()
name = name.lower()
- name = utils.format_underscore_as_camelcase(name)
+ name = format_underscore_as_camelcase(name)
name = 'Lasso%sException' % name
self.generate_exception_class(name, 'LassoException', 0, orig)
self.generate_exception_switch_case(efd, name, orig)
@@ -726,7 +736,7 @@ protected static native void destroy(long cptr);
if m.rename:
return m.rename
else:
- name = utils.format_as_camelcase(m.name[6:])
+ name = format_as_camelcase(m.name[6:])
name = name[prefix:]
return name[0].lower() + name[1:]
for c in self.binding_data.structs:
@@ -776,7 +786,7 @@ protected static native void destroy(long cptr);
for m in c.members:
type, name, options = m
prefix = self.JNI_member_function_prefix(c,m)
- jname = utils.format_as_camelcase('_'+name)
+ jname = format_as_camelcase('_'+name)
jtype = self.JNI_member_type(m)
if type == 'GList*' or type == 'const GList*':
print >> fd, ' public void set%s(List list) {' % jname
@@ -859,8 +869,10 @@ protected static native void destroy(long cptr);
else:
print >> fd, ' /**\n'
print >> fd, ' *'
- for name, desc in doc.parameters:
- print >> fd, normalize(desc, ' * @param %s ' % utils.format_as_camelcase(name))
+ for p in doc.parameters:
+ name = p[0]
+ desc = p[1]
+ print >> fd, normalize(desc, ' * @param %s ' % format_as_camelcase(name))
if doc.return_value:
print >> fd, normalize(doc.return_value, ' * @return ')
if m.errors:
@@ -868,7 +880,22 @@ protected static native void destroy(long cptr);
err = error_to_exception(err)[0]
print >> fd, normalize(err,' * @throws ')
print >> fd, ' **/'
- if m.return_type == 'GList*' or m.return_type == 'const GList*':
+ outarg = None
+ for a in args:
+ if is_out(a):
+ # only one output arg supported
+ assert not outarg
+ outarg = a
+ if outarg:
+ assert is_int(make_arg(m.return_type), self.binding_data)
+ new_return_type = self.JNI_return_type(var_type(outarg))
+ print >> fd, ' public %s %s(%s) {' % (new_return_type, mname, generate_arg_list(self, args[1:]))
+ print >> fd, ' Object[] output = new Object[1];'
+ print >> fd, ' LassoException.throwError(LassoJNI.%s(this, %s));' % (jni_name, generate_arg_list2(args[1:]))
+ print >> fd, ' return (%s)output[0];' % new_return_type
+ print >> fd, ' }'
+
+ elif m.return_type == 'GList*' or m.return_type == 'const GList*':
print >> fd, ' public List %s(%s) {' % (mname,generate_arg_list(self,args[1:]))
arglist = generate_arg_list2(args[1:])
if arglist:
diff --git a/bindings/overrides.xml b/bindings/overrides.xml
index eedcec3e..d85657de 100644
--- a/bindings/overrides.xml
+++ b/bindings/overrides.xml
@@ -37,14 +37,14 @@
<!-- LassoWsfProfile -->
<func name="lasso_wsf_profile_get_identity" return_owner="false" />
<func name="lasso_wsf_profile_get_session" return_owner="false" />
- <func name="lasso_wsf_profile_get_remote_provider" skip="true"/>
- <func name="lasso_data_service_get_answer" skip="true"/>
- <func name="lasso_data_service_get_query_item" skip="true"/>
- <func name="lasso_data_service_add_modification" skip="true"/>
+ <func name="lasso_wsf_profile_get_remote_provider" skip="java"/>
+ <func name="lasso_data_service_get_answer" skip="java"/>
+ <func name="lasso_data_service_get_query_item" skip="java"/>
+ <func name="lasso_data_service_add_modification" skip="java"/>
+ <func name="lasso_data_service_get_answers" skip="java"/>
+ <func name="lasso_data_service_get_answers_by_select" skip="java"/>
+ <func name="lasso_data_service_get_answers_by_item_id" skip="java"/>
<func name="lasso_saml2_encrypted_element_decrypt" skip="true"/>
- <func name="lasso_data_service_get_answers" skip="true"/>
- <func name="lasso_data_service_get_answers_by_select" skip="true"/>
- <func name="lasso_data_service_get_answers_by_item_id" skip="true"/>
<!-- LassoIdentity -->
<func name="lasso_identity_get_federation" return_owner="false" />
<func name="lasso_identity_get_svc_md_ids" return_type_qualifier="char*"/>
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)
diff --git a/bindings/python/lang.py b/bindings/python/lang.py
index 57d67273..ff06b746 100644
--- a/bindings/python/lang.py
+++ b/bindings/python/lang.py
@@ -23,7 +23,25 @@ import os
import sys
import re
import textwrap
-import utils
+from utils import *
+
+def defval_to_python_value(defval):
+ if defval is None:
+ return 'None'
+ if defval.startswith('b:'):
+ if defval[2:].lower() == 'true':
+ return 'True'
+ if defval[2:].lower() == 'false':
+ return 'False'
+ if defval.startswith('c:'):
+ return defval[8:]
+ raise Exception('Could not convert %s to python value' % defval)
+
+def get_python_arg_decl(arg):
+ if is_optional(arg):
+ return '%s = %s' % (arg_name(arg), defval_to_python_value(arg_default(arg)))
+ else:
+ return arg_name(arg)
class Binding:
def __init__(self, binding_data):
@@ -31,14 +49,7 @@ class Binding:
self.src_dir = os.path.dirname(__file__)
def is_pygobject(self, t):
- if t:
- m = re.match(r'(?:const\s*)?(.*)',t) # Remove const modifier
- t = m.group(1)
- return t not in ['guchar*', 'guchar*', 'char*', 'gchar*',
- 'GList*', 'GHashTable*',
- 'int', 'gint', 'gboolean', 'xmlNode*'] + self.binding_data.enums
- else:
- return False
+ return t and is_object((t,'',{})) and t not in self.binding_data.enums
def generate(self):
fd = open('lasso.py', 'w')
@@ -254,17 +265,14 @@ if WSF_SUPPORT:
methods = clss.methods[:]
# constructor(s)
- method_prefix = 'lasso_' + utils.format_as_underscored(klassname) + '_'
+ method_prefix = 'lasso_' + format_as_underscored(klassname) + '_'
for m in self.binding_data.functions:
if m.name == method_prefix + 'new':
c_args = []
py_args = []
for o in m.args:
arg_type, arg_name, arg_options = o
- if arg_options.get('optional'):
- py_args.append('%s = None' % arg_name)
- else:
- py_args.append(arg_name)
+ py_args.append(get_python_arg_decl(o))
if self.is_pygobject(arg_type):
c_args.append('%s._cptr' % arg_name)
@@ -284,15 +292,12 @@ if WSF_SUPPORT:
for m in self.binding_data.functions:
if m.name.startswith(method_prefix + 'new_'):
- constructor_name = utils.format_as_camelcase(m.name[len(method_prefix):])
+ constructor_name = format_as_camelcase(m.name[len(method_prefix):])
c_args = []
py_args = []
for o in m.args:
arg_type, arg_name, arg_options = o
- if arg_options.get('optional'):
- py_args.append('%s = None' % arg_name)
- else:
- py_args.append(arg_name)
+ py_args.append(get_python_arg_decl(o))
if self.is_pygobject(arg_type):
c_args.append('%s._cptr' % arg_name)
@@ -311,7 +316,7 @@ if WSF_SUPPORT:
# create properties for members
for m in clss.members:
- mname = utils.format_as_camelcase(m[1])
+ mname = format_as_camelcase(m[1])
options = m[2]
print >> fd, ' def get_%s(self):' % mname
if self.is_pygobject(m[0]):
@@ -372,7 +377,7 @@ if WSF_SUPPORT:
else:
mname = m.name
mname = re.match(r'lasso_.*_get_(\w+)', mname).group(1)
- mname = utils.format_underscore_as_camelcase(mname)
+ mname = format_underscore_as_camelcase(mname)
print >> fd, ' def get_%s(self):' % mname
function_name = m.name[6:]
@@ -413,25 +418,21 @@ if WSF_SUPPORT:
function_name = m.name[6:]
py_args = []
c_args = []
+ outarg = None
for o in m.args[1:]:
arg_type, arg_name, arg_options = o
- if arg_options.get('optional'):
- if arg_options.get('default'):
- defval = arg_options.get('default')
- if defval.startswith('c:'): # constant
- py_args.append('%s = %s' % (arg_name, defval[8:]))
- elif defval.startswith('b:'): # boolean
- py_args.append('%s = %s' % (arg_name, defval[2:]))
- else:
- print >> sys.stderr, "E: don't know what to do with %s" % defval
- sys.exit(1)
- else:
- py_args.append('%s = None' % arg_name)
+ if is_out(o):
+ assert not outarg
+ outarg = o
+ outvar = '_%s_out' % arg_name
else:
- py_args.append(arg_name)
- if arg_type in ('char*', 'const char*', 'guchar*', 'const guchar*', 'gchar*', 'const gchar*', 'xmlNode*') or \
+ py_args.append(get_python_arg_decl(o))
+
+ if is_out(o):
+ c_args.append(outvar)
+ elif arg_type in ('char*', 'const char*', 'guchar*', 'const guchar*', 'gchar*', 'const gchar*', 'xmlNode*') or \
arg_type in ['int', 'gint', 'gboolean', 'const gboolean'] or \
- arg_type in self.binding_data.enums:
+ arg_type in self.binding_data.enums or is_time_t_pointer(o):
c_args.append(arg_name)
else:
c_args.append('%s._cptr' % arg_name)
@@ -446,32 +447,39 @@ if WSF_SUPPORT:
c_args = ''
print >> fd, ' def %s(self%s):' % (
- utils.format_underscore_as_camelcase(mname), py_args)
+ format_underscore_as_camelcase(mname), py_args)
if m.docstring:
print >> fd, " '''"
print >> fd, self.format_docstring(m, mname, 8)
print >> fd, " '''"
- if m.return_type in (None, 'void'):
- print >> fd, ' _lasso.%s(self._cptr%s)' % (
- function_name, c_args)
- elif m.return_type in ('gint', 'int'):
+
+ if outarg:
+ print >> fd, " %s = list((None,))" % outvar
+ return_type = m.return_type
+ return_type_qualifier = m.return_type_qualifier
+ assert is_int(make_arg(return_type),self.binding_data) or not outarg
+ if return_type in ('gint', 'int'):
print >> fd, ' rc = _lasso.%s(self._cptr%s)' % (
function_name, c_args)
- print >> fd, ' if rc == 0:'
- print >> fd, ' return'
- print >> fd, ' raise Error.raise_on_rc(rc)'
- elif m.return_type == 'GList*' and self.is_pygobject(m.return_type_qualifier):
+ print >> fd, ' if rc != 0:'
+ print >> fd, ' raise Error.raise_on_rc(rc)'
+ elif return_type in (None, 'void'):
+ print >> fd, ' _lasso.%s(self._cptr%s)' % (
+ function_name, c_args)
+ elif return_type == 'GList*' and self.is_pygobject(return_type_qualifier):
print >> fd, ' value = _lasso.%s(self._cptr%s)' % (
function_name, c_args)
print >> fd, ' if value is not None:'
print >> fd, ' value = tuple([cptrToPy(x) for x in value])'
print >> fd, ' return value'
- elif self.is_pygobject(m.return_type):
+ elif self.is_pygobject(return_type):
print >> fd, ' return cptrToPy(_lasso.%s(self._cptr%s))' % (
function_name, c_args)
else:
print >> fd, ' return _lasso.%s(self._cptr%s)' % (
function_name, c_args)
+ if outarg:
+ print >> fd, ' return %s[0]' % outvar
print >> fd, ''
print >> fd, ''
@@ -573,10 +581,10 @@ if WSF_SUPPORT:
name = m.rename
if name.startswith('lasso_'):
name = name[6:]
- pname = utils.format_as_camelcase(name)
+ pname = format_as_camelcase(name)
else:
name = m.name[6:]
- pname = utils.format_as_camelcase(name)
+ pname = format_as_camelcase(name)
print >> fd, '%s = _lasso.%s' % (pname, name)
@@ -627,7 +635,7 @@ register_constants(PyObject *d)
def generate_member_wrapper(self, c, fd):
klassname = c.name
for m in c.members:
- mname = utils.format_as_camelcase(m[1])
+ mname = format_as_camelcase(m[1])
# getter
print >> fd, '''static PyObject*
%s_%s_get(G_GNUC_UNUSED PyObject *self, PyObject *args)
@@ -715,60 +723,62 @@ register_constants(PyObject *d)
print >> fd, ''
- def return_value(self, fd, vtype, options):
+ def return_value(self, fd, vtype, options, return_var_name = 'return_value', return_pyvar_name = 'return_pyvalue'):
if vtype == 'gboolean':
- print >> fd, ' if (return_value) {'
+ print >> fd, ' if (%s) {' % return_var_name
print >> fd, ' Py_INCREF(Py_True);'
- print >> fd, ' return_pyvalue = Py_True;'
+ print >> fd, ' %s = Py_True;' % return_pyvar_name
print >> fd, ' } else {'
print >> fd, ' Py_INCREF(Py_False);'
- print >> fd, ' return_pyvalue = Py_False;'
+ print >> fd, ' %s = Py_False;' % return_pyvar_name
print >> fd, ' }'
elif vtype in ['int', 'gint'] + self.binding_data.enums:
- print >> fd, ' return_pyvalue = PyInt_FromLong(return_value);'
+ print >> fd, ' %s = PyInt_FromLong(%s);' % (return_pyvar_name, return_var_name)
elif vtype in ('char*', 'guchar*', 'const guchar*', 'gchar*'):
- print >> fd, ' if (return_value) {'
- print >> fd, ' return_pyvalue = PyString_FromString(return_value);'
- print >> fd, ' g_free(return_value);'
+ print >> fd, ' if (%s) {' % return_var_name
+ print >> fd, ' %s = PyString_FromString(%s);' % (return_pyvar_name, return_var_name)
+ print >> fd, ' g_free(%s);' % return_var_name
print >> fd, ' } else {'
- print >> fd, ' return_pyvalue = noneRef();'
+ print >> fd, ' %s = noneRef();' % return_pyvar_name
print >> fd, ' }'
elif vtype in ('const char*', 'const gchar*'):
- print >> fd, ' if (return_value) {'
- print >> fd, ' return_pyvalue = PyString_FromString(return_value);'
+ print >> fd, ' if (%s) {' % return_var_name
+ print >> fd, ' %s = PyString_FromString(%s);' % (return_pyvar_name, return_var_name)
print >> fd, ' } else {'
- print >> fd, ' return_pyvalue = noneRef();'
+ print >> fd, ' %s = noneRef();' % return_pyvar_name
print >> fd, ' }'
elif vtype in ('const GList*', 'GList*',):
elem_type = options.get('elem_type')
- if elem_type == 'char*':
- print >> fd, ' return_pyvalue = get_list_of_strings(return_value);'
- elif elem_type == 'xmlNode*':
- print >> fd, ' return_pyvalue = get_list_of_xml_nodes(return_value);'
+ if not elem_type or self.is_pygobject(elem_type):
+ print >> fd, ' %s = get_list_of_pygobject(%s);' % (return_pyvar_name, return_var_name)
+ elif elem_type == 'char*':
+ print >> fd, ' %s = get_list_of_strings(%s);' % (return_pyvar_name, return_var_name)
+ elif elem_type.startswith('xmlNode'):
+ print >> fd, ' %s = get_list_of_xml_nodes(%s);' % (return_pyvar_name, return_var_name)
else:
- print >> fd, ' return_pyvalue = get_list_of_pygobject(return_value);'
+ raise Exception('Should not happen: %s %s ' % (repr(options), vtype))
elif vtype in ('GHashTable*',):
elem_type = options.get('elem_type')
if elem_type == 'char*':
- print >> fd, ' return_pyvalue = get_dict_from_hashtable_of_strings(return_value);'
+ print >> fd, ' %s = get_dict_from_hashtable_of_strings(%s);' % (return_pyvar_name, return_var_name)
else:
- print >> fd, ' return_pyvalue = get_dict_from_hashtable_of_objects(return_value);'
+ print >> fd, ' %s = get_dict_from_hashtable_of_objects(%s);' % (return_pyvar_name, return_var_name)
elif vtype == 'xmlNode*':
# convert xmlNode* to strings
- print >> fd, ' if (return_value) {'
- print >> fd, ' return_pyvalue = get_pystring_from_xml_node(return_value);'
+ print >> fd, ' if (%s) {' % return_var_name
+ print >> fd, ' %s = get_pystring_from_xml_node(%s);' % (return_pyvar_name, return_var_name)
print >> fd, ' } else {'
- print >> fd, ' return_pyvalue = noneRef();'
+ print >> fd, ' %s = noneRef();' % return_pyvar_name
print >> fd, ' }'
else:
# return a PyGObjectPtr (wrapper around GObject)
print >> fd, '''\
- if (return_value) {
- return_pyvalue = PyGObjectPtr_New(G_OBJECT(return_value));
+ if (%s) {
+ %s = PyGObjectPtr_New(G_OBJECT(%s));
} else {
- return_pyvalue = noneRef();
+ %s = noneRef();
}
-'''
+''' % (return_var_name, return_pyvar_name, return_var_name, return_pyvar_name)
def generate_function_wrapper(self, m, fd):
if m.rename:
@@ -785,6 +795,9 @@ register_constants(PyObject *d)
parse_tuple_args = []
for arg in m.args:
arg_type, arg_name, arg_options = arg
+ arg_def = None
+ python_cvt_def = None
+ defval = None
if arg_type in ('char*', 'const char*', 'gchar*', 'const gchar*'):
arg_type = arg_type.replace('const ', '')
if arg_options.get('optional'):
@@ -794,7 +807,7 @@ register_constants(PyObject *d)
else:
parse_tuple_format.append('s')
parse_tuple_args.append('&%s' % arg_name)
- print >> fd, ' %s %s = NULL;' % (arg[0], arg[1])
+ arg_def = ' %s %s = NULL;' % (arg[0], arg[1])
elif arg_type in ['int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums:
if arg_options.get('optional'):
if not '|' in parse_tuple_format:
@@ -807,23 +820,34 @@ register_constants(PyObject *d)
defval = defval[2:].upper()
else:
defval = defval[2:]
- print >> fd, ' %s %s = %s;' % (arg[0], arg[1], defval)
+ arg_def = ' %s %s = %s;' % (arg[0], arg[1], defval)
else:
- print >> fd, ' %s %s;' % (arg[0], arg[1])
- elif arg_type in ('GList*', 'xmlNode*'):
+ arg_def = ' %s %s;' % (arg[0], arg[1])
+ elif is_xml_node(arg) or is_list(arg) or is_time_t_pointer(arg):
parse_tuple_format.append('O')
parse_tuple_args.append('&cvt_%s' % arg_name)
- print >> fd, ' %s %s = NULL;' % (arg[0], arg[1])
- print >> fd, ' PyObject *cvt_%s = NULL;' % arg_name
+ arg_def = ' %s %s = NULL;' % (arg[0], arg[1])
+ python_cvt_def = ' PyObject *cvt_%s = NULL;' % arg_name
else:
parse_tuple_format.append('O')
parse_tuple_args.append('&cvt_%s' % arg_name)
- print >> fd, ' %s %s = NULL;' % (arg[0], arg[1])
- print >> fd, ' PyGObjectPtr *cvt_%s = NULL;' % arg_name
+ arg_def = ' %s %s = NULL;' % (arg[0], arg[1])
+ python_cvt_def = ' PyGObjectPtr *cvt_%s = NULL;' % arg_name
+ if is_out(arg):
+ arg_def = ' %s %s = NULL;' % (var_type(arg), arg[1])
+ parse_tuple_format.pop()
+ parse_tuple_format.append('O')
+ parse_tuple_args.pop()
+ parse_tuple_args.append('&cvt_%s_out' % arg_name)
+ python_cvt_def = ' PyObject *cvt_%s_out = NULL;' % arg_name
+ print >> fd, ' PyObject *out_pyvalue = NULL;'
+ print >> fd, arg_def
+ if python_cvt_def:
+ print >> fd, python_cvt_def
if m.return_type:
print >> fd, ' %s return_value;' % m.return_type
- print >> fd, ' PyObject* return_pyvalue;'
+ print >> fd, ' PyObject* return_pyvalue = NULL;'
print >> fd, ''
parse_tuple_args = ', '.join(parse_tuple_args)
@@ -834,7 +858,9 @@ register_constants(PyObject *d)
''.join(parse_tuple_format), parse_tuple_args)
for f, arg in zip(parse_tuple_format, m.args):
- if arg[0] == 'GList*':
+ if is_out(arg):
+ continue
+ if is_list(arg):
qualifier = arg[2].get('elem_type')
if qualifier == 'char*':
print >> fd, ' set_list_of_strings(&%s, cvt_%s);' % (arg[1], arg[1])
@@ -844,8 +870,10 @@ register_constants(PyObject *d)
print >> fd, ' set_list_of_pygobject(&%s, cvt_%s);' % (arg[1], arg[1])
else:
print >> sys.stderr, 'E: unqualified GList argument in', name
- elif arg[0] == 'xmlNode*':
+ elif is_xml_node(arg):
print >> fd, ' %s = get_xml_node_from_pystring(cvt_%s);' % (arg[1], arg[1])
+ elif is_time_t_pointer(arg):
+ print >> fd, ' %s = get_time_t(cvt_%s);' % (arg[1], arg[1])
elif f == 'O':
print >> fd, ' %s = (%s)cvt_%s->obj;' % (arg[1], arg[0], arg[1])
@@ -853,10 +881,15 @@ register_constants(PyObject *d)
print >> fd, ' return_value =',
if 'new' in m.name:
print >> fd, '(%s)' % m.return_type,
- print >> fd, '%s(%s);' % (m.name, ', '.join([x[1] for x in m.args]))
+ else:
+ print >> fd, ' ',
+ print >> fd, '%s(%s);' % (m.name, ', '.join([ref_name(x) for x in m.args]))
for f, arg in zip(parse_tuple_format, m.args):
- if arg[0] == 'GList*':
+ if is_out(arg):
+ self.return_value(fd, var_type(arg), {'elem_type': element_type(arg)}, return_var_name = arg[1], return_pyvar_name = 'out_pyvalue')
+ print >> fd, ' PyList_SetItem(cvt_%s_out, 0, out_pyvalue);' % arg[1]
+ elif arg[0] == 'GList*':
qualifier = arg[2].get('elem_type')
if qualifier == 'char*':
print >> fd, ' free_list(&%s, (GFunc)g_free);' % arg[1]
@@ -864,6 +897,8 @@ register_constants(PyObject *d)
print >> fd, ' free_list(&%s, (GFunc)xmlFreeNode);' % arg[1]
elif qualifier == 'LassoNode':
print >> fd, ' free_list(&%s, (GFunc)g_object_unref);' % arg[1]
+ elif is_time_t_pointer(arg):
+ print >> fd, ' if (%s) free(%s);' % (arg[1], arg[1])
if not m.return_type:
print >> fd, ' return noneRef();'
diff --git a/bindings/python/tests/Makefile.am b/bindings/python/tests/Makefile.am
index 64dfc090..c2130fb3 100644
--- a/bindings/python/tests/Makefile.am
+++ b/bindings/python/tests/Makefile.am
@@ -1,6 +1,8 @@
MAINTAINERCLEANFILES = Makefile.in
TESTS = #
+TESTS_ENVIRONMENT=TOP_SRCDIR=$(top_srcdir)
+
if PYTHON_ENABLED
TESTS += profiles_tests.py binding_tests.py
endif
diff --git a/bindings/python/tests/idwsf1_tests.py b/bindings/python/tests/idwsf1_tests.py
index a2f26b83..a37cd838 100755
--- a/bindings/python/tests/idwsf1_tests.py
+++ b/bindings/python/tests/idwsf1_tests.py
@@ -36,7 +36,7 @@ import lasso
try:
dataDir
except NameError:
- dataDir = '../../../tests/data'
+ dataDir = os.path.join(os.environ['TOP_SRCDIR'], 'tests', 'data')
wsp_metadata = os.path.join(dataDir, 'sp1-la/metadata.xml')
wsp_private_key = os.path.join(dataDir, 'sp1-la/private-key-raw.pem')
@@ -51,6 +51,12 @@ idp_public_key = os.path.join(dataDir, 'idp1-la/public-key.pem')
abstract_description = "Personal Profile Resource"
resource_id = "http://idp/user/resources/1"
+def __LINE__():
+ try:
+ raise Exception
+ except:
+ return sys.exc_info()[2].tb_frame.f_back.f_lineno
+
class IdWsf1TestCase(unittest.TestCase):
def get_wsp_server(self):
server = lasso.Server(wsp_metadata, wsp_private_key, None, None)
@@ -144,7 +150,7 @@ class IdWsf1TestCase(unittest.TestCase):
# Process query
idp_disco = lasso.Discovery(self.idp)
- idp_disco.processQueryMsg(wsc_disco.msgBody)
+ idp_disco.processRequestMsg(wsc_disco.msgBody)
idp_disco.setIdentityFromDump(idp_identity_dump)
idp_disco.getIdentity().addResourceOffering(self.get_resource_offering())
idp_disco.buildResponseMsg()
@@ -158,10 +164,12 @@ class DiscoveryQueryTestCase(IdWsf1TestCase):
'''Test a discovery query'''
service = self.get_pp_service()
# Check service attributes
- self.failUnless(service.resourceId is not None)
- self.failUnless(service.resourceId.content == resource_id)
- self.failUnless(service.providerId == self.wsc.providerIds[0])
- self.failUnless(service.abstractDescription == abstract_description)
+ resource_offering = service.getResourceOffering()
+ self.failUnless(resource_offering is not None)
+ self.failUnless(resource_offering.resourceId is not None)
+ self.failUnless(resource_offering.resourceId.content == resource_id)
+ self.failUnless(resource_offering.serviceInstance.providerId == self.wsc.providerIds[0])
+ self.failUnless(resource_offering.abstract == abstract_description)
class DiscoveryModifyTestCase(IdWsf1TestCase):
def test01(self):
@@ -177,16 +185,18 @@ class DiscoveryModifyTestCase(IdWsf1TestCase):
wsp_disco = lasso.Discovery(self.wsp)
wsp_disco.setIdentityFromDump(sp_identity_dump)
wsp_disco.setSessionFromDump(sp_session_dump)
- wsp_disco.initInsert(self.get_resource_offering())
+ resource_offering = self.get_resource_offering()
+ wsp_disco.initModify()
+ wsp_disco.addInsertEntry(resource_offering.serviceInstance, resource_offering.resourceId)
wsp_disco.buildRequestMsg()
# Process Modify
request_type = lasso.getRequestTypeFromSoapMsg(wsp_disco.msgBody)
self.failUnless(request_type == lasso.REQUEST_TYPE_DISCO_MODIFY)
idp_disco = lasso.Discovery(self.idp)
- idp_disco.processModifyMsg(wsp_disco.msgBody)
+ idp_disco.processRequestMsg(wsp_disco.msgBody)
idp_disco.setIdentityFromDump(idp_identity_dump)
- idp_disco.buildModifyResponseMsg()
+ idp_disco.buildResponseMsg()
offerings = idp_disco.identity.getOfferings()
self.failUnless('<disco:Status code="OK"/>' in idp_disco.msgBody)
self.failUnless('<disco:ModifyResponse newEntryIDs="%s"' % offerings[0].entryId in idp_disco.msgBody)
@@ -211,20 +221,21 @@ class DiscoveryRemoveTestCase(IdWsf1TestCase):
wsp_disco = lasso.Discovery(self.wsp)
wsp_disco.setIdentityFromDump(sp_identity_dump)
wsp_disco.setSessionFromDump(sp_session_dump)
- wsp_disco.initRemove('0')
+ wsp_disco.initModify()
+ wsp_disco.addRemoveEntry('0')
wsp_disco.buildRequestMsg()
# Process Modify
request_type = lasso.getRequestTypeFromSoapMsg(wsp_disco.msgBody)
self.failUnless(request_type == lasso.REQUEST_TYPE_DISCO_MODIFY)
idp_disco = lasso.Discovery(self.idp)
- idp_disco.processModifyMsg(wsp_disco.msgBody)
+ idp_disco.processRequestMsg(wsp_disco.msgBody)
idp_disco.setIdentityFromDump(idp_identity_dump)
offering = self.get_resource_offering()
idp_disco.getIdentity().addResourceOffering(offering)
self.failUnless('<disco:ServiceType>urn:liberty:id-sis-pp:2003-08</disco:ServiceType>' in
idp_disco.identity.dump())
- idp_disco.buildModifyResponseMsg()
+ idp_disco.buildResponseMsg()
self.failUnless('<disco:Status code="OK"/>' in idp_disco.msgBody)
self.failIf('<disco:ServiceType>urn:liberty:id-sis-pp:2003-08</disco:ServiceType>' in
idp_disco.identity.dump())
@@ -237,17 +248,19 @@ class DataServiceQueryTestCase(IdWsf1TestCase):
'''Test a data service query'''
wsc_service = self.get_pp_service()
wsc_service.initQuery('/pp:PP/pp:InformalName', 'name')
- wsc_service.buildRequestMsg()
+ wsc_service.buildSoapRequestMsg()
self.failUnless(lasso.getRequestTypeFromSoapMsg(wsc_service.msgBody)
== lasso.REQUEST_TYPE_DST_QUERY)
self.wsp = self.get_wsp_server()
wsp_service = lasso.DataService(self.wsp)
- wsp_service.processQueryMsg(wsc_service.msgBody)
+ wsp_service.processRequestMsg(wsc_service.msgBody)
+ self.failUnless(isinstance(wsp_service.request, lasso.DstQuery))
wsp_service.resourceData = '''
<PP xmlns="urn:liberty:id-sis-pp:2003-08">
<InformalName>Damien</InformalName>
</PP>'''
+ wsp_service.validateRequest()
wsp_service.buildResponseMsg()
wsc_service.processQueryResponseMsg(wsp_service.msgBody)
diff --git a/bindings/python/tests/idwsf2_tests.py b/bindings/python/tests/idwsf2_tests.py
index bbc66c5d..aff03816 100755
--- a/bindings/python/tests/idwsf2_tests.py
+++ b/bindings/python/tests/idwsf2_tests.py
@@ -40,7 +40,7 @@ import lasso
try:
dataDir
except NameError:
- dataDir = '../../../tests/data'
+ dataDir = os.path.join(os.environ['TOP_SRCDIR'], 'tests', 'data')
class IdWsf2TestCase(unittest.TestCase):
diff --git a/bindings/utils.py b/bindings/utils.py
index a2370b9c..e1248d92 100644
--- a/bindings/utils.py
+++ b/bindings/utils.py
@@ -22,6 +22,18 @@
import re
import string
+_mapping_convert_type_from_gobject_annotation = {
+ 'utf8': 'char8'
+}
+
+def convert_type_from_gobject_annotation(type):
+ return _mapping_convert_type_from_gobject_annotation.get(type, type)
+
+def clean_type(type):
+ type = type.strip()
+ type = re.sub('\s+', ' ', type)
+ return re.sub('\s*\*\s*', '*', type)
+
def format_as_camelcase(var):
'''Format an identifier name into CamelCase'''
if '_' in var:
@@ -100,3 +112,102 @@ def group(list):
+def _test_arg(arg, what):
+ return bool(arg[2].get(what))
+
+def is_optional(arg):
+ return _test_arg(arg, 'optional')
+
+def element_type(arg):
+ return arg[2].get('element-type')
+
+def key_type(arg):
+ return arg[2].get('key-type')
+
+def value_type(arg):
+ return arg[2].get('value-type')
+
+def is_out(arg):
+ return _test_arg(arg, 'out') or arg_type(arg).endswith('**')
+
+def is_glist(arg):
+ return re.match('GList\>', var_type(arg))
+
+def is_hashtable(arg):
+ return re.match('GHashTable\>', var_type(arg))
+
+def var_type(arg):
+ '''Return the type of variable to store content'''
+ if is_out(arg):
+ return arg[0][:-1]
+ else:
+ return arg[0]
+
+def unref_type(arg):
+ return (var_type(arg), arg[1], arg[2])
+
+def ref_name(arg):
+ if is_out(arg):
+ return '&%s' % arg[1]
+ else:
+ return arg[1]
+
+def arg_type(arg):
+ return arg[0]
+
+def arg_name(arg):
+ return arg[1]
+
+def unconstify(type):
+ return re.sub(r'\bconst\b\s*', '', type).strip()
+
+def make_arg(type):
+ return (type,'',{})
+
+def arg_default(arg):
+ return arg[2].get('default')
+
+def remove_modifiers(type):
+ type = re.sub(r'\s*\bunsigned\b\s*', ' ', type).strip()
+ type = re.sub(r'\s*\bconst\b\s*', ' ', type).strip()
+ type = re.sub(r'\s*\bsigned\b\s*', ' ', type).strip()
+ type = re.sub(r'\s*\bvolatile\b\s*', ' ', type).strip()
+ return clean_type(type)
+
+def is_const(arg):
+ return bool(re.search(r'\bconst\b', arg_type(arg)))
+
+def is_cstring(arg):
+ return unconstify(arg_type(arg)) in ('char*','gchar*','guchar*')
+
+def is_xml_node(arg):
+ return unconstify(arg_type(arg)).startswith('xmlNode')
+
+def is_boolean(arg):
+ return arg_type(arg) in ('gboolean','bool')
+
+def is_pointer(arg):
+ return arg_type(arg).endswith('*')
+
+def is_list(arg):
+ return unconstify(arg_type(arg)).startswith('GList')
+
+def is_int(arg, binding_data):
+ return arg_type(arg) in [ 'int', 'gint', 'long', 'glong'] + binding_data.enums
+
+def is_time_t_pointer(arg):
+ return re.match(r'\btime_t*', unconstify(arg_type(arg)))
+
+def is_transfer_full(arg):
+ transfer = arg[2].get('transfer')
+ if transfer:
+ return transfer == 'full'
+ else:
+ return is_out(arg) or is_object(arg)
+
+_not_objects = ( 'GHashTable', 'GList', 'GType' )
+
+def is_object(arg):
+
+ t = unconstify(arg_type(arg))
+ return t[0] in string.uppercase and not [ x for x in _not_objects if x in t ]