summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-28 15:31:49 +0000
committerBenjamin Dauvergne <bdauvergne@entrouvert.com>2010-01-28 15:31:49 +0000
commit1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce (patch)
tree014771b1f67344ee8ad19807f541f73eb357f7ea
parenta1ae48d2ef48492faafd26464e64e2dccd0d8565 (diff)
downloadlasso-1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce.tar.gz
lasso-1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce.tar.xz
lasso-1dab7b59e5f36ef0a5cfed124a3a2f5d549d82ce.zip
Bindings: java, php5, python simplify logic in binding generator
* use utils.h macros to manipulate fields. * use utils.py function to filter variables, argument and return types. * finish support of hashtables of strings for php5 and python.
-rw-r--r--bindings/java/lang.py18
-rw-r--r--bindings/php5/php_code.py103
-rw-r--r--bindings/php5/wrapper_source.py268
-rw-r--r--bindings/php5/wrapper_source_top.c64
-rw-r--r--bindings/python/lang.py205
-rwxr-xr-xbindings/python/tests/idwsf2_tests.py80
-rw-r--r--bindings/python/wrapper_top.c68
7 files changed, 439 insertions, 367 deletions
diff --git a/bindings/java/lang.py b/bindings/java/lang.py
index 8c60e7bc..fc0fdd5b 100644
--- a/bindings/java/lang.py
+++ b/bindings/java/lang.py
@@ -416,12 +416,12 @@ protected static native void destroy(long cptr);
return 'get_list_of_xml_nodes(env, %s, &%s)' % (right, left)
else:
return 'get_list_of_objects(env, %s, &%s)' % (right, left)
- elif type in ('GHashTable*',):
+ elif is_hashtable(type):
element_type = options.get('element-type')
- if element_type == 'char*':
- return 'get_hash_of_strings(env, %s, &%s)' % (right, left)
- else:
+ if is_object(element_type):
return 'get_hash_of_objects(env, %s, &%s)' % (right, left)
+ else:
+ return 'get_hash_of_strings(env, %s, &%s)' % (right, left)
elif type == 'xmlNode*':
return 'xml_node_to_jstring(env, %s, &%s)' % (right, left)
else:
@@ -627,16 +627,20 @@ protected static native void destroy(long cptr);
print >> fd, ' add_to_list_of_objects(env, &gobj->%s,value);' % m[1]
print >> fd, '}'
# remove
- if element_type not in ('xmlNode*',):
+ if is_xml_node(element_type):
+ print >>sys.stderr, 'W: remove for list of xml node not supported: %s' % (m,)
+ else:
print >> fd,'/* Remover for %s %s.%s */' % (mtype,klassname,m[1])
wrapper_decl("%s_remove" % prefix, 'void', fd)
print >> fd, ', jobject jobj, %s value)\n {' % jni_elem_type(element_type)
print >> fd, ' %s *gobj;' % klassname
print >> fd, ' jobject_to_gobject(env, jobj, (GObject**)&gobj);'
- if element_type in ('char*','gchar*'):
+ if is_cstring(element_type):
print >> fd, ' remove_from_list_of_strings(env, &gobj->%s,value);' % m[1]
- else:
+ elif is_object(element_type):
print >> fd, ' remove_from_list_of_objects(env, &gobj->%s,value);' % m[1]
+ else:
+ raise Exception('remove_from_list unsupported for %s' % (m,))
print >> fd, '}'
# add/remove/get_by_name
if mtype in ('GHashTable*',):
diff --git a/bindings/php5/php_code.py b/bindings/php5/php_code.py
index 3530acf8..1e3fdcad 100644
--- a/bindings/php5/php_code.py
+++ b/bindings/php5/php_code.py
@@ -177,62 +177,59 @@ function lassoRegisterIdWsf2DstService($prefix, $href) {
elif m.name == method_prefix + 'new_full':
pass
- def generate_getters_and_setters(self, klass):
-
- # FIXME: handle objects and GLists
-
- for m in klass.members:
- mtype = m[0]
- mname = format_as_camelcase(m[1])
- options = m[2]
-
- # Getters
- print >> self.fd, ' /**'
- print >> self.fd, ' * @return %s' % self.get_docstring_return_type(mtype)
- print >> self.fd, ' */'
- print >> self.fd, ' protected function get_%s() {' % mname
- if self.is_object(mtype):
- print >> self.fd, ' return cptrToPhp(%s_%s_get($this->_cptr));' % (
- klass.name, mname)
- elif mtype in ('GList*', 'GHashTable*'):
- print >> self.fd, ' $array = %s_%s_get($this->_cptr);' % (klass.name, mname)
- if self.is_object(options.get('element-type')):
- print >> self.fd, ' $obj_array = array();'
- if mtype == 'GList*':
- print >> self.fd, ' foreach ($array as $item) {'
- print >> self.fd, ' $obj_array[] = cptrToPhp($item);'
- else:
- print >> self.fd, ' foreach ($array as $key => $item) {'
- print >> self.fd, ' $obj_array[$key] = cptrToPhp($item);'
- print >> self.fd, ' }'
- print >> self.fd, ' $array = $obj_array;'
- print >> self.fd, ' return $array;'
- else:
- print >> self.fd, ' return %s_%s_get($this->_cptr);' % (klass.name, mname)
- print >> self.fd, ' }'
- # Setters
- print >> self.fd, ' protected function set_%s($value) {' % mname
- if self.is_object(mtype):
- print >> self.fd, ' %s_%s_set($this->_cptr, $value->_cptr);' % (klass.name, mname)
- elif mtype in ('GList*', 'GHashTable*') and self.is_object(options.get('element-type')):
- print >> self.fd, ' $array = array();'
- # FIXME: setting an array to NULL should really set it to NULL and not to an empty array
- print >> self.fd, ' if (!is_null($value)) {'
- if mtype == 'GList*':
- print >> self.fd, ' foreach ($value as $item) {'
- print >> self.fd, ' $array[] = $item->_cptr;'
- else:
- print >> self.fd, ' foreach ($value as $key => $item) {'
- print >> self.fd, ' $array[$key] = $item->_cptr;'
- print >> self.fd, ' }'
+ def generate_getter(self, c, m):
+ d = { 'type': arg_type(m), 'name': format_as_camelcase(arg_name(m)),
+ 'docstring': self.get_docstring_return_type(arg_type(m)), 'class': c.name }
+
+ print >> self.fd, ''' /**'
+ * @return %(docstring)s
+ */
+ protected function get_%(name)s() {''' % d
+ print >> self.fd, ' $t = %(class)s_%(name)s_get($this->_cptr);' % d
+ if is_object(m):
+ print >> self.fd, ' $t = cptrToPhp($t);'
+ elif (is_glist(m) or is_hashtable(m)) and is_object(element_type(m)):
+ print >> self.fd, ' foreach ($t as $key => $item) {'
+ print >> self.fd, ' $t[$key] = cptrToPhp($item);'
print >> self.fd, ' }'
- print >> self.fd, ' %s_%s_set($this->_cptr, $array);' % (klass.name, mname)
- else:
- print >> self.fd, ' %s_%s_set($this->_cptr, $value);' % (klass.name, mname)
- print >> self.fd, ' }'
- print >> self.fd, ''
+ elif is_hashtable(m) or (is_glist(m) and (is_cstring(element_type(m)) \
+ or is_xml_node(element_type(m)))) or is_int(m, self.binding_data) \
+ or is_boolean(m) or is_cstring(m) or is_xml_node(m):
+ pass
+ else:
+ raise Exception('Cannot generate a Php getter %s.%s' % (c,m))
+ print >> self.fd, ' return $t;'
+ print >>self.fd, ' }'
+
+ def generate_setter(self, c, m):
+ d = { 'type': arg_type(m), 'name': format_as_camelcase(arg_name(m)),
+ 'docstring': self.get_docstring_return_type(arg_type(m)), 'class': c.name }
+ print >> self.fd, ' protected function set_%(name)s($value) {' % d
+ if is_object(m):
+ print >> self.fd, ' $value = $value->_cptr;'
+ elif (is_glist(m) or is_hashtable(m)) and is_object(element_type(m)):
+ print >> self.fd, ' $array = array();'
+ print >> self.fd, ' if (!is_null($value)) {'
+ print >> self.fd, ' foreach ($value as $key => $item) {'
+ print >> self.fd, ' $array[$key] = $item->_cptr;'
+ print >> self.fd, ' }'
+ print >> self.fd, ' }'
+ print >> self.fd, ' $value = $array;'
+ elif is_hashtable(m) or (is_glist(m) and (is_cstring(element_type(m)) \
+ or is_xml_node(element_type(m)))) or is_int(m, self.binding_data) \
+ or is_boolean(m) or is_cstring(m) or is_xml_node(m):
+ pass
+ else:
+ raise Exception('Cannot generate a Php setter %s.%s' % (c,m))
+ print >> self.fd, ' %(class)s_%(name)s_set($this->_cptr, $value);' % d
+ print >> self.fd, ' }'
+ print >> self.fd, ''
+ def generate_getters_and_setters(self, klass):
+ for m in klass.members:
+ self.generate_getter(klass, m)
+ self.generate_setter(klass, m)
def generate_methods(self, klass):
methods = klass.methods[:]
diff --git a/bindings/php5/wrapper_source.py b/bindings/php5/wrapper_source.py
index 21030dde..b9ccc48f 100644
--- a/bindings/php5/wrapper_source.py
+++ b/bindings/php5/wrapper_source.py
@@ -117,7 +117,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
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
+ print >> self.fd, ' ZVAL_STRING(%s, (char*)%s, 1);' % p
if free and not is_const(type):
print >> self.fd, 'g_free(%s)' % c_variable
elif arg_type(type) == 'xmlNode*':
@@ -131,7 +131,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
}
}
''' % q
- elif arg_type(type) == 'GList*':
+ elif is_glist(type):
elem_type = make_arg(element_type(type))
if not arg_type(elem_type):
raise Exception('unknown element-type: ' + repr(type))
@@ -146,7 +146,7 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
free_function = 'g_list_free(%(c_variable)s);'
else:
raise Exception('unknown element-type: ' + repr(type))
- print >> self.fd, ' %s(%s, &%s);' % (function, c_variable, zval_name)
+ print >> self.fd, ' %s((GList*)%s, &%s);' % (function, c_variable, zval_name)
if free:
print >> self.fd, ' ', free_function % q
elif is_object(type):
@@ -170,30 +170,24 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
- def return_value(self, vtype, options, free = False):
- if vtype is None:
+ def return_value(self, arg, free = False):
+ if arg is None:
return
- elif vtype == 'gboolean':
+
+ if is_boolean(arg):
print >> self.fd, ' RETVAL_BOOL(return_c_value);'
- elif vtype in ['int', 'gint', 'GType', ] + self.binding_data.enums:
+ elif is_int(arg, self.binding_data):
print >> self.fd, ' RETVAL_LONG(return_c_value);'
- elif vtype in ('char*', 'gchar*'):
- print >> self.fd, '''\
- if (return_c_value) {
- RETVAL_STRING(return_c_value, 1);
- } else {
- RETVAL_NULL();
- }'''
- if free:
- print >> self.fd, ' free(return_c_value);'
- elif vtype in ('const char*', 'const gchar*'):
+ elif is_cstring(arg):
print >> self.fd, '''\
if (return_c_value) {
RETVAL_STRING((char*)return_c_value, 1);
} else {
RETVAL_NULL();
}'''
- elif vtype == 'xmlNode*':
+ if free or is_transfer_full(arg):
+ print >> self.fd, ' free(return_c_value);'
+ elif is_xml_node(arg):
print >> self.fd, '''\
{
char* xmlString = get_string_from_xml_node(return_c_value);
@@ -204,42 +198,53 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
}
}
'''
- elif vtype == 'GList*':
- if options.get('element-type') == 'char*':
+ elif is_glist(arg):
+ el_type = element_type(arg)
+ if is_cstring(el_type):
print >> self.fd, '''\
- set_array_from_list_of_strings(return_c_value, &return_value);
+ set_array_from_list_of_strings((GList*)return_c_value, &return_value);
'''
- if free:
- print >> self.fd, ' free_glist(&return_c_value, (GFunc)free);'
- elif options.get('element-type') == 'xmlNode*':
+ if free or is_transfer_full(arg):
+ print >> self.fd, ' lasso_release_list_of_strings(return_c_value);'
+ elif is_xml_node(el_type):
print >> self.fd, '''\
- set_array_from_list_of_xmlnodes(return_c_value, &return_value);
+ set_array_from_list_of_xmlnodes((GList*)return_c_value, &return_value);
'''
- if free:
- print >> self.fd, ' free_glist(&return_c_value, (GFunc)efree);'
- else:
+ if free or is_transfer_full(arg):
+ print >> self.fd, ' lasso_release_list_of_xml_node(return_c_value);'
+ elif is_object(el_type):
print >> self.fd, '''\
- set_array_from_list_of_objects(return_c_value, &return_value);
+ set_array_from_list_of_objects((GList*)return_c_value, &return_value);
'''
- if free:
- print >> self.fd, ' free_glist(&return_c_value, NULL);'
- elif vtype == 'GHashTable*':
- if options.get('element-type') not in ('char*', 'xmlNode*'):
+ if free or is_transfer_full(arg):
+ print >> self.fd, ' lasso_release_list_of_gobjects(return_c_value);'
+ else:
+ raise Exception('cannot return value for %s' % (arg,))
+ elif is_hashtable(arg):
+ el_type = element_type(arg)
+ if is_object(el_type):
print >> self.fd, '''\
set_array_from_hashtable_of_objects(return_c_value, &return_value);
'''
- else:
+ else:
+ if not is_cstring(arg):
+ print >>sys.stderr, 'W: %s has no explicit string annotation' % (arg,)
+ print >> self.fd, '''\
+ set_array_from_hashtable_of_strings(return_c_value, &return_value);
+'''
+ elif is_object(arg):
print >> self.fd, '''\
if (return_c_value) {
+ PhpGObjectPtr *self;
self = PhpGObjectPtr_New(G_OBJECT(return_c_value));
ZEND_REGISTER_RESOURCE(return_value, self, le_lasso_server);
} else {
RETVAL_NULL();
}'''
if free:
- print >> self.fd, ' if (return_c_value) {'
- print >> self.fd, ' g_object_unref(return_c_value); // If constructor ref is off by one'
- print >> self.fd, ' }'
+ print >> self.fd, ' lasso_release_gobject(return_c_value);'
+ else:
+ raise Exception('cannot return value for %s' % (arg,))
def generate_function(self, m):
if m.name in ('lasso_init','lasso_shutdown'):
@@ -291,8 +296,8 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
if m.return_type:
print >> self.fd, ' %s return_c_value;' % m.return_type
- if m.return_type is not None and self.is_object(m.return_type):
- print >> self.fd, ' PhpGObjectPtr *self;'
+ if m.return_type is not None and self.is_object(m.return_arg):
+ print >> self.fd, ' G_GNUC_UNUSED PhpGObjectPtr *self;'
print >> self.fd, ''
parse_tuple_args = ', '.join(parse_tuple_args)
@@ -318,11 +323,13 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
print >> self.fd, ' ZEND_FETCH_RESOURCE(cvt_%s, PhpGObjectPtr *, &zval_%s, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server);' % (arg[1], arg[1])
print >> self.fd, ' %s = (%s)cvt_%s->obj;' % (arg[1], arg[0], arg[1])
elif f.startswith('a'):
- element_type = arg[2].get('element-type')
- if is_cstring(element_type):
+ el_type = element_type(arg)
+ if is_cstring(el_type):
print >> self.fd, ' %(name)s = get_list_from_array_of_strings(zval_%(name)s);' % {'name': arg[1]}
+ elif is_object(el_type):
+ print >> self.fd, ' %(name)s = get_list_from_array_of_objects(zval_%(name)s);' % {'name': arg[1]}
else:
- print >> sys.stderr, 'E: In %(function)s arg %(name)s is of type GList<%(elem)s>' % { 'function': m.name, 'name': arg[1], 'elem': element_type }
+ print >> sys.stderr, 'E: In %(function)s arg %(name)s is of type GList<%(elem)s>' % { 'function': m.name, 'name': arg[1], 'elem': el_type }
elif f == 'l':
pass
else:
@@ -348,43 +355,39 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
elif argtype == 'xmlNode*':
print >> self.fd, ' xmlFree(%s);' % argname
elif f.startswith('a'):
- element_type = arg[2].get('element-type')
- if element_type == 'char*':
+ el_type = element_type(arg)
+ if is_cstring(el_type):
print >> self.fd, ' if (%(name)s) {' % { 'name': arg[1] }
print >> self.fd, ' free_glist(&%(name)s,(GFunc)free);' % { 'name': arg[1] }
print >> self.fd, ' }'
- self.return_value(m.return_type, {}, m.return_owner)
+ try:
+ self.return_value(m.return_arg, is_transfer_full(m.return_arg))
+ except:
+ raise Exception('Cannot return value for function %s' % m)
print >> self.fd, '}'
print >> self.fd, ''
def generate_members(self, c):
- for m_type, m_name, m_options in c.members:
- self.generate_getter(c.name, m_type, m_name, m_options)
- self.generate_setter(c.name, m_type, m_name, m_options)
-
- def generate_getter(self, klassname, m_type, m_name, m_options):
- if m_type == 'GList*' and m_options.get('element-type') not in ('char*', 'xmlNode*') \
- and not self.is_object(m_options.get('element-type')):
- print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('element-type'))
- return
+ for m in c.members:
+ self.generate_getter(c, m)
+ self.generate_setter(c, m)
+
+ def generate_getter(self, c, m):
+ klassname = c.name
+ name = arg_name(m)
+ type = arg_type(m)
- function_name = '%s_%s_get' % (klassname, format_as_camelcase(m_name))
+ function_name = '%s_%s_get' % (klassname, format_as_camelcase(name))
print >> self.fd, '''PHP_FUNCTION(%s)
{''' % function_name
self.functions_list.append(function_name)
-
- if self.is_object(m_type):
- print >> self.fd, ' %s return_c_value = NULL;' % m_type
- else:
- print >> self.fd, ' %s return_c_value;' % m_type
+ print >> self.fd, ' %s return_c_value;' % type
print >> self.fd, ' %s* this;' % klassname
print >> self.fd, ' zval* zval_this;'
print >> self.fd, ' PhpGObjectPtr *cvt_this;'
- if self.is_object(m_type):
- print >> self.fd, ' PhpGObjectPtr *self;'
print >> self.fd, ''
print >> self.fd, '''\
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &zval_this) == FAILURE) {
@@ -394,27 +397,16 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
ZEND_FETCH_RESOURCE(cvt_this, PhpGObjectPtr *, &zval_this, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server);
this = (%s*)cvt_this->obj;
''' % (klassname)
-
- if self.is_object(m_type):
- print >> self.fd, ' if (this->%s != NULL) {' % m_name
- print >> self.fd, ' return_c_value = this->%s;' % m_name
- print >> self.fd, ' }'
- else:
- print >> self.fd, ' return_c_value = this->%s;' % m_name
-
- self.return_value(m_type, m_options)
-
+ print >> self.fd, ' return_c_value = (%s)this->%s;' % (type, name)
+ self.return_value(m)
print >> self.fd, '}'
print >> self.fd, ''
-
- def generate_setter(self, klassname, m_type, m_name, m_options):
- if m_type == 'GList*' and m_options.get('element-type') not in ('char*', 'xmlNode*') \
- and not self.is_object(m_options.get('element-type')):
- print >> sys.stderr, 'E: GList argument : %s of %s, with type : %s' % (m_name, klassname, m_options.get('element-type'))
- return
-
- function_name = '%s_%s_set' % (klassname, format_as_camelcase(m_name))
+ def generate_setter(self, c, m):
+ klassname = c.name
+ name = arg_name(m)
+ type = arg_type(m)
+ function_name = '%s_%s_set' % (klassname, format_as_camelcase(name))
print >> self.fd, '''PHP_FUNCTION(%s)
{''' % function_name
self.functions_list.append(function_name)
@@ -426,29 +418,28 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
# FIXME: This bloc should be factorised
parse_tuple_format = ''
parse_tuple_args = []
- arg_type = m_type
- arg_name = m_name
- arg_options = m_options
- if arg_type in ('char*', 'const char*', 'gchar*', 'const gchar*', 'xmlNode*'):
- arg_type = arg_type.replace('const ', '')
+ if is_cstring(m) or is_xml_node(m):
+ # arg_type = arg_type.replace('const ', '')
parse_tuple_format += 's'
- parse_tuple_args.append('&%s_str, &%s_len' % (arg_name, arg_name))
- print >> self.fd, ' %s %s_str = NULL;' % ('char*', arg_name)
- print >> self.fd, ' %s %s_len = 0;' % ('int', arg_name)
- elif arg_type in ['int', 'gint', 'GType', 'gboolean', 'const gboolean'] + self.binding_data.enums:
+ parse_tuple_args.append('&%s_str, &%s_len' % (name, name))
+ print >> self.fd, ' %s %s_str = NULL;' % ('char*', name)
+ print >> self.fd, ' %s %s_len = 0;' % ('int', name)
+ elif is_int(m, self.binding_data) or is_boolean(m):
parse_tuple_format += 'l'
- parse_tuple_args.append('&%s' % arg_name)
- print >> self.fd, ' %s %s;' % ('long', arg_name)
+ parse_tuple_args.append('&%s' % name)
+ print >> self.fd, ' %s %s;' % ('long', name)
# Must also handle lists of Objects
- elif arg_type in ('GList*', 'GHashTable*'):
+ elif is_glist(m) or is_hashtable(m):
parse_tuple_format += 'a'
- parse_tuple_args.append('&zval_%s' % arg_name)
- print >> self.fd, ' %s zval_%s;' % ('zval*', arg_name)
- else:
+ parse_tuple_args.append('&zval_%s' % name)
+ print >> self.fd, ' %s zval_%s;' % ('zval*', name)
+ elif is_object(m):
parse_tuple_format += 'r'
- parse_tuple_args.append('&zval_%s' % arg_name)
- print >> self.fd, ' %s zval_%s = NULL;' % ('zval*', arg_name)
- print >> self.fd, ' %s cvt_%s = NULL;' % ('PhpGObjectPtr*', arg_name)
+ parse_tuple_args.append('&zval_%s' % name)
+ print >> self.fd, ' %s zval_%s = NULL;' % ('zval*', name)
+ print >> self.fd, ' %s cvt_%s = NULL;' % ('PhpGObjectPtr*', name)
+ else:
+ raise Exception('Cannot make a setter for %s.%s' % (c,m))
if parse_tuple_args:
parse_tuple_arg = parse_tuple_args[0]
@@ -471,60 +462,37 @@ PHP_MSHUTDOWN_FUNCTION(lasso)
''' % klassname
# Set new value
- if parse_tuple_format == 'l':
- print >> self.fd, ' this->%s = %s;' % (m_name, m_name)
- elif parse_tuple_format == 's':
- print >> self.fd, ' if (this->%s) {' % m_name
- print >> self.fd, ' g_free(this->%s);' % m_name
- print >> self.fd, ' }'
- print >> self.fd, ' if (%s_str && strcmp(%s_str, "") != 0) {' % (m_name, m_name)
- if arg_type == 'xmlNode*':
- print >> self.fd, ' this->%s = get_xml_node_from_string(%s_str);' % (m_name, m_name)
+ d = { 'name': name, 'type': type }
+ if is_int(m, self.binding_data) or is_boolean(m):
+ print >> self.fd, ' this->%s = %s;' % (name, name)
+ elif is_cstring(m):
+ print >> self.fd, ' lasso_assign_string(this->%(name)s, %(name)s_str);' % d
+ elif is_xml_node(m):
+ print >> self.fd, ' lasso_assign_new_xml_node(this->%(name)s, get_xml_node_from_string(%(name)s_str));' % d
+ elif is_glist(m):
+ el_type = element_type(m)
+ if is_cstring(el_type):
+ print >> self.fd, ' lasso_assign_new_list_of_strings(this->%(name)s, get_list_from_array_of_strings(zval_%(name)s));' % d
+ elif is_xml_node(el_type):
+ print >> self.fd, ' lasso_assign_new_list_of_xml_node(this->%(name)s, get_list_from_array_of_xmlnodes(zval_%(name)s))' % d
+ elif is_object(el_type):
+ print >> self.fd, ' lasso_assign_new_list_of_gobjects(this->%(name)s, get_list_from_array_of_objects(zval_%(name)s));' % d
else:
- print >> self.fd, ' this->%s = g_strndup(%s_str, %s_len);' % (m_name, m_name, m_name)
- print >> self.fd, ' } else {'
- print >> self.fd, ' this->%s = NULL;' % m_name
- print >> self.fd, ' }'
- elif arg_type == 'GList*':
- if m_options.get('element-type') == 'char*':
- print >> self.fd, '''
- if (this->%(name)s) {
- /* free existing list */
- g_list_foreach(this->%(name)s, (GFunc)g_free, NULL);
- g_list_free(this->%(name)s);
- }
- this->%(name)s = get_list_from_array_of_strings(zval_%(name)s);
-''' % { 'name': m_name }
- elif m_options.get('element-type') == 'xmlNode*':
- print >> self.fd, '''
- if (this->%(name)s) {
- /* free existing list */
- g_list_foreach(this->%(name)s, (GFunc)xmlFreeNode, NULL);
- g_list_free(this->%(name)s);
- }
- this->%(name)s = get_list_from_array_of_xmlnodes(zval_%(name)s);
-''' % { 'name': m_name }
- else:
- print >> self.fd, '''
- free_glist(&this->%(name)s, (GFunc)g_object_unref);
- this->%(name)s = get_list_from_array_of_objects(zval_%(name)s);
-''' % { 'name': m_name }
- elif arg_type == 'GHashTable*' and arg_options.get('element-type') != 'char*':
+ raise Exception('Cannot create C setter for %s.%s' % (c,m))
+ elif is_hashtable(m):
+ el_type = element_type(m)
print >> self.fd, '''\
- {
- GHashTable *oldhash = this->%(name)s;
- this->%(name)s = get_hashtable_from_array_of_objects(zval_%(name)s);
- g_hash_table_destroy(oldhash);
- }
-''' % { 'name': m_name }
- elif parse_tuple_format == 'r':
- print >> self.fd, ' ZEND_FETCH_RESOURCE(cvt_%s, PhpGObjectPtr*, &zval_%s, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server);' % (m_name, m_name)
- print >> self.fd, '''
- g_object_ref(cvt_%(name)s->obj);
- if (this->%(name)s)
- g_object_unref(this->%(name)s);
- this->%(name)s = (%(type)s)cvt_%(name)s->obj;
-''' % { 'name': m_name, 'type': m_type }
+ {
+ GHashTable *oldhash = this->%(name)s;''' % d
+ if is_object(el_type):
+ print >>self.fd, ' this->%(name)s = get_hashtable_from_array_of_objects(zval_%(name)s);' % d
+ else:
+ print >>self.fd, ' this->%(name)s = get_hashtable_from_array_of_strings(zval_%(name)s);' % d
+ print >> self.fd, ' g_hash_table_destroy(oldhash);'
+ print >> self.fd, ' }'
+ elif is_object(m):
+ print >> self.fd, ' ZEND_FETCH_RESOURCE(cvt_%(name)s, PhpGObjectPtr*, &zval_%(name)s, -1, PHP_LASSO_SERVER_RES_NAME, le_lasso_server);' % d
+ print >> self.fd, ' lasso_assign_gobject(this->%(name)s, cvt_%(name)s->obj);' % d
print >> self.fd, '}'
print >> self.fd, ''
diff --git a/bindings/php5/wrapper_source_top.c b/bindings/php5/wrapper_source_top.c
index 8969408b..5567f499 100644
--- a/bindings/php5/wrapper_source_top.c
+++ b/bindings/php5/wrapper_source_top.c
@@ -192,10 +192,15 @@ get_list_from_array_of_xmlnodes(zval* array)
for (zend_hash_internal_pointer_reset_ex(hashtable, &pointer);
zend_hash_get_current_data_ex(hashtable, (void**) &data, &pointer) == SUCCESS;
zend_hash_move_forward_ex(hashtable, &pointer)) {
+ xmlNode *value;
+
temp = **data;
zval_copy_ctor(&temp);
convert_to_string(&temp);
- result = g_list_append(result, get_xml_node_from_string(Z_STRVAL(temp)));
+ value = get_xml_node_from_string(Z_STRVAL(temp));
+ if (value) {
+ lasso_list_add_new_xml_node(result, value);
+ }
zval_dtor(&temp);
}
return result;
@@ -281,16 +286,37 @@ get_hashtable_from_array_of_objects(zval *array)
zend_hash_move_forward_ex(hashtable, &pointer)) {
cvt_temp = (PhpGObjectPtr*) zend_fetch_resource(data TSRMLS_CC, -1, PHP_LASSO_SERVER_RES_NAME, NULL, 1, le_lasso_server);
if (zend_hash_get_current_key_ex(hashtable, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) {
- if (cvt_temp != NULL) {
- g_hash_table_insert(result, key, g_object_ref(cvt_temp->obj));
- } else {
- g_hash_table_insert(result, key, NULL);
- }
+ g_hash_table_insert(result, key, lasso_ref(cvt_temp->obj));
} else {
- if (cvt_temp != NULL) {
- g_hash_table_insert(result, (gpointer)index, g_object_ref(cvt_temp->obj));
+ /* FIXME: throw an exception */
+ }
+ }
+ return result;
+}
+
+static GHashTable*
+get_hashtable_from_array_of_strings(zval *array)
+{
+ HashTable *hashtable = NULL;
+ HashPosition pointer;
+ int size;
+ char *key = NULL;
+ unsigned int key_len;
+ unsigned long index;
+ zval **data = NULL;
+ GHashTable *result = NULL;
+
+ result = g_hash_table_new(g_str_hash, g_str_equal);
+ hashtable = Z_ARRVAL_P(array);
+ size = zend_hash_num_elements(hashtable);
+ for (zend_hash_internal_pointer_reset_ex(hashtable, &pointer);
+ zend_hash_get_current_data_ex(hashtable, (void**) &data, &pointer) == SUCCESS;
+ zend_hash_move_forward_ex(hashtable, &pointer)) {
+ if (Z_TYPE_PP(data) == IS_STRING) {
+ if (zend_hash_get_current_key_ex(hashtable, &key, &key_len, &index, 0, &pointer) == HASH_KEY_IS_STRING) {
+ g_hash_table_insert(result, g_strdup(key), g_strdup(Z_STRVAL_PP(data)));
} else {
- g_hash_table_insert(result, (gpointer)index, NULL);
+ /* FIXME: throw an exception */
}
}
}
@@ -318,3 +344,23 @@ set_array_from_hashtable_of_objects(GHashTable *hashtable, zval **array)
g_list_free(keys);
}
+static void
+set_array_from_hashtable_of_strings(GHashTable *hashtable, zval **array)
+{
+ GList *keys = NULL;
+ zval *zval_item = NULL;
+
+ array_init(*array);
+ for (keys = g_hash_table_get_keys(hashtable); keys; keys = g_list_next(keys)) {
+ char *item = g_hash_table_lookup(hashtable, keys->data);
+ if (item) {
+ MAKE_STD_ZVAL(zval_item);
+ ZVAL_STRING(zval_item, item, 1);
+ add_assoc_zval(*array, (char*)keys->data, zval_item);
+ } else {
+ add_assoc_null(*array, (char*)keys->data);
+ }
+ }
+ g_list_free(keys);
+}
+
diff --git a/bindings/python/lang.py b/bindings/python/lang.py
index 3c3e688f..b967e926 100644
--- a/bindings/python/lang.py
+++ b/bindings/python/lang.py
@@ -272,10 +272,10 @@ if WSF_SUPPORT:
c_args = []
py_args = []
for o in m.args:
- arg_type, arg_name, arg_options = o
+ type, arg_name, arg_options = o
py_args.append(get_python_arg_decl(o))
- if self.is_pygobject(arg_type):
+ if self.is_pygobject(type):
c_args.append('%s and %s._cptr' % (arg_name, arg_name))
else:
c_args.append(arg_name)
@@ -297,10 +297,10 @@ if WSF_SUPPORT:
c_args = []
py_args = []
for o in m.args:
- arg_type, arg_name, arg_options = o
+ type, arg_name, arg_options = o
py_args.append(get_python_arg_decl(o))
- if self.is_pygobject(arg_type):
+ if self.is_pygobject(type):
c_args.append('%s and %s._cptr' % (arg_name, arg_name))
else:
c_args.append(arg_name)
@@ -319,37 +319,52 @@ if WSF_SUPPORT:
for m in clss.members:
mname = format_as_camelcase(m[1])
options = m[2]
+ # getter
print >> fd, ' def get_%s(self):' % mname
- if self.is_pygobject(m[0]):
- print >> fd, ' t = _lasso.%s_%s_get(self._cptr)' % (
- klassname, mname)
+ print >> fd, ' t = _lasso.%s_%s_get(self._cptr)' % (
+ klassname, mname)
+ if is_object(m):
print >> fd, ' return cptrToPy(t)'
- elif m[0] == 'GList*' and options.get('element-type') not in ('char*', 'xmlNode*'):
- print >> fd, ' l = _lasso.%s_%s_get(self._cptr)' % (
- klassname, mname)
- print >> fd, ' if not l: return l'
- print >> fd, ' return tuple([cptrToPy(x) for x in l])'
- elif m[0] == 'GHashTable*':
- print >> fd, ' d = _lasso.%s_%s_get(self._cptr)' % (
- klassname, mname)
- print >> fd, ' if not d: return d'
- if options.get('element-type') != 'char*':
+ elif is_glist(m):
+ el_type = element_type(m)
+ if is_cstring(el_type):
+ pass
+ elif is_xml_node(el_type):
+ pass
+ elif is_object(element_type(m)):
+ print >> fd, ' if not t: return t'
+ print >> fd, ' t = tuple([cptrToPy(x) for x in t])'
+ else:
+ raise Exception('Unsupported python getter %s.%s' % (clss, m))
+ elif is_hashtable(m):
+ el_type = element_type(m)
+ print >> fd, ' if not t: return t'
+ if is_object(el_type):
print >> fd, ' d2 = {}'
- print >> fd, ' for k, v in d.items():'
+ print >> fd, ' for k, v in t.items():'
print >> fd, ' d2[k] = cptrToPy(v)'
- print >> fd, ' return frozendict(d2)'
+ print >> fd, ' t = frozendict(d2)'
else:
- print >> fd, ' return frozendict(d)'
+ print >> fd, ' t = frozendict(t)'
+ elif is_boolean(m) or is_int(m, self.binding_data) or is_xml_node(m) or is_cstring(m):
+ pass
else:
- print >> fd, ' return _lasso.%s_%s_get(self._cptr)' % (
- klassname, mname)
+ raise Exception('Unsupported python getter %s.%s' % (clss, m))
+ print >> fd, ' return t;'
+ # setter
print >> fd, ' def set_%s(self, value):' % mname
- if self.is_pygobject(m[0]):
+ if is_object(m):
print >> fd, ' if value is not None:'
print >> fd, ' value = value and value._cptr'
- elif m[0] == 'GList*' and options.get('element-type') not in ('char*', 'xmlNode*'):
- print >> fd, ' if value is not None:'
- print >> fd, ' value = tuple([x._cptr for x in value])'
+ elif is_glist(m):
+ el_type = element_type(m)
+ if is_cstring(el_type) or is_xml_node(el_type):
+ pass
+ elif is_object(el_type):
+ print >> fd, ' if value is not None:'
+ print >> fd, ' value = tuple([x._cptr for x in value])'
+ else:
+ raise Exception('Unsupported python setter %s.%s' % (clss, m))
print >> fd, ' _lasso.%s_%s_set(self._cptr, value)' % (
klassname, mname)
print >> fd, ' %s = property(get_%s, set_%s)' % (mname, mname, mname)
@@ -424,7 +439,7 @@ if WSF_SUPPORT:
c_args = []
outarg = None
for o in m.args[1:]:
- arg_type, arg_name, arg_options = o
+ type, arg_name, arg_options = o
if is_out(o):
assert not outarg
outarg = o
@@ -434,7 +449,7 @@ if WSF_SUPPORT:
if is_out(o):
c_args.append(outvar)
- elif not self.is_pygobject(arg_type):
+ elif not self.is_pygobject(type):
c_args.append(arg_name)
else:
c_args.append('%s and %s._cptr' % (arg_name, arg_name))
@@ -444,7 +459,7 @@ if WSF_SUPPORT:
if '=' in x:
opt = True
elif opt:
- print 'W: non-optional follow optional,', m
+ print >>sys.stderr, 'W: non-optional follow optional,', m
if py_args:
py_args = ', ' + ', '.join(py_args)
@@ -645,15 +660,16 @@ register_constants(PyObject *d)
def generate_member_wrapper(self, c, fd):
klassname = c.name
for m in c.members:
- mname = format_as_camelcase(m[1])
+ name = arg_name(m)
+ mname = format_as_camelcase(arg_name(m))
# getter
print >> fd, '''static PyObject*
%s_%s_get(G_GNUC_UNUSED PyObject *self, PyObject *args)
{''' % (klassname[5:], mname)
self.wrapper_list.append('%s_%s_get' % (klassname[5:], mname))
- ftype = m[0]
- if ftype in ('char*', 'const char*', 'guchar*', 'const guchar*', 'gchar*', 'const gchar*'):
+ ftype = arg_type(m)
+ if is_cstring(m):
ftype = 'char*'
print >> fd, ' %s return_value;' % ftype
print >> fd, ' PyObject* return_pyvalue;'
@@ -663,14 +679,17 @@ register_constants(PyObject *d)
print >> fd, ' if (! PyArg_ParseTuple(args, "O", &cvt_this)) return NULL;'
print >> fd, ' this = (%s*)cvt_this->obj;' % klassname
- if self.is_pygobject(ftype):
+ if is_cstring(m):
+ print >> fd, ' return_value = g_strdup(this->%s);' % arg_name(m)
+ elif is_object(m):
print >> fd, ' return_value = this->%s;' % m[1];
- elif ftype in ('char*',):
- print >> fd, ' return_value = g_strdup(this->%s);' % m[1]
else:
print >> fd, ' return_value = this->%s;' % m[1];
-
- self.return_value(fd, ftype, m[2])
+ try:
+ self.return_value(fd, m)
+ except:
+ print >>sys.stderr, 'W: cannot make an assignment for', c, m
+ raise
print >> fd, ' return return_pyvalue;'
print >> fd, '}'
@@ -684,57 +703,68 @@ register_constants(PyObject *d)
print >> fd, ' PyGObjectPtr* cvt_this;'
print >> fd, ' %s* this;' % klassname
- arg_type = m[0]
+ type = m[0]
# Determine type class
- if m[0] in ('char*', 'const char*', 'guchar*', 'const guchar*', 'gchar*', 'const gchar*'):
- arg_type = arg_type.replace('const ', '')
+ if is_cstring(m):
+ type = type.replace('const ', '')
parse_format = 'z'
parse_arg = '&value'
- print >> fd, ' %s value;' % arg_type
- elif arg_type in ['int', 'gint', 'gboolean', 'const gboolean'] + self.binding_data.enums:
+ print >> fd, ' %s value;' % type
+ elif is_int(m, self.binding_data):
parse_format = 'i'
parse_arg = '&value'
- print >> fd, ' %s value;' % arg_type
- elif arg_type in ('GList*','GHashTable*', 'xmlNode*'):
+ print >> fd, ' %s value;' % type
+ elif is_glist(m) or is_hashtable(m) or is_xml_node(m) or is_boolean(m):
parse_format = 'O'
print >> fd, ' PyObject *cvt_value;'
parse_arg = '&cvt_value'
- else:
+ elif is_object(m):
parse_format = 'O'
print >> fd, ' PyGObjectPtr *cvt_value;'
parse_arg = '&cvt_value'
+ else:
+ raise Exception('Unsupported field: %s' % (m,))
# Get GObject
print >> fd, ' if (! PyArg_ParseTuple(args, "O%s", &cvt_this, %s)) return NULL;' % (
parse_format, parse_arg)
print >> fd, ' this = (%s*)cvt_this->obj;' % klassname
# Change value
- if parse_format == 'i':
- print >> fd, ' this->%s = value;' % m[1]
- elif parse_format in ('s', 'z'):
- print >> fd, ' if (this->%s) g_free(this->%s);' % (m[1], m[1])
- print >> fd, ' this->%s = g_strdup(value);' % m[1]
- elif parse_format == 'O' and arg_type == 'GList*':
- element_type = m[2].get('element-type')
- if element_type == 'char*':
- print >> fd, ' set_list_of_strings(&this->%s, cvt_value);' % m[1]
- elif element_type == 'xmlNode*':
- print >> fd, ' set_list_of_xml_nodes(&this->%s, cvt_value);' % m[1]
+ if is_int(m, self.binding_data):
+ print >> fd, ' this->%s = value;' % name
+ elif is_boolean(m):
+ print >> fd, ' this->%s = PyInt_AS_LONG(cvt_value) ? TRUE : FALSE;' % name
+ elif is_cstring(m):
+ print >> fd, ' lasso_assign_string(this->%s, value);' % name
+ elif is_xml_node(m):
+ print >> fd, ' if (this->%s) xmlFreeNode(this->%s);' % (name, name)
+ print >> fd, ' this->%s = get_xml_node_from_pystring(cvt_value);' % name
+ elif is_glist(m):
+ el_type = element_type(m)
+ if is_cstring(el_type):
+ print >> fd, ' set_list_of_strings(&this->%s, cvt_value);' % name
+ elif is_xml_node(el_type):
+ print >> fd, ' set_list_of_xml_nodes(&this->%s, cvt_value);' % name
+ elif is_object(el_type):
+ print >> fd, ' set_list_of_pygobject(&this->%s, cvt_value);' % name
+ else:
+ raise Exception('Unsupported setter for %s' % (m,))
+ elif is_hashtable(m):
+ el_type = element_type(m)
+ if is_object(el_type):
+ print >> fd, ' set_hashtable_of_pygobject(this->%s, cvt_value);' % name
else:
- print >> fd, ' set_list_of_pygobject(&this->%s, cvt_value);' % m[1]
- elif parse_format == 'O' and arg_type == 'GHashTable*':
- print >> fd, ' set_hashtable_of_pygobject(this->%s, cvt_value);' % m[1]
- elif parse_format == 'O' and arg_type == 'xmlNode*':
- print >> fd, ' if (this->%s) xmlFreeNode(this->%s);' % (m[1], m[1])
- print >> fd, ' this->%s = get_xml_node_from_pystring(cvt_value);' % m[1]
- elif parse_format == 'O':
- print >> fd, ' set_object_field((GObject**)&this->%s, cvt_value);' % m[1]
+ print >> fd, ' set_hashtable_of_strings(this->%s, cvt_value);' % name
+ elif is_object(m):
+ print >> fd, ' set_object_field((GObject**)&this->%s, cvt_value);' % name
+ else:
+ raise Exception('Unsupported member %s.%s' % (klassname, m))
print >> fd, ' return noneRef();'
print >> fd, '}'
print >> fd, ''
- def return_value(self, fd, vtype, options, return_var_name = 'return_value', return_pyvar_name = 'return_pyvalue'):
- if vtype == 'gboolean':
+ def return_value(self, fd, arg, return_var_name = 'return_value', return_pyvar_name = 'return_pyvalue'):
+ if is_boolean(arg):
print >> fd, ' if (%s) {' % return_var_name
print >> fd, ' Py_INCREF(Py_True);'
print >> fd, ' %s = Py_True;' % return_pyvar_name
@@ -742,45 +772,45 @@ register_constants(PyObject *d)
print >> fd, ' Py_INCREF(Py_False);'
print >> fd, ' %s = Py_False;' % return_pyvar_name
print >> fd, ' }'
- elif vtype in ['int', 'gint'] + self.binding_data.enums:
+ elif is_int(arg, self.binding_data):
print >> fd, ' %s = PyInt_FromLong(%s);' % (return_pyvar_name, return_var_name)
- elif vtype in ('char*', 'guchar*', 'const guchar*', 'gchar*'):
+ elif is_cstring(arg) and is_transfer_full(arg):
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, ' %s = noneRef();' % return_pyvar_name
print >> fd, ' }'
- elif vtype in ('const char*', 'const gchar*'):
+ elif is_cstring(arg):
print >> fd, ' if (%s) {' % return_var_name
print >> fd, ' %s = PyString_FromString(%s);' % (return_pyvar_name, return_var_name)
print >> fd, ' } else {'
print >> fd, ' %s = noneRef();' % return_pyvar_name
print >> fd, ' }'
- elif vtype in ('const GList*', 'GList*',):
- element_type = options.get('element-type')
- if not element_type or self.is_pygobject(element_type):
+ elif is_glist(arg):
+ el_type = element_type(arg)
+ if is_object(el_type):
print >> fd, ' %s = get_list_of_pygobject(%s);' % (return_pyvar_name, return_var_name)
- elif element_type == 'char*':
+ elif is_cstring(el_type):
print >> fd, ' %s = get_list_of_strings(%s);' % (return_pyvar_name, return_var_name)
- elif element_type.startswith('xmlNode'):
+ elif is_xml_node(el_type):
print >> fd, ' %s = get_list_of_xml_nodes(%s);' % (return_pyvar_name, return_var_name)
else:
- raise Exception('Should not happen: %s %s ' % (repr(options), vtype))
- elif vtype in ('GHashTable*',):
- element_type = options.get('element-type')
- if element_type == 'char*':
- print >> fd, ' %s = get_dict_from_hashtable_of_strings(%s);' % (return_pyvar_name, return_var_name)
- else:
+ raise Exception('failed to make an assignment for %s' % (arg,))
+ elif is_hashtable(arg):
+ el_type = element_type(arg)
+ if is_object(el_type):
print >> fd, ' %s = get_dict_from_hashtable_of_objects(%s);' % (return_pyvar_name, return_var_name)
- elif vtype == 'xmlNode*':
+ else:
+ print >> fd, ' %s = get_dict_from_hashtable_of_strings(%s);' % (return_pyvar_name, return_var_name)
+ elif is_xml_node(arg):
# convert xmlNode* to strings
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, ' %s = noneRef();' % return_pyvar_name
print >> fd, ' }'
- else:
+ elif is_object(arg):
# return a PyGObjectPtr (wrapper around GObject)
print >> fd, '''\
if (%s) {
@@ -789,6 +819,8 @@ register_constants(PyObject *d)
%s = noneRef();
}
''' % (return_var_name, return_pyvar_name, return_var_name, return_pyvar_name)
+ else:
+ raise Exception('failed to make an assignment for %s' % (arg,))
def generate_function_wrapper(self, m, fd):
if m.rename:
@@ -908,7 +940,7 @@ register_constants(PyObject *d)
for f, arg in zip(parse_tuple_format, m.args):
if is_out(arg):
- self.return_value(fd, var_type(arg), {'element-type': element_type(arg)}, return_var_name = arg[1], return_pyvar_name = 'out_pyvalue')
+ self.return_value(fd, 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('element-type')
@@ -926,7 +958,12 @@ register_constants(PyObject *d)
else:
# Constructor so decrease refcount (it was incremented by PyGObjectPtr_New called
# in self.return_value
- self.return_value(fd, m.return_type, {'element-type': m.return_type_qualifier})
+ try:
+ self.return_value(fd, m.return_arg)
+ except:
+ print >>sys.stderr, 'W: cannot assign return value of', m
+ raise
+
if m.return_owner and self.is_pygobject(m.return_type):
print >> fd, ' if (return_value) g_object_unref(return_value);'
print >> fd, ' return return_pyvalue;'
diff --git a/bindings/python/tests/idwsf2_tests.py b/bindings/python/tests/idwsf2_tests.py
index fd98ef5e..39ce9fde 100755
--- a/bindings/python/tests/idwsf2_tests.py
+++ b/bindings/python/tests/idwsf2_tests.py
@@ -42,6 +42,7 @@ try:
except NameError:
dataDir = os.path.join(os.environ['TOP_SRCDIR'], 'tests', 'data')
+disco_soap_url = 'http://idp1/soapEndpoint'
class IdWsf2TestCase(unittest.TestCase):
def getWspServer(self):
@@ -82,29 +83,28 @@ class IdWsf2TestCase(unittest.TestCase):
return server
- def idpRegisterSelf(self, idp_server):
- disco = lasso.IdWsf2Discovery(idp_server)
- service_type = lasso.IDWSF2_DISCO_HREF
- abstract = 'Disco service'
- soapEndpoint = 'http://idp1/soapEndpoint'
- disco.metadataRegisterSelf(service_type, abstract, soapEndpoint)
-
- return idp_server
def metadataRegister(self, wsp, idp):
wsp_disco = lasso.IdWsf2Discovery(wsp)
abstract = 'Personal Profile service'
soapEndpoint = 'http://idp1/soapEndpoint'
- wsp_disco.initMetadataRegister(
- 'urn:liberty:id-sis-pp:2005-05', abstract, wsp.providerIds[0], soapEndpoint)
+ wsp_disco.initMetadataRegister()
+ wsp_disco.addSimpleServiceMetadata(
+ service_types = ['urn:liberty:id-sis-pp:2005-05'],
+ abstract = abstract, provider_id = wsp.providerIds[0],
+ address = soapEndpoint)
wsp_disco.buildRequestMsg()
idp_disco = lasso.IdWsf2Discovery(idp)
- idp_disco.processMetadataRegisterMsg(wsp_disco.msgBody)
+ idp_disco.processRequestMsg(wsp_disco.msgBody)
+ idp_disco.validateRequestMsg()
+ assert(len(idp_disco.metadatas) = 1)
+ assert(idp_disco.metadatas[0].svcMDID == idp_disco.response.SvcMDID[0])
idp_disco.buildResponseMsg()
-
wsp_disco.processMetadataRegisterResponseMsg(idp_disco.msgBody)
- return idp, wsp_disco.svcMDIDs[0]
+ assert(len(wsp_disco.metadatas) = 1)
+ assert(wsp_disco.metadatas[0].svcMDID == wsp_disco.response.SvcMDID[0])
+ return idp, wsp_disco.metadatas[0].svcMDID
def login(self, sp, idp, sp_identity_dump=None, sp_session_dump=None,
idp_identity_dump=None, idp_session_dump=None):
@@ -124,6 +124,7 @@ class IdWsf2TestCase(unittest.TestCase):
idp_login.processAuthnRequestMsg(query)
idp_login.validateRequestMsg(True, True)
idp_login.buildAssertion(lasso.SAML_AUTHENTICATION_METHOD_PASSWORD, None, None, None, None)
+ idp_login.idwsf2AddDiscoveryBootstrapEpr(url = disco_soap_url, abstract = 'Discovery Service', security_mech_id = lasso.SECURITY_MECH_NULL)
idp_login.buildArtifactMsg(lasso.HTTP_METHOD_ARTIFACT_GET)
artifact_message = idp_login.artifactMessage
@@ -150,55 +151,7 @@ class IdWsf2TestCase(unittest.TestCase):
if sp_login.isSessionDirty:
sp_session_dump = sp_login.session.dump()
- return sp_identity_dump, sp_session_dump, idp_identity_dump, idp_session_dump
-
-
-class IdpSelfRegistrationTestCase(IdWsf2TestCase):
- def test01(self):
- """Register IdP as Dicovery Service and get a random svcMDID"""
-
- disco = lasso.IdWsf2Discovery(self.getIdpServer())
-
- service_type = lasso.IDWSF2_DISCO_HREF
- abstract = 'Disco service'
- soapEndpoint = 'http://idp1/soapEndpoint'
-
- svcMDID = disco.metadataRegisterSelf(service_type, abstract, soapEndpoint)
- # In real use, store the server dump here
-
- self.failUnless(svcMDID, 'missing svcMDID')
-
- def test02(self):
- """Register IdP as Dicovery Service with a given svcMDID"""
-
- disco = lasso.IdWsf2Discovery(self.getIdpServer())
-
- service_type = lasso.IDWSF2_DISCO_HREF
- abstract = 'Disco service'
- soapEndpoint = 'http://idp1/soapEndpoint'
- mySvcMDID = 'RaNdOm StRiNg'
-
- svcMDID = disco.metadataRegisterSelf(service_type, abstract, soapEndpoint, mySvcMDID)
- # In real use, store the server dump here
-
- self.failUnless(svcMDID, 'missing svcMDID')
- self.failUnlessEqual(svcMDID, mySvcMDID, 'wrong svcMDID')
-
- def test03(self):
- """Register IdP as Dicovery Service with wrong parameters"""
-
- disco = lasso.IdWsf2Discovery(self.getIdpServer())
-
- service_type = ''
- abstract = ''
- soapEndpoint = ''
-
- try:
- svcMDID = disco.metadataRegisterSelf(service_type, abstract, soapEndpoint)
- except lasso.ParamBadTypeOrNullObjError:
- pass
- else:
- self.fail('metadataRegisterSelf should fail with a ParamBadTypeOrNullObjError')
+ return sp_identity_dump, sp_session_dump, idp_identity_dump, idp_session_dump, sp_login.idwsf2GetDiscoveryBootstrapEpr()
class MetadataRegisterTestCase(IdWsf2TestCase):
@@ -1786,13 +1739,12 @@ class DataServiceQueryTestCase(IdWsf2TestCase):
self.failUnless(email_strings[1] == email2)
-idpSelfRegistrationSuite = unittest.makeSuite(IdpSelfRegistrationTestCase, 'test')
metadataRegisterSuite = unittest.makeSuite(MetadataRegisterTestCase, 'test')
metadataAssociationAddSuite = unittest.makeSuite(MetadataAssociationAddTestCase, 'test')
discoveryQuerySuite = unittest.makeSuite(DiscoveryQueryTestCase, 'test')
dataServiceQuerySuite = unittest.makeSuite(DataServiceQueryTestCase, 'test')
-allTests = unittest.TestSuite((idpSelfRegistrationSuite, metadataRegisterSuite,
+allTests = unittest.TestSuite((metadataRegisterSuite,
metadataAssociationAddSuite, discoveryQuerySuite, dataServiceQuerySuite))
if __name__ == '__main__':
diff --git a/bindings/python/wrapper_top.c b/bindings/python/wrapper_top.c
index a24a2dba..24eb93ac 100644
--- a/bindings/python/wrapper_top.c
+++ b/bindings/python/wrapper_top.c
@@ -18,8 +18,10 @@ PyMODINIT_FUNC init_lasso(void);
G_GNUC_UNUSED static PyObject* get_pystring_from_xml_node(xmlNode *xmlnode);
G_GNUC_UNUSED static xmlNode* get_xml_node_from_pystring(PyObject *string);
G_GNUC_UNUSED static PyObject* get_dict_from_hashtable_of_objects(GHashTable *value);
+G_GNUC_UNUSED static PyObject* get_dict_from_hashtable_of_strings(GHashTable *value);
G_GNUC_UNUSED static PyObject* PyGObjectPtr_New(GObject *obj);
G_GNUC_UNUSED static void set_hashtable_of_pygobject(GHashTable *a_hash, PyObject *dict);
+G_GNUC_UNUSED static void set_hashtable_of_strings(GHashTable *a_hash, PyObject *dict);
G_GNUC_UNUSED static void set_list_of_strings(GList **a_list, PyObject *seq);
G_GNUC_UNUSED static void set_list_of_xml_nodes(GList **a_list, PyObject *seq);
G_GNUC_UNUSED static void set_list_of_pygobject(GList **a_list, PyObject *seq);
@@ -73,6 +75,34 @@ get_dict_from_hashtable_of_objects(GHashTable *value)
}
static PyObject*
+get_dict_from_hashtable_of_strings(GHashTable *value)
+{
+ GList *keys, *begin;
+ PyObject *dict,*proxy;
+ char *item_value;
+ PyObject *item;
+
+ dict = PyDict_New();
+
+ begin = keys = g_hash_table_get_keys(value);
+ for (; keys; keys = g_list_next(keys)) {
+ item_value = g_hash_table_lookup(value, keys->data);
+ if (item_value) {
+ item = PyString_FromString(item_value);
+ PyDict_SetItemString(dict, (char*)keys->data, item);
+ Py_DECREF(item);
+ } else {
+ PyErr_Warn(PyExc_RuntimeWarning, "hashtable contains a null value");
+ }
+ }
+ g_list_free(begin);
+
+ proxy = PyDictProxy_New(dict);
+ Py_DECREF(dict);
+ return proxy;
+}
+
+static PyObject*
get_pystring_from_xml_node(xmlNode *xmlnode)
{
xmlOutputBufferPtr buf;
@@ -165,6 +195,44 @@ failure:
}
}
+static void
+set_hashtable_of_strings(GHashTable *a_hash, PyObject *dict)
+{
+ PyObject *key, *value;
+ Py_ssize_t i;
+
+ if (! a_hash) {
+ PyErr_SetString(PyExc_TypeError, "hashtable does not exist");
+ return;
+ }
+ if (dict != Py_None && ! PyDict_Check(dict)) {
+ PyErr_SetString(PyExc_TypeError, "value should be a frozen dict");
+ return;
+ }
+ i = 0;
+ // Increase ref count of common object between old and new
+ // value of the hashtable
+ while (PyDict_Next(dict, &i, &key, &value)) {
+ if (! PyString_Check(key) || ! PyString_Check(value))
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "value should be a dict, "
+ "with string keys "
+ "and string values");
+ goto failure;
+ }
+ }
+ g_hash_table_remove_all (a_hash);
+ i = 0;
+ while (PyDict_Next(dict, &i, &key, &value)) {
+ char *ckey = PyString_AsString(key);
+ char *cvalue = PyString_AsString(value);
+ g_hash_table_insert (a_hash, g_strdup(ckey), g_strdup(cvalue));
+ }
+failure:
+ return;
+}
+
/** Set the GList* pointer, pointed by a_list, to a pointer on a new GList
* created by converting the python seq into a GList of char*.
*/