[glibmm] gmmproc: Added parameter exception_handler in _WRAP_VFUNC (bgo#735132)



commit e96ac12360a50a902647eb7e61e7ebe8fd1b89f6
Author: Marcin Kolny <marcin kolny gmail com>
Date:   Thu Aug 21 02:19:06 2014 +0200

    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

 tools/m4/signal.m4     |   58 ++++++++++++++++++++++++++++++++++++++---------
 tools/m4/vfunc.m4      |   19 ++++++++++++++-
 tools/pm/Output.pm     |   45 +++++++++++++++++++++---------------
 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 bb487ea..d84838d 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 652aabc..beac4c8 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 d1d3b1e..22af9ef 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 1ef5cbc..a52769c 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.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]