[glibmm] gmmproc: _WRAP_VFUNC: Handle virtual functions that throw GErrors.



commit 629eb04ecce6d8b617292710bf4862169b693cca
Author: Josà Alburquerque <jaalburqu svn gnome org>
Date:   Thu Sep 6 00:01:23 2012 -0400

    gmmproc: _WRAP_VFUNC: Handle virtual functions that throw GErrors.
    
    	* tools/pm/WrapParser.pm (on_wrap_vfunc): Modified so that _WRAP_VFUNC
    	recognizes an optional "errthrow" parameter as is done in
    	_WRAP_METHOD.
    	(output_wrap_vfunc): Modified to tag the located virtual function
    	definition as one that will be wrapped by a C++ method that throws the
    	final C GError parameter.
    	* tools/pm/Output.pm (output_wrap_vfunc_cc): Modified to pass an
    	optional "errthrow" string to _VFUNC_CC and _VFUNC_PCC so that they
    	can include the proper code for the getting and throwing of the
    	GError.  Also modified to pass the "errthrow" string to the
    	convert_args_cpp_to_c() so that it process the C++ method as one
    	throwing a Glib::Error.
    	(convert_args_c_to_cpp): Modified to ignore the final GError if the
    	C function has been marked as one that will be wrapped by a C++ method
    	throwing the final C GError parameter.
    
    	* tools/m4/vfunc.m4 (_VFUNC_PCC): Modified to recognize a final
    	"errthrow" string parameter in which case code is inserted to declare
    	a local parameter in which to store the C GError and then throw
    	it as a Glib::Error if an error was received when the underlying C
    	function is called in the virtual function callback.
    	(_VFUNC_CC): Also modified to recognize a final "errthrow" string
    	parameter inserting code to store and then throw a possibly obtained
    	GError as a Glib::Error in the C++ virtual function when calling the
    	underlying C virtual function.

 ChangeLog              |   30 ++++++++++++++++++++++++++++++
 tools/m4/vfunc.m4      |   35 +++++++++++++++++++++++++++--------
 tools/pm/Output.pm     |   24 ++++++++++++++++++------
 tools/pm/WrapParser.pm |   14 ++++++++++----
 4 files changed, 85 insertions(+), 18 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 333b508..8ffc8b1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2012-09-05  Josà Alburquerque  <jaalburquerque gmail com>
+
+	gmmproc: _WRAP_VFUNC: Handle virtual functions that throw GErrors.
+
+	* tools/pm/WrapParser.pm (on_wrap_vfunc): Modified so that _WRAP_VFUNC
+	recognizes an optional "errthrow" parameter as is done in
+	_WRAP_METHOD.
+	(output_wrap_vfunc): Modified to tag the located virtual function
+	definition as one that will be wrapped by a C++ method that throws the
+	final C GError parameter.
+	* tools/pm/Output.pm (output_wrap_vfunc_cc): Modified to pass an
+	optional "errthrow" string to _VFUNC_CC and _VFUNC_PCC so that they
+	can include the proper code for the getting and throwing of the
+	GError.  Also modified to pass the "errthrow" string to the
+	convert_args_cpp_to_c() so that it process the C++ method as one
+	throwing a Glib::Error.
+	(convert_args_c_to_cpp): Modified to ignore the final GError if the
+	C function has been marked as one that will be wrapped by a C++ method
+	throwing the final C GError parameter.
+
+	* tools/m4/vfunc.m4 (_VFUNC_PCC): Modified to recognize a final
+	"errthrow" string parameter in which case code is inserted to declare
+	a local parameter in which to store the C GError and then throw
+	it as a Glib::Error if an error was received when the underlying C
+	function is called in the virtual function callback.
+	(_VFUNC_CC): Also modified to recognize a final "errthrow" string
+	parameter inserting code to store and then throw a possibly obtained
+	GError as a Glib::Error in the C++ virtual function when calling the
+	underlying C virtual function.
+
 2012-09-04  Josà Alburquerque  <jaalburquerque gmail com>
 
 	giomm: Add the ZlibDecompressor and the CharsetConverter classes.
diff --git a/tools/m4/vfunc.m4 b/tools/m4/vfunc.m4
index 93fccc1..c361162 100644
--- a/tools/m4/vfunc.m4
+++ b/tools/m4/vfunc.m4
@@ -18,10 +18,10 @@ ifelse(`$4',,,`#endif // $4
 _POP()')
 
 
-dnl               $1      $2       $3        $4
+dnl              $1      $2       $3        $4
 dnl _VFUNC_PCC(cppname,gtkname,cpprettype,crettype,
-dnl                        $5                $6          $7            $8        $9					$10
-dnl                  `<cargs and names>',`<cnames>',`<cpparg names>',firstarg, refreturn_ctype, ifdef)
+dnl                         $5               $6           $7            $8         $9           $10      $11
+dnl                  `<cargs and names>',`<cnames>',`<cpparg names>',firstarg, refreturn_ctype, ifdef, errthrow)
 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_(),
@@ -86,7 +86,15 @@ dnl  g_assert(base != 0);
 
   // Call the original underlying C function:
   if(base && base->$2)
-    ifelse($4,void,,`return ')(*base->$2)`'($6);
+  {
+    ifelse($4,void,,`$4 result = ')(*base->$2)`'($6);
+ifelse($11,errthrow,`dnl
+    if(*error)
+      ::Glib::Error::throw_exception(*error);
+')dnl
+ifelse($4,void,,`    return result;
+')dnl
+  }
 
 ifelse($4,void,,`dnl
 
@@ -98,8 +106,8 @@ ifelse(`$10',,,`#endif // $10
 ')dnl
 _POP()')
 
-#                $1        $2        $3           $4          $5            $6         $7          $8			$9
-# _VFUNC_CC(vfunc_name, gtkname, cpp_rettype, c_rettype, `<cppargs>', `<carg_names>', is_const, refreturn, $ifdef)
+#               $1        $2          $3         $4          $5             $6          $7        $8        $9        $10
+# _VFUNC_CC(vfunc_name, gtkname, cpp_rettype, c_rettype, `<cppargs>', `<carg_names>', is_const, refreturn, $ifdef, $errthrow)
 #
 define(`_VFUNC_CC',`dnl
 _PUSH(SECTION_CC_VFUNCS)
@@ -116,14 +124,25 @@ ifdef(`__BOOL_IS_INTERFACE__',`dnl
 dnl  g_assert(base != 0);
 
   if(base && base->$2)
+  {
+ifelse($10,errthrow,`dnl
+    GError* gerror = 0;
+')dnl
 ifelse($3,void,`dnl
     (*base->$2)`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'_COMMA_PREFIX($6));
+  }
 ',`dnl
 ifelse($8,refreturn,`dnl Assume Glib::wrap() is correct if refreturn is requested.
-    return Glib::wrap((*base->$2)`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'_COMMA_PREFIX($6)), true);
+    $3 result(Glib::wrap((*base->$2)`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'_COMMA_PREFIX($6)), true));
 ',`dnl
-    return _CONVERT($4,$3,`(*base->$2)`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'_COMMA_PREFIX($6))');
+    $3 result(_CONVERT($4,$3,`(*base->$2)`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'_COMMA_PREFIX($6))'));
 ')dnl
+ifelse($10,errthrow,`dnl
+    if(gerror)
+      ::Glib::Error::throw_exception(gerror);
+')dnl
+    return result;
+  }
 
   typedef $3 RType;
   return RType`'();
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index 33bbe45..2cad5d8 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -140,12 +140,18 @@ sub output_wrap_vfunc_h($$$$$$)
 }
 
 # _VFUNC_CC(signame,gtkname,rettype,crettype,`<cppargs>',`<cargs>')
-sub output_wrap_vfunc_cc($$$$$$$)
+sub output_wrap_vfunc_cc($$$$$$$$)
 {
   my ($self, $filename, $line_num, $objCppfunc, $objCFunc,
       $custom_vfunc, $custom_vfunc_callback, $ifdef) = @_;
 
   my $cname = $$objCFunc{name};
+  
+  my $errthrow = "";
+  if($$objCFunc{throw_any_errors})
+  {
+    $errthrow = "errthrow"
+  }
 
   # e.g. Gtk::Button::draw_indicator:
 
@@ -156,16 +162,17 @@ sub output_wrap_vfunc_cc($$$$$$$)
     my $refreturn = "";
     $refreturn = "refreturn" if($$objCppfunc{rettype_needs_ref});
 
-    my $str = sprintf("_VFUNC_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s)dnl\n",
+    my $str = sprintf("_VFUNC_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s)dnl\n",
       $$objCppfunc{name},
       $cname,
       $$objCppfunc{rettype},
       $$objCFunc{rettype},
       $objCppfunc->args_types_and_names(),
-      convert_args_cpp_to_c($objCppfunc, $objCFunc, 0, $line_num), #$objCppfunc->args_names_only(),
+      convert_args_cpp_to_c($objCppfunc, $objCFunc, 0, $line_num, $errthrow), #$objCppfunc->args_names_only(),
       $objCppfunc->get_is_const(),
       $refreturn,
-      $ifdef);
+      $ifdef,
+      $errthrow);
 
     $self->append($str);
   }
@@ -177,7 +184,7 @@ sub output_wrap_vfunc_cc($$$$$$$)
     my $refreturn_ctype = "";
     $refreturn_ctype = "refreturn_ctype" if($$objCFunc{rettype_needs_ref});
 
-    my $str = sprintf("_VFUNC_PCC(%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)dnl\n",
       $$objCppfunc{name},
       $cname,
       $$objCppfunc{rettype},
@@ -187,7 +194,8 @@ sub output_wrap_vfunc_cc($$$$$$$)
       convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num),
       ${$objCFunc->get_param_names()}[0],
       $refreturn_ctype,
-      $ifdef);
+      $ifdef,
+      $errthrow);
 
     $self->append($str);
   }
@@ -964,6 +972,10 @@ sub convert_args_c_to_cpp($$$)
   my @result;
 
   my $num_c_args = scalar(@{$c_param_types});
+  
+  # If the the function has been marked as a function that throws errors (Glib::Error)
+  # don't count the last GError** argument.
+  $num_c_args-- if($$objCDefsFunc{throw_any_errors});
 
   my $num_cpp_args = scalar(@{$cpp_param_types});
 
diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm
index 33a2431..374a575 100644
--- a/tools/pm/WrapParser.pm
+++ b/tools/pm/WrapParser.pm
@@ -1201,6 +1201,7 @@ sub on_wrap_vfunc($)
   my $custom_vfunc = 0;
   my $custom_vfunc_callback = 0;
   my $ifdef = "";
+  my $errthrow = 0;
 
   while($#args >= 2) # If optional arguments are there.
   {
@@ -1223,6 +1224,10 @@ sub on_wrap_vfunc($)
     {
       $custom_vfunc_callback = 1;
     }
+    elsif($argRef eq "errthrow")
+    {
+      $errthrow = 1;
+    }
     elsif($argRef =~ /^ifdef(.*)/) #If ifdef is at the start.
     {
     	$ifdef = $1;
@@ -1231,7 +1236,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);
+                           $custom_vfunc_callback, $ifdef, $errthrow);
 }
 
 sub on_wrap_enum($)
@@ -1400,11 +1405,11 @@ sub output_wrap_signal($$$$$$$$$$$)
 }
 
 # void output_wrap($CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype,
-#                  $custom_vfunc, $custom_vfunc_callback, $ifdef)
-sub output_wrap_vfunc($$$$$$$$)
+#                  $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow)
+sub output_wrap_vfunc($$$$$$$$$)
 {
   my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype,
-      $custom_vfunc, $custom_vfunc_callback, $ifdef) = @_;
+      $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow) = @_;
 
   #Some checks:
   return if ($self->output_wrap_check($CppDecl, $vfunc_name, $filename, $line_num, '_WRAP_VFUNC'));
@@ -1438,6 +1443,7 @@ sub output_wrap_vfunc($$$$$$$$)
   $$objCppVfunc{name} .= "_vfunc"; #All vfuncs should have the "_vfunc" suffix, and a separate easily-named invoker method.
 
   $$objCVfunc{rettype_needs_ref} = $refreturn_ctype;
+  $$objCVfunc{throw_any_errors} = 1 if($errthrow);
 
   $objOutputter->output_wrap_vfunc_h($filename, $line_num, $objCppVfunc, $objCVfunc, $ifdef);
   $objOutputter->output_wrap_vfunc_cc($filename, $line_num, $objCppVfunc, $objCVfunc,



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