From: Didier 'Ptitjes Date: Wed, 6 May 2009 00:06:20 +0000 (+0200) Subject: D-Bus: Fix error handling in static clients X-Git-Tag: 0.7.6~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a33789a1007a0eaa6ce1cf562784c11ad0ca343d;p=thirdparty%2Fvala.git D-Bus: Fix error handling in static clients Fixes bug 581101. Signed-off-by: Didier 'Ptitjes --- diff --git a/codegen/valadbusclientmodule.vala b/codegen/valadbusclientmodule.vala index c5f25f4c2..bf89555cb 100644 --- a/codegen/valadbusclientmodule.vala +++ b/codegen/valadbusclientmodule.vala @@ -45,6 +45,15 @@ internal class Vala.DBusClientModule : DBusModule { } } + bool has_dbus_error (Gee.List 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 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 4d6e9ecfc..4ee95ff52 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 74e534685..0393bb2d3 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 5ae27468e..289ca1763 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 () {