summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Alburquerque <jaalburqu@svn.gnome.org>2011-06-07 13:33:16 -0400
committerJosé Alburquerque <jaalburqu@svn.gnome.org>2011-06-07 13:39:24 -0400
commit5212ec63cc25b7350b349a2e435ee1e8000bf7f8 (patch)
treec9f7db32811a067223d3b5d7f6e694877fd867fa
parent29da38e4fa01fa4460ca5359e0346f25c7781a5a (diff)
downloadglibmm-5212ec63cc25b7350b349a2e435ee1e8000bf7f8.tar.gz
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.
-rw-r--r--ChangeLog47
-rw-r--r--tools/m4/convert_base.m421
-rw-r--r--tools/m4/method.m443
-rw-r--r--tools/pm/Function.pm2
-rw-r--r--tools/pm/Output.pm58
5 files changed, 152 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 0b798215..331a1206 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 51c462eb..c5786a3e 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 20a8f3a3..943eb318 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 c80e993f..cfa64ad6 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 0872de1d..10acc10a 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}));