[vala] D-Bus: Fix error handling in static clients
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] D-Bus: Fix error handling in static clients
- Date: Mon, 14 Sep 2009 21:44:57 +0000 (UTC)
commit a33789a1007a0eaa6ce1cf562784c11ad0ca343d
Author: Didier 'Ptitjes <ptitjes free fr>
Date: Wed May 6 02:06:20 2009 +0200
D-Bus: Fix error handling in static clients
Fixes bug 581101.
Signed-off-by: Didier 'Ptitjes <ptitjes free fr>
codegen/valadbusclientmodule.vala | 123 ++++++++++++++++++++++++++++++++++++-
tests/dbus/arrays.test | 4 +-
tests/dbus/async.test | 4 +-
tests/dbus/basic-types.test | 4 +-
4 files changed, 128 insertions(+), 7 deletions(-)
---
diff --git a/codegen/valadbusclientmodule.vala b/codegen/valadbusclientmodule.vala
index c5f25f4..bf89555 100644
--- a/codegen/valadbusclientmodule.vala
+++ b/codegen/valadbusclientmodule.vala
@@ -45,6 +45,15 @@ internal class Vala.DBusClientModule : DBusModule {
}
}
+ bool has_dbus_error (Gee.List<DataType> error_types) {
+ foreach (DataType error_type in error_types) {
+ if (((ErrorType) error_type).error_domain.get_full_name () == "DBus.Error") {
+ return true;
+ }
+ }
+ return false;
+ }
+
public override void generate_dynamic_method_wrapper (DynamicMethod method) {
var dynamic_method = (DynamicMethod) method;
@@ -1486,6 +1495,12 @@ internal class Vala.DBusClientModule : DBusModule {
}
block.add_statement (new CCodeIfStatement (new CCodeMemberAccess.pointer (new CCodeCastExpression (new CCodeIdentifier ("self"), iface.get_cname () + "DBusProxy*"), "disposed"), dispose_return_block));
+ cdecl = new CCodeDeclaration ("DBusError");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_dbus_error"));
+ block.add_statement (cdecl);
+
+ var dbus_error = new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_dbus_error"));
+
cdecl = new CCodeDeclaration ("DBusGConnection");
cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection"));
block.add_statement (cdecl);
@@ -1510,6 +1525,10 @@ internal class Vala.DBusClientModule : DBusModule {
gconnection.add_argument (new CCodeConstant ("NULL"));
block.add_statement (new CCodeExpressionStatement (gconnection));
+ var dbus_error_init = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_init"));
+ dbus_error_init.add_argument (dbus_error);
+ block.add_statement (new CCodeExpressionStatement (dbus_error_init));
+
var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection"));
connection.add_argument (new CCodeIdentifier ("_connection"));
@@ -1517,7 +1536,7 @@ internal class Vala.DBusClientModule : DBusModule {
ccall.add_argument (connection);
ccall.add_argument (new CCodeIdentifier ("_message"));
ccall.add_argument (new CCodeConstant ("-1"));
- ccall.add_argument (new CCodeConstant ("NULL"));
+ ccall.add_argument (dbus_error);
block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref"));
@@ -1528,6 +1547,42 @@ internal class Vala.DBusClientModule : DBusModule {
message_unref.add_argument (new CCodeIdentifier ("_message"));
block.add_statement (new CCodeExpressionStatement (message_unref));
+ var error_types = m.get_error_types ();
+ if (!has_dbus_error (error_types)) {
+ Report.error (m.source_reference, "D-Bus methods must throw DBus.Error");
+ } else {
+ var error_block = new CCodeBlock ();
+
+ cdecl = new CCodeDeclaration ("GQuark");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_edomain"));
+ error_block.add_statement (cdecl);
+
+ cdecl = new CCodeDeclaration ("gint");
+ cdecl.add_declarator (new CCodeVariableDeclarator ("_ecode"));
+ error_block.add_statement (cdecl);
+
+ generate_client_error_cases (error_block, error_types, new CCodeMemberAccess (new CCodeIdentifier ("_dbus_error"), "name"), new CCodeIdentifier ("_edomain"), new CCodeIdentifier ("_ecode"));
+
+ var g_set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error"));
+ g_set_error.add_argument (new CCodeIdentifier ("error"));
+ g_set_error.add_argument (new CCodeIdentifier ("_edomain"));
+ g_set_error.add_argument (new CCodeIdentifier ("_ecode"));
+ g_set_error.add_argument (new CCodeMemberAccess (new CCodeIdentifier ("_dbus_error"), "message"));
+ error_block.add_statement (new CCodeExpressionStatement (g_set_error));
+
+ var dbus_error_free = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_free"));
+ dbus_error_free.add_argument (dbus_error);
+ error_block.add_statement (new CCodeExpressionStatement (dbus_error_free));
+
+ if (!(m.return_type is VoidType)) {
+ error_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+ }
+
+ var dbus_error_is_set = new CCodeFunctionCall (new CCodeIdentifier ("dbus_error_is_set"));
+ dbus_error_is_set.add_argument (dbus_error);
+ block.add_statement (new CCodeIfStatement (dbus_error_is_set, error_block));
+ }
+
block.add_statement (postfragment);
var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref"));
@@ -1545,6 +1600,72 @@ internal class Vala.DBusClientModule : DBusModule {
return proxy_name;
}
+ void generate_client_error_cases (CCodeBlock error_block, Gee.List<DataType> error_types, CCodeExpression dbus_error_name, CCodeExpression result_edomain, CCodeExpression result_ecode) {
+ CCodeStatement if_else_if = null;
+ CCodeIfStatement last_statement = null;
+
+ foreach (DataType error_type in error_types) {
+ var edomain = ((ErrorType) error_type).error_domain;
+
+ var edomain_dbus_name = get_dbus_name (edomain);
+ if (edomain_dbus_name == null) {
+ Report.error (edomain.source_reference, "Errordomain must have a DBus.name annotation to be serialized over DBus");
+ }
+
+ var true_block = new CCodeBlock ();
+ true_block.suppress_newline = true;
+
+ string temp_name = "_tmp%d_".printf (next_temp_var_id++);
+
+ var cdecl = new CCodeDeclaration ("const char*");
+ cdecl.add_declarator (new CCodeVariableDeclarator (temp_name));
+ true_block.add_statement (cdecl);
+
+ true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (result_edomain, new CCodeIdentifier (edomain.get_upper_case_cname ()))));
+
+ true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier (temp_name), new CCodeBinaryExpression (CCodeBinaryOperator.PLUS, dbus_error_name, new CCodeConstant ("%ld".printf (edomain_dbus_name.length + 1))))));
+
+ CCodeStatement inner_if_else_if = null;
+ CCodeIfStatement inner_last_statement = null;
+ foreach (ErrorCode ecode in edomain.get_codes ()) {
+ var inner_true_block = new CCodeBlock ();
+ inner_true_block.suppress_newline = true;
+ inner_true_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (result_ecode, new CCodeIdentifier (ecode.get_cname ()))));
+
+ var ecode_dbus_name = get_dbus_name (ecode);
+ if (ecode_dbus_name == null) {
+ ecode_dbus_name = Symbol.lower_case_to_camel_case (ecode.name.down ());
+ }
+
+ var string_comparison = new CCodeFunctionCall (new CCodeIdentifier ("strcmp"));
+ string_comparison.add_argument (new CCodeIdentifier (temp_name));
+ string_comparison.add_argument (new CCodeConstant ("\"%s\"".printf (ecode_dbus_name)));
+ var stmt = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, string_comparison, new CCodeConstant ("0")), inner_true_block);
+
+ if (inner_last_statement != null) {
+ inner_last_statement.false_statement = stmt;
+ } else {
+ inner_if_else_if = stmt;
+ }
+ inner_last_statement = stmt;
+ }
+ true_block.add_statement (inner_if_else_if);
+
+ var string_comparison = new CCodeFunctionCall (new CCodeIdentifier ("strstr"));
+ string_comparison.add_argument (dbus_error_name);
+ string_comparison.add_argument (new CCodeConstant ("\"%s\"".printf (edomain_dbus_name)));
+ var stmt = new CCodeIfStatement (new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, string_comparison, dbus_error_name), true_block);
+
+ if (last_statement != null) {
+ last_statement.false_statement = stmt;
+ } else {
+ if_else_if = stmt;
+ }
+ last_statement = stmt;
+ }
+ error_block.add_statement (if_else_if);
+ }
+
string generate_async_dbus_proxy_method (Interface iface, Method m) {
string proxy_name = "%sdbus_proxy_%s_async".printf (iface.get_lower_case_cprefix (), m.name);
diff --git a/tests/dbus/arrays.test b/tests/dbus/arrays.test
index 4d6e9ec..4ee95ff 100644
--- a/tests/dbus/arrays.test
+++ b/tests/dbus/arrays.test
@@ -6,8 +6,8 @@ Program: client
interface Test : Object {
public abstract string[] test_property { owned get; set; }
- public abstract int[] test_int (int[] i, out int[] j);
- public abstract string[] test_string (string[] s, out string[] t);
+ public abstract int[] test_int (int[] i, out int[] j) throws DBus.Error;
+ public abstract string[] test_string (string[] s, out string[] t) throws DBus.Error;
}
void main () {
diff --git a/tests/dbus/async.test b/tests/dbus/async.test
index 74e5346..0393bb2 100644
--- a/tests/dbus/async.test
+++ b/tests/dbus/async.test
@@ -4,8 +4,8 @@ Program: client
[DBus (name = "org.example.Test")]
interface Test : Object {
- public abstract async int test_int (int i);
- public abstract async string test_string (string s);
+ public abstract async int test_int (int i) throws DBus.Error;
+ public abstract async string test_string (string s) throws DBus.Error;
}
MainLoop main_loop;
diff --git a/tests/dbus/basic-types.test b/tests/dbus/basic-types.test
index 5ae2746..289ca17 100644
--- a/tests/dbus/basic-types.test
+++ b/tests/dbus/basic-types.test
@@ -6,8 +6,8 @@ Program: client
interface Test : Object {
public abstract string test_property { owned get; set; }
- public abstract int test_int (int i, out int j);
- public abstract string test_string (string s, out string t);
+ public abstract int test_int (int i, out int j) throws DBus.Error;
+ public abstract string test_string (string s, out string t) throws DBus.Error;
}
void main () {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]