diff options
author | Marcin Kolny <marcin.kolny@gmail.com> | 2014-08-21 02:19:06 +0200 |
---|---|---|
committer | Marcin Kolny <marcin.kolny@gmail.com> | 2014-09-08 18:49:21 +0200 |
commit | e96ac12360a50a902647eb7e61e7ebe8fd1b89f6 (patch) | |
tree | 806b441594dca8fcca75f6f9d98044c018422da9 | |
parent | b671bb745680c8b98854dc748ae80849ccff06d5 (diff) | |
download | glibmm-e96ac12360a50a902647eb7e61e7ebe8fd1b89f6.tar.gz |
gmmproc: Added parameter exception_handler in _WRAP_VFUNC (bgo#735132)
This change allows developer to use custom exception handler, instead of
using Glib::exception_handlers_invoke() method. It might be useful, if
developer can't get access to a thread, where exception might appear, or
it is very difficult to register handler in this thread.
* tools/m4/signal.m4:
* tools/m4/vfunc.m4:
* tools/pm/Output.pm:
* tools/pm/WrapParser.pm: added additional parameter
to a _WRAP_VFUNC and _WRAP_SIGNAL, allowing write custom
exception handlers
-rw-r--r-- | tools/m4/signal.m4 | 58 | ||||
-rw-r--r-- | tools/m4/vfunc.m4 | 19 | ||||
-rw-r--r-- | tools/pm/Output.pm | 45 | ||||
-rw-r--r-- | tools/pm/WrapParser.pm | 36 |
4 files changed, 115 insertions, 43 deletions
diff --git a/tools/m4/signal.m4 b/tools/m4/signal.m4 index bb487ea9..d84838d9 100644 --- a/tools/m4/signal.m4 +++ b/tools/m4/signal.m4 @@ -13,7 +13,8 @@ dnl $7 = `<c_args_to_cpp>', dnl $8 = `custom_c_callback (boolean)', dnl $9 = `deprecated' (boolean), dnl $10 = `refdoc_comment', -dnl $11 = ifdef) +dnl $11 = ifdef, +dnl $12 = exceptionHandler) define(`_SIGNAL_PROXY',` ifelse(`$11',,,`#ifdef $11' @@ -34,10 +35,10 @@ ifelse(`$11',,,`#ifdef $11' ifelse(`$9',,,`_DEPRECATE_IFDEF_START ')dnl dnl -ifelse($2`'_NUM($3)`'$5`'_NUM($6)`'$8,`void0void00',`dnl +ifelse($2`'_NUM($3)`'$5`'_NUM($6)`'$8`'_NUM($12),`void0void000',`dnl dnl dnl Use predefined callback for SignalProxy0<void>, to reduce code size, -dnl if custom_c_callback is not specified. +dnl if custom_c_callback or exception_handler is not specified. static const Glib::SignalProxyInfo __CPPNAME__`'_signal_$4_info = { @@ -53,8 +54,9 @@ static $2 __CPPNAME__`'_signal_$4_callback`'(__CNAME__`'* self, _COMMA_SUFFIX($3 using namespace __NAMESPACE__; typedef sigc::slot< $5`'_COMMA_PREFIX($6) > SlotType; + __CPPNAME__* obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self)); // Do not try to call a signal on a disassociated wrapper. - if(Glib::ObjectBase::_get_current_wrapper((GObject*) self)) + if(obj) { #ifdef GLIBMM_EXCEPTIONS_ENABLED try @@ -70,7 +72,18 @@ ifelse(`$2',void,`dnl } catch(...) { - Glib::exception_handlers_invoke(); +ifelse($15, `', `dnl + Glib::exception_handlers_invoke`'(); +', `dnl + try + { + return _CONVERT($5, $2, `obj->$12`'()'); + } + catch(...) + { + Glib::exception_handlers_invoke`'(); + } +')dnl } #endif //GLIBMM_EXCEPTIONS_ENABLED } @@ -87,8 +100,9 @@ static $2 __CPPNAME__`'_signal_$4_notify_callback`'(__CNAME__`'* self, _COMMA_SU using namespace __NAMESPACE__; typedef sigc::slot< void`'_COMMA_PREFIX($6) > SlotType; + __CPPNAME__* obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self)); // Do not try to call a signal on a disassociated wrapper. - if(Glib::ObjectBase::_get_current_wrapper((GObject*) self)) + if(obj) { #ifdef GLIBMM_EXCEPTIONS_ENABLED try @@ -100,7 +114,18 @@ static $2 __CPPNAME__`'_signal_$4_notify_callback`'(__CNAME__`'* self, _COMMA_SU } catch(...) { - Glib::exception_handlers_invoke(); +ifelse($12, `', `dnl + Glib::exception_handlers_invoke`'(); +', `dnl + try + { + return _CONVERT($5, $2, `obj->$12`'()'); + } + catch(...) + { + Glib::exception_handlers_invoke`'(); + } +')dnl } #endif //GLIBMM_EXCEPTIONS_ENABLED } @@ -142,8 +167,8 @@ ifelse(`$11',,,`#endif // $11 _POP()') -dnl $1 $2 $3 $4 $5 -dnl _SIGNAL_PH(gname, crettype, cargs and names, ifdef, deprecated) +dnl $1 $2 $3 $4 $5 $6 +dnl _SIGNAL_PH(gname, crettype, cargs and names, ifdef, deprecated, exceptionHandler) dnl Create a callback and set it in our derived G*Class. dnl define(`_SIGNAL_PH',`dnl @@ -173,8 +198,8 @@ _POP()') dnl $1 $2 $3 $4 $5 $6 dnl _SIGNAL_PCC(cppname,gname,cpprettype,crettype,`<cargs and names>',`<cnames>', -dnl $7 $8 $9 $10 -dnl `<cpparg names>',firstarg,<ifdef>,deprecated) +dnl $7 $8 $9 $10 $11 +dnl `<cpparg names>',firstarg,<ifdef>,deprecated,exceptionHandler) dnl define(`_SIGNAL_PCC',`dnl _PUSH(SECTION_PCC_DEFAULT_SIGNAL_HANDLERS) @@ -218,7 +243,18 @@ ifelse($4,void,`dnl } catch(...) { +ifelse($15, `', `dnl Glib::exception_handlers_invoke`'(); +', `dnl + try + { + return _CONVERT($3, $4, `obj->$15`'()'); + } + catch(...) + { + Glib::exception_handlers_invoke`'(); + } +')dnl } #endif //GLIBMM_EXCEPTIONS_ENABLED } diff --git a/tools/m4/vfunc.m4 b/tools/m4/vfunc.m4 index 652aabc7..beac4c86 100644 --- a/tools/m4/vfunc.m4 +++ b/tools/m4/vfunc.m4 @@ -22,8 +22,8 @@ dnl $1 $2 $3 $4 dnl _VFUNC_PCC(cppname,gtkname,cpprettype,crettype, dnl $5 $6 $7 $8 $9 $10 $11 dnl `<cargs and names>',`<cnames>',`<cpparg names>',firstarg, refreturn_ctype, ifdef, errthrow, -dnl $12 $13 $14 -dnl slot_type, c_data_param_name, return_value) +dnl $12 $13 $14 $15 +dnl slot_type, c_data_param_name, return_value, exception_handler) dnl dnl Note: _get_current_wrapper_inline() could be used throughout for performance instead of _get_current_wrapper(), dnl and is_derived_() instead of is_derived_(), @@ -76,7 +76,22 @@ ifelse($9,refreturn_ctype,`dnl Assume Glib::unwrap_copy() is correct if refretur } catch(...) { +ifelse($15, `', `dnl Glib::exception_handlers_invoke`'(); +', `dnl + try + { +ifelse($9,refreturn_ctype,`dnl + return Glib::unwrap_copy`'(obj->$15`'()); +', `dnl + return _CONVERT($3, $4, `obj->$15`'()'); +')dnl + } + catch(...) + { + Glib::exception_handlers_invoke`'(); + } +')dnl } #endif //GLIBMM_EXCEPTIONS_ENABLED } diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm index d1d3b1e4..22af9ef8 100644 --- a/tools/pm/Output.pm +++ b/tools/pm/Output.pm @@ -209,8 +209,9 @@ sub output_wrap_vfunc_cc($$$$$$$$) convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num); my $returnValue = $$objCppfunc{return_value}; + my $exceptionHandler = $$objCppfunc{exception_handler}; - my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s)dnl\n", + my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s,%s)dnl\n", $$objCppfunc{name}, $cname, $$objCppfunc{rettype}, @@ -224,7 +225,8 @@ sub output_wrap_vfunc_cc($$$$$$$$) $errthrow, $$objCppfunc{slot_type}, $$objCppfunc{c_data_param_name}, - $returnValue); + $returnValue, + $exceptionHandler); $self->append($str); } @@ -234,10 +236,10 @@ sub output_wrap_vfunc_cc($$$$$$$$) # _SIGNAL_H(signame,rettype, `<cppargs>', ifdef) # _SIGNAL_PH(gtkname,crettype, cargs and names, ifdef, deprecated) # void output_wrap_default_signal_handler_h($filename, $line_num, $objCppfunc, -# $objCDefsFunc, $ifdef, $deprecated) -sub output_wrap_default_signal_handler_h($$$$$$$) +# $objCDefsFunc, $ifdef, $deprecated, $exceptionHandler) +sub output_wrap_default_signal_handler_h($$$$$$$$) { - my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef, $deprecated) = @_; + my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef, $deprecated, $exceptionHandler) = @_; # The default signal handler is a virtual function. # It's not hidden by deprecation, since that would break ABI. @@ -253,21 +255,23 @@ sub output_wrap_default_signal_handler_h($$$$$$$) #The default callback, which will call on_* or the base default callback. #Declares the callback in the private *Class class and sets it in the class_init function. #This is hidden by deprecation. - $str = sprintf("_SIGNAL_PH(%s,%s,\`%s\',%s,%s)dnl\n", + $str = sprintf("_SIGNAL_PH(%s,%s,\`%s\',%s,%s,%s)dnl\n", $$objCDefsFunc{name}, $$objCDefsFunc{rettype}, $objCDefsFunc->args_types_and_names(), $ifdef, - $deprecated + $deprecated, + $exceptionHandler ); $self->append($str); } -# _SIGNAL_CC(signame, gtkname, rettype, crettype,`<cppargs>',`<cargs>', const, refreturn, ifdef) -sub output_wrap_default_signal_handler_cc($$$$$$$$$) +# _SIGNAL_CC(signame, gtkname, rettype, crettype,`<cppargs>',`<cargs>', const, refreturn, ifdef, exceptionHandler) +sub output_wrap_default_signal_handler_cc($$$$$$$$$$$) { my ($self, $filename, $line_num, $objCppfunc, $objDefsSignal, $bImplement, - $bCustomCCallback, $bRefreturn, $ifdef, $deprecated) = @_; + $bCustomCCallback, $bRefreturn, $ifdef, $deprecated, $exceptionHandler) = @_; + my $cname = $$objDefsSignal{name}; # $cname = $1 if ($args[3] =~ /"(.*)"/); #TODO: What's this about? @@ -291,7 +295,8 @@ sub output_wrap_default_signal_handler_cc($$$$$$$$$) $conversions, $$objCppfunc{const}, $refreturn, - $ifdef); + $ifdef + ); $self->append($str); } @@ -313,7 +318,7 @@ sub output_wrap_default_signal_handler_cc($$$$$$$$$) convert_args_c_to_cpp($objDefsSignal, $objCppfunc, $line_num); #This is hidden by deprecation. - my $str = sprintf("_SIGNAL_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',%s,%s)dnl\n", + my $str = sprintf("_SIGNAL_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',%s,%s,%s)dnl\n", $$objCppfunc{name}, $cname, $$objCppfunc{rettype}, @@ -323,7 +328,8 @@ sub output_wrap_default_signal_handler_cc($$$$$$$$$) $conversions, ${$objDefsSignal->get_param_names()}[0], $ifdef, - $deprecated); + $deprecated, + $exceptionHandler); $self->append($str); } } @@ -572,15 +578,15 @@ sub output_wrap_create($$$) } } -# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs) +# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) # custom_signalproxy_name is "" when no type conversion is required - a normal templates SignalProxy will be used instead. -sub output_wrap_sig_decl($$$$$$$$$$) +sub output_wrap_sig_decl($$$$$$$$$$$) { - my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs) = @_; + my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) = @_; # _SIGNAL_PROXY(c_signal_name, c_return_type, `<c_arg_types_and_names>', # cpp_signal_name, cpp_return_type, `<cpp_arg_types>',`<c_args_to_cpp>', -# refdoc_comment) +# refdoc_comment, exceptionHandler) # Get the signal name with underscores only (to look up docs -- they are # stored that way). @@ -623,7 +629,7 @@ sub output_wrap_sig_decl($$$$$$$$$$) my $conversions = convert_args_c_to_cpp($objCSignal, $objCppfunc, $line_num); - my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',%s,\`%s\',%s)dnl\n", + my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',%s,\`%s\',%s,%s)dnl\n", $signal_name, $$objCSignal{rettype}, $objCSignal->args_types_and_names_without_object(), @@ -634,7 +640,8 @@ sub output_wrap_sig_decl($$$$$$$$$$) $bCustomCCallback, #When this is true, it will not write the *_callback implementation for you. $deprecated, $doxycomment, - $ifdef + $ifdef, + $exceptionHandler ); $self->append($str); diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm index 1ef5cbce..a52769c2 100644 --- a/tools/pm/WrapParser.pm +++ b/tools/pm/WrapParser.pm @@ -1198,6 +1198,7 @@ sub on_wrap_signal($$) my $ifdef; my $argDeprecated = ""; my $deprecation_docs = ""; + my $exceptionHandler = ""; while($#args >= 2) # If optional arguments are there. { @@ -1236,11 +1237,16 @@ sub on_wrap_signal($$) { $ifdef = $1; } + + elsif($argRef =~ /^exception_handler\s+(.*)/) #If exception_handler at the start. + { + $exceptionHandler = $1; + } } $self->output_wrap_signal($argCppDecl, $argCName, $$self{filename}, $$self{line_num}, $bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback, - $bRefreturn, $ifdef, $commentblock, $argDeprecated, $deprecation_docs); + $bRefreturn, $ifdef, $commentblock, $argDeprecated, $deprecation_docs, $exceptionHandler); } # void on_wrap_vfunc() @@ -1265,6 +1271,7 @@ sub on_wrap_vfunc($) my $refreturn = 0; my $refreturn_ctype = 0; my $returnValue = ""; + my $exceptionHandler = ""; my $custom_vfunc = 0; my $custom_vfunc_callback = 0; my $ifdef = ""; @@ -1293,6 +1300,12 @@ sub on_wrap_vfunc($) { $returnValue = $1; } + # If exception handler is not defined, then Glib::exception_handlers_invoke + # method will be used for exception handling. + elsif($argRef =~ /^exception_handler\s+(.*)/) + { + $exceptionHandler = $1; + } elsif($argRef eq "custom_vfunc") { $custom_vfunc = 1; @@ -1333,7 +1346,7 @@ sub on_wrap_vfunc($) $self->output_wrap_vfunc($argCppDecl, $argCName, $$self{filename}, $$self{line_num}, $refreturn, $refreturn_ctype, $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow, - $slot_name, $slot_callback, $no_slot_copy, $returnValue); + $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler); } sub on_wrap_enum($) @@ -1492,12 +1505,12 @@ sub output_wrap_check($$$$$$) # void output_wrap($CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler, # $bNoDefaultHandler, $bCustomCCallback, $bRefreturn, $ifdef, -# $commentblock, $deprecated, $deprecation_docs) -sub output_wrap_signal($$$$$$$$$$$) +# $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) +sub output_wrap_signal($$$$$$$$$$$$) { my ($self, $CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback, $bRefreturn, $ifdef, - $commentblock, $deprecated, $deprecation_docs) = @_; + $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) = @_; #Some checks: return if ($self->output_wrap_check($CppDecl, $signal_name, @@ -1531,30 +1544,30 @@ sub output_wrap_signal($$$$$$$$$$$) $objOutputter->output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppSignal, $signal_name, $bCustomCCallback, $ifdef, $commentblock, - $deprecated, $deprecation_docs); + $deprecated, $deprecation_docs, $exceptionHandler); if($bNoDefaultHandler eq 0) { $objOutputter->output_wrap_default_signal_handler_h($filename, $line_num, - $objCppSignal, $objCSignal, $ifdef, $deprecated); + $objCppSignal, $objCSignal, $ifdef, $deprecated, $exceptionHandler); my $bImplement = 1; if($bCustomDefaultHandler) { $bImplement = 0; } $objOutputter->output_wrap_default_signal_handler_cc($filename, $line_num, $objCppSignal, $objCSignal, $bImplement, $bCustomCCallback, $bRefreturn, - $ifdef, $deprecated); + $ifdef, $deprecated, $exceptionHandler); } } # void output_wrap_vfunc($CppDecl, $vfunc_name, $filename, $line_num, # $refreturn, $refreturn_ctype, # $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow, -# $slot_name, $slot_callback, $no_slot_copy, $returnValue) -sub output_wrap_vfunc($$$$$$$$$$$$$) +# $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler) +sub output_wrap_vfunc($$$$$$$$$$$$$$) { my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype, $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow, - $slot_name, $slot_callback, $no_slot_copy, $returnValue) = @_; + $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler) = @_; #Some checks: return if ($self->output_wrap_check($CppDecl, $vfunc_name, $filename, $line_num, '_WRAP_VFUNC')); @@ -1586,6 +1599,7 @@ sub output_wrap_vfunc($$$$$$$$$$$$$) $$objCppVfunc{rettype_needs_ref} = $refreturn; $$objCppVfunc{return_value} = $returnValue; + $$objCppVfunc{exception_handler} = $exceptionHandler; $$objCppVfunc{name} .= "_vfunc"; #All vfuncs should have the "_vfunc" suffix, and a separate easily-named invoker method. # Store the slot information in the vfunc if specified. |