From: Thijs Vermeir Date: Tue, 17 Mar 2009 00:56:49 +0000 (+0100) Subject: GError: Check error domain before propagating X-Git-Tag: 0.6.0~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e941e64753083c39acd8362b54ba6921d92384f9;p=thirdparty%2Fvala.git GError: Check error domain before propagating Check the error domain of the method before propagating the method up and print a critical when the domain cannot be handled by the method. --- diff --git a/gobject/valagerrormodule.vala b/gobject/valagerrormodule.vala index d94feaaac..71770dfe7 100644 --- a/gobject/valagerrormodule.vala +++ b/gobject/valagerrormodule.vala @@ -17,7 +17,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Author: - * Jürg Billeter + * Jürg Billeter + * Thijs Vermeir */ using GLib; @@ -109,26 +110,48 @@ internal class Vala.GErrorModule : CCodeDelegateModule { return cerror_block; } - public override void add_simple_check (CodeNode node, CCodeFragment cfrag) { - current_method_inner_error = true; + CCodeStatement uncaught_error_statement (CCodeExpression inner_error) { + var cerror_block = new CCodeBlock (); + + // free local variables + var free_frag = new CCodeFragment (); + append_local_free (current_symbol, free_frag, false); + cerror_block.add_statement (free_frag); - var inner_error = get_variable_cexpression ("inner_error"); - var cprint_frag = new CCodeFragment (); var ccritical = new CCodeFunctionCall (new CCodeIdentifier ("g_critical")); ccritical.add_argument (new CCodeConstant ("\"file %s: line %d: uncaught error: %s\"")); ccritical.add_argument (new CCodeConstant ("__FILE__")); ccritical.add_argument (new CCodeConstant ("__LINE__")); ccritical.add_argument (new CCodeMemberAccess.pointer (inner_error, "message")); - cprint_frag.append (new CCodeExpressionStatement (ccritical)); + var cclear = new CCodeFunctionCall (new CCodeIdentifier ("g_clear_error")); cclear.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, inner_error)); + + var cprint_frag = new CCodeFragment (); + cprint_frag.append (new CCodeExpressionStatement (ccritical)); cprint_frag.append (new CCodeExpressionStatement (cclear)); - CCodeStatement cerror_handler; + // print critical message + cerror_block.add_statement (cprint_frag); + + if (current_return_type is VoidType) { + cerror_block.add_statement (new CCodeReturnStatement ()); + } else if (current_return_type != null) { + cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false))); + } + + return cerror_block; + } + + public override void add_simple_check (CodeNode node, CCodeFragment cfrag) { + current_method_inner_error = true; + + var inner_error = get_variable_cexpression ("inner_error"); + + CCodeStatement cerror_handler = null; if (current_try != null) { // surrounding try found - var cerror_block = new CCodeBlock (); // free local variables @@ -151,7 +174,6 @@ internal class Vala.GErrorModule : CCodeDelegateModule { cerror_block.add_statement (new CCodeIfStatement (ccond, cgoto_block)); } - } // go to finally clause if no catch clause matches @@ -160,29 +182,36 @@ internal class Vala.GErrorModule : CCodeDelegateModule { cerror_handler = cerror_block; } else if (current_method != null && current_method.get_error_types ().size > 0) { // current method can fail, propagate error - // TODO ensure one of the error domains matches - - cerror_handler = return_with_exception (inner_error); - } else { - // unhandled error - - var cerror_block = new CCodeBlock (); - - // free local variables - var free_frag = new CCodeFragment (); - append_local_free (current_symbol, free_frag, false); - cerror_block.add_statement (free_frag); + CCodeBinaryExpression ccond = null; - // print critical message - cerror_block.add_statement (cprint_frag); + foreach (DataType error_type in current_method.get_error_types ()) { + // If GLib.Error is allowed we propagate everything + if (error_type.equals (gerror_type)) { + ccond = null; + break; + } - if (current_return_type is VoidType) { - cerror_block.add_statement (new CCodeReturnStatement ()); - } else if (current_return_type != null) { - cerror_block.add_statement (new CCodeReturnStatement (default_value_for_type (current_return_type, false))); + // Check the allowed error domains to propagate + var domain_check = new CCodeBinaryExpression (CCodeBinaryOperator.EQUALITY, new CCodeMemberAccess.pointer + (inner_error, "domain"), new CCodeIdentifier (error_type.data_type.get_upper_case_cname ())); + if (ccond == null) { + ccond = domain_check; + } else { + ccond = new CCodeBinaryExpression (CCodeBinaryOperator.OR, ccond, domain_check); + } } - cerror_handler = cerror_block; + if (ccond == null) { + cerror_handler = return_with_exception (inner_error); + } else { + var cerror_block = new CCodeBlock (); + cerror_block.add_statement (new CCodeIfStatement (ccond, + return_with_exception (inner_error), + uncaught_error_statement (inner_error))); + cerror_handler = cerror_block; + } + } else { + cerror_handler = uncaught_error_statement (inner_error); } var ccond = new CCodeBinaryExpression (CCodeBinaryOperator.INEQUALITY, inner_error, new CCodeConstant ("NULL"));