[glibmm] gmmproc: _WRAP_METHOD: Add the possibility of an output parameter.
- From: José Alburquerque <jaalburqu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] gmmproc: _WRAP_METHOD: Add the possibility of an output parameter.
- Date: Tue, 7 Jun 2011 17:42:05 +0000 (UTC)
commit 5212ec63cc25b7350b349a2e435ee1e8000bf7f8
Author: José Alburquerque <jaalburqu svn gnome org>
Date: Tue Jun 7 13:33:16 2011 -0400
gmmproc: _WRAP_METHOD: Add the possibility of an output parameter.
* tools/pm/Output.pm (output_wrap_meth): Modified to test if there is
a parameter mapping in the current C++ function from the hypothetical
C name 'RET' to a C++ parameter index. If so, that parameter is
treated as an output parameter. This allows wrap statements such as:
_WRAP_METHOD(static void get_finish(Glib::RefPtr<Connection>&
conn{RET}, const Glib::RefPtr<AsyncResult>& res), g_bus_get_finish,
errthrow
)
Where the 'conn' parameter is an output parameter. The output
parameter name and type are passed to the _STATIC_METHOD and _METHOD
macros (along with the wrap line number).
(convert_args_cpp_to_c): Modified to process the C++ parameters
dealing with the possibility of an output parameter.
* tools/pm/Function.pm: Typo.
* tools/m4/method.m4 (_METHOD):
(_STATIC_METHOD): Both modified to accept an optional output parameter
name, type and wrap line number and if they exist to ensure that the
output parameter is correctly set to the return of the C function. To
do that it uses the new _INITIALIZE macro.
* tools/m4/convert_base.m4 (_INITIALIZER):
(_INITIALIZE): Add macros (similar to the _CONVERSION/_CONVERT
macros) used to record how to initialize a C++ type from a C type and
later to initialize an output parameter of the C++ type. The
_INITIALIZER macro has much the same syntax as the _CONVERSION macro.
For example:
_INITIALIZER(`Glib::RefPtr<Connection>&',`GDBusConnection*',
`$3 = Glib::wrap($4)')
Describes how to initialize a C++ reference to a Glib::RefPtr that
contains a Gio::DBus::Connection from its corresponding C type. $3
represents the output parameter name and $4 represents the C return.
The _INITIALIZE macro can then be appropriately used by the _METHOD
and _STATIC_METHOD macros to initialize the output parameters passed
to them by gmmproc.
ChangeLog | 47 +++++++++++++++++++++++++++++++++++++
tools/m4/convert_base.m4 | 21 ++++++++++++++++
tools/m4/method.m4 | 43 +++++++++++++++++++++++----------
tools/pm/Function.pm | 2 +-
tools/pm/Output.pm | 58 ++++++++++++++++++++++++++++++++++++++++++----
5 files changed, 152 insertions(+), 19 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 0b79821..331a120 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,50 @@
+2011-06-07 José Alburquerque <jaalburqu svn gnome org>
+
+ gmmproc: _WRAP_METHOD: Add the possibility of an output parameter.
+
+ * tools/pm/Output.pm (output_wrap_meth): Modified to test if there is
+ a parameter mapping in the current C++ function from the hypothetical
+ C name 'RET' to a C++ parameter index. If so, that parameter is
+ treated as an output parameter. This allows wrap statements such as:
+
+ _WRAP_METHOD(static void get_finish(Glib::RefPtr<Connection>&
+ conn{RET}, const Glib::RefPtr<AsyncResult>& res), g_bus_get_finish,
+ errthrow
+ )
+
+ Where the 'conn' parameter is an output parameter. The output
+ parameter name and type are passed to the _STATIC_METHOD and _METHOD
+ macros (along with the wrap line number).
+
+ (convert_args_cpp_to_c): Modified to process the C++ parameters
+ dealing with the possibility of an output parameter.
+
+ * tools/pm/Function.pm: Typo.
+
+ * tools/m4/method.m4 (_METHOD):
+ (_STATIC_METHOD): Both modified to accept an optional output parameter
+ name, type and wrap line number and if they exist to ensure that the
+ output parameter is correctly set to the return of the C function. To
+ do that it uses the new _INITIALIZE macro.
+
+ * tools/m4/convert_base.m4 (_INITIALIZER):
+ (_INITIALIZE): Add macros (similar to the _CONVERSION/_CONVERT
+ macros) used to record how to initialize a C++ type from a C type and
+ later to initialize an output parameter of the C++ type. The
+ _INITIALIZER macro has much the same syntax as the _CONVERSION macro.
+ For example:
+
+ _INITIALIZER(`Glib::RefPtr<Connection>&',`GDBusConnection*',
+ `$3 = Glib::wrap($4)')
+
+ Describes how to initialize a C++ reference to a Glib::RefPtr that
+ contains a Gio::DBus::Connection from its corresponding C type. $3
+ represents the output parameter name and $4 represents the C return.
+
+ The _INITIALIZE macro can then be appropriately used by the _METHOD
+ and _STATIC_METHOD macros to initialize the output parameters passed
+ to them by gmmproc.
+
2011-06-06 José Alburquerque <jaalburqu svn gnome org>
gmmproc: _WRAP_[CREATE|CTOR|METHOD]: Support parameter reordering.
diff --git a/tools/m4/convert_base.m4 b/tools/m4/convert_base.m4
index 51c462e..c5786a3 100644
--- a/tools/m4/convert_base.m4
+++ b/tools/m4/convert_base.m4
@@ -35,6 +35,27 @@ define(`_CONVERSION',`
m4_ifelse(`$3',,,`define(CF`'__HASH2(`$1',`$2'),`$3')')
')
+#
+# _INITIALIZE(target_type, fromtype, output_param_name, c_return, wrap_line)
+# Print an initialize statement from ctype to cpptype
+define(`_INITIALIZE',`dnl
+m4_ifelse(`$2',void,`$4',`dnl
+pushdef(`__INI',`IN`'__HASH2(`$1',`$2')')dnl
+m4_ifdef(__INI,`m4_indir(__INI,`$1',`$2',`$3', `$4')',`
+m4_errprint(`No initializer for type $1 from type $2 defined (line: $5, output param: $3, c return: $4)
+')
+m4_m4exit(1)
+')`'dnl
+')`'dnl
+')
+
+#
+# Functions for populating initializer tables.
+#
+define(`_INITIALIZER',`
+m4_ifelse(`$3',,,`define(IN`'__HASH2(`$1',`$2'),`$3')')
+')
+
define(`_EQUAL',`define(EV`'__HASH(`$1'),`$2')')
/*******************************************************************/
diff --git a/tools/m4/method.m4 b/tools/m4/method.m4
index 20a8f3a..943eb31 100644
--- a/tools/m4/method.m4
+++ b/tools/m4/method.m4
@@ -2,15 +2,15 @@ dnl $Id$
dnl
dnl
-dnl Code generation sections for making a method.
+dnl Code generation sections for making a method.
dnl
dnl
dnl
dnl method
-dnl $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14
-dnl _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const,refreturn,errthrow,deprecated,constversion,ifdef, arglist_without_types)
+dnl $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16
+dnl _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const,refreturn,errthrow,deprecated,constversion,ifdef,arglist_without_types,out_param,out_param_cpptype,wrap_line)
define(`_METHOD',`dnl
_PUSH(SECTION_CC)
ifelse(`$10',,,`_DEPRECATE_IFDEF_START
@@ -21,19 +21,28 @@ $3 __CPPNAME__::$1`'($5)ifelse(`$7',1,` const')
{
ifelse(`$11',,dnl
`ifelse(`$8'`$9',,dnl If it is not errthrow or refreturn
+`ifelse(`$14',,dnl If no output parameter is specified
`ifelse(`$3',void,dnl If it returns voids:
`$2(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$6',,,`, ')$6);' dnl It it returns non-void:
-,` return _CONVERT($4,$3,`$2`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$6',,,`, ')$6)');')'dnl End if it returns voids.
-,dnl If is errthrow or refreturn
+,` return _CONVERT($4,$3,`$2`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$6',,,`, ')$6)');'dnl
+)'dnl End if it returns voids.
+dnl An output parameter is specified:
+,` _INITIALIZE($15,$4,`$14',`$2`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$6',,,`, ')$6)',$16);'dnl
+)',dnl End if an output parameter is specified.
+dnl If is errthrow or refreturn
`ifelse(`$9',,,` GError* gerror = 0;')
- ifelse(`$3',void,,``$3' retvalue = ')_CONVERT($4,$3,`$2`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$6',,,`, ')$6)');dnl
+ifelse(`$14',,dnl If no output parameter is specified:
+` ifelse(`$3',void,,``$3' retvalue = ')_CONVERT($4,$3,`$2`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$6',,,`, ')$6)');'dnl
+dnl An output parameter is specified:
+,` _INITIALIZE($15,$4,`$14',`$2`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'ifelse(`$6',,,`, ')$6)',$16);'dnl
+)dnl
ifelse(`$9',,,`
if(gerror)
::Glib::Error::throw_exception(gerror);
')
ifelse(`$8',,,`dnl
- if(retvalue)
- retvalue->reference(); //The function does not do a ref for us.
+ if(ifelse(`$14',,`retvalue',$14))
+ ifelse(`$14',,`retvalue',$14)->reference(); //The function does not do a ref for us.
')dnl
ifelse(`$3',void,,` return retvalue;')
')dnl End errthrow/refreturn
@@ -49,8 +58,8 @@ _POP()')
dnl
dnl static method
-dnl $1 $2 $3 $4 $5 $6 $7 $8 $9 $10
-dnl _STATIC_METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,refreturn,errthrow,deprecated,ifdef))
+dnl $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13
+dnl _STATIC_METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,refreturn,errthrow,deprecated,ifdef,out_param,out_param_type,wrap_line)
define(`_STATIC_METHOD',`dnl
_PUSH(SECTION_CC)
ifelse(`$9',,,`_DEPRECATE_IFDEF_START
@@ -60,17 +69,25 @@ ifelse(`$10',,,`#ifdef $10'
$3 __CPPNAME__::$1($5)
{
ifelse(`$7'`$8',,dnl
+`ifelse(`$11',,dnl If no output parameter is specified
`ifelse(`$3',void,,` return ')_CONVERT($4,$3,`$2`'($6)');
-',dnl
+'dnl
+dnl An output parameter is specified:
+,` _INITIALIZE($12,$4,`$11',`$2`'($6)',$13);'
+)',dnl End if an output parameter is specified.
`ifelse(`$8',,,` GError* gerror = 0;')
+ifelse(`$11',,dnl If no output parameter is specified:
ifelse(`$3',void,,``$3' retvalue = ')_CONVERT($4,$3,`$2`'($6)');
+dnl An output parameter is specified:
+,` _INITIALIZE($12,$4,`$11',`$2`'($6)',$13);'dnl
+)dnl
ifelse(`$8',,,`
if(gerror)
::Glib::Error::throw_exception(gerror);
')
ifelse(`$7',,,`dnl
- if(retvalue)
- retvalue->reference(); //The function does not do a ref for us.
+ if(ifelse(`$11',,`retvalue',$11))
+ ifelse(`$11',,`retvalue',$11)->reference(); //The function does not do a ref for us
')dnl
ifelse(`$3',void,,` return retvalue;')
')dnl
diff --git a/tools/pm/Function.pm b/tools/pm/Function.pm
index c80e993..cfa64ad 100644
--- a/tools/pm/Function.pm
+++ b/tools/pm/Function.pm
@@ -281,7 +281,7 @@ sub parse_param($$)
$curr_param++;
# Mappings from a C name to this C++ param defaults to empty (no mapping).
- my $mapping = "";
+ $mapping = "";
$id = 0;
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index 0872de1..10acc10 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -282,8 +282,21 @@ sub output_wrap_meth($$$$$$$)
my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $cppMethodDecl, $documentation, $ifdef) = @_;
my $objDefsParser = $$self{objDefsParser};
+ my $cpp_param_names = $$objCppfunc{param_names};
+ my $cpp_param_types = $$objCppfunc{param_types};
+ my $cpp_param_mappings = $$objCppfunc{param_mappings};
+
my $num_args_list = $objCppfunc->get_num_possible_args_list();
+ my $output_var_name;
+ my $output_var_type;
+
+ if(defined($$cpp_param_mappings{"RET"}))
+ {
+ $output_var_name = $$cpp_param_names[$$cpp_param_mappings{"RET"}];
+ $output_var_type = $$cpp_param_types[$$cpp_param_mappings{"RET"}];
+ }
+
for(my $arg_list = 0; $arg_list < $num_args_list; $arg_list++)
{
# Allow the generated .h/.cc code to have an #ifndef around it, and add
@@ -343,7 +356,7 @@ sub output_wrap_meth($$$$$$$)
#Implementation:
my $str;
if ($$objCppfunc{static}) {
- $str = sprintf("_STATIC_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s)dnl\n",
+ $str = sprintf("_STATIC_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s)dnl\n",
$$objCppfunc{name},
$$objCDefsFunc{c_name},
$$objCppfunc{rettype},
@@ -354,9 +367,13 @@ sub output_wrap_meth($$$$$$$)
$refneeded,
$errthrow,
$deprecated,
- $ifdef);
+ $ifdef,
+ $output_var_name,
+ $output_var_type,
+ $line_num
+ );
} else {
- $str = sprintf("_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s,%s,\`%s\',%s)dnl\n",
+ $str = sprintf("_METHOD(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s,%s,\`%s\',%s,%s,%s,%s)dnl\n",
$$objCppfunc{name},
$$objCDefsFunc{c_name},
$$objCppfunc{rettype},
@@ -370,7 +387,10 @@ sub output_wrap_meth($$$$$$$)
$deprecated,
$constversion,
$objCppfunc->args_names_only($arg_list),
- $ifdef
+ $ifdef,
+ $output_var_name,
+ $output_var_type,
+ $line_num
);
}
$self->append($str);
@@ -785,6 +805,19 @@ sub convert_args_cpp_to_c($$$$$)
my $num_cpp_args = scalar(@{$cpp_param_types});
+ my $has_output_param = 0;
+ my $output_param_index;
+
+ # See if there is an output parameter. If so, temporarily decrement the
+ # number of C++ arguments so that the possible GError addition works and
+ # note the existence.
+ if(defined($$cpp_param_mappings{"RET"}))
+ {
+ $num_cpp_args--;
+ $has_output_param = 1;
+ $output_param_index = $$cpp_param_mappings{"RET"};
+ }
+
# add implicit last error parameter;
if ( $automatic_error ne "" &&
$num_cpp_args == ($num_c_args_expected - 1) &&
@@ -794,8 +827,13 @@ sub convert_args_cpp_to_c($$$$$)
$cpp_param_names = [ {$cpp_param_names},"gerror"];
$cpp_param_types = [ {$cpp_param_types},"GError*&"];
$cpp_param_optional = [ {$cpp_param_optional}, 0];
+
# Map from the C gerror param name to the newly added C++ param index.
- $$cpp_param_mappings{ $c_param_names[$num_c_args_expected]} =$num_cpp_args - 1;
+ # The correct C++ index to map to (from the C name) depends on if there
+ # is an output parameter since it will be readded.
+ my $cpp_index = $num_cpp_args - 1;
+ $cpp_index++ if($has_output_param);
+ $$cpp_param_mappings{ $c_param_names[$num_c_args_expected]} = $cpp_index;
}
if ( $num_cpp_args != $num_c_args_expected )
@@ -809,6 +847,10 @@ sub convert_args_cpp_to_c($$$$$)
return "";
}
+ # If there is an output variable it must be processed so re-increment (now)
+ # the number of C++ arguments.
+ $num_cpp_args++ if($has_output_param);
+
# Get the desired argument list combination.
my $possible_arg_list = $$objCppfunc{possible_args_list}[$index];
@@ -819,10 +861,16 @@ sub convert_args_cpp_to_c($$$$$)
for ($i = 0; $i < $cpp_param_max; $i++)
{
+ # Skip the output parameter because it is handled in output_wrap_meth().
+ next if($has_output_param && $i == $output_param_index);
+
#index of C parameter:
my $iCParam = $i;
if( !($static) ) { $iCParam++; }
+ # Account for a possible C++ output param in the C++ arg list.
+ $iCParam-- if($has_output_param && $i > $output_param_index);
+
my $c_param_name = @$c_param_names[$iCParam];
my $cpp_param_index = $i;
$cpp_param_index = $$cpp_param_mappings{$c_param_name} if(defined($$cpp_param_mappings{$c_param_name}));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]