[glibmm] gmmproc: _WRAP_VFUNC: Support the wrapping of slots.
- From: Josà Alburquerque <jaalburqu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] gmmproc: _WRAP_VFUNC: Support the wrapping of slots.
- Date: Thu, 17 Jan 2013 07:02:59 +0000 (UTC)
commit ded8526814af9a7c1596ace5bf85af942b9c890c
Author: Josà Alburquerque <jaalburqu svn gnome org>
Date: Thu Jan 17 01:36:12 2013 -0500
gmmproc: _WRAP_VFUNC: Support the wrapping of slots.
* tools/pm/WrapParser.pm (on_wrap_vfunc): Add support for parsing the
additional 'slot_name', 'slot_callback', and 'no_slot_copy' options
that do the same thing as the corresponding _WRAP_METHOD options (ie.
specify the name of the C++ slot parameter, the name of the callback
function and whether to use the original slot or a copy of it,
respectively. Also pass the options along to:
(output_wrap_vfunc): Store the options in the C++ virtual function
object so they can be tested for when converting the parameters and
composing the _VFUNC* m4 macro calls.
* tools/pm/Output.pm (output_wrap_vfunc_cc):
- Append the additional 'slot_type', 'slot_name' and 'no_slot_copy'
parameters to the _VFUNC_CC m4 macro invocation so that it can include
code for the vfunc to copy the slot parameter and pass it on to the C
function.
- Also append the additional 'slot_type' and 'c_data_param_name' to
the _VFUNC_PCC m4 macro so that it knows the slot type and the C
gpointer parameter name that contains the slot so that the macro can
generate code to extract the slot from the data parameter and pass the
slot on to the C++ virtual function.
(convert_args_c_to_cpp):
- Rewritten so that it loops through the C++ parameters so that it is
possible to re-order the parameters using the existing mapping
functionality that allows parameters to be re-ordered for the
_WRAP_[CREATE|CTOR|METHOD] macros. Also re-written so that it knows
how to deal with slot parameters.
* tools/m4/vfunc.m4 (_VFUNC_PCC): Modified to accept the additional
'slot_type' and 'c_data_param_name' arguments and to insert code to
extract the slot from the C gpointer data parameter to be passed on
to the C++ virtual function.
(_VFUNC_CC): Modified to accept the additional 'slot_type',
'slot_name' and 'no_slot_copy' arguments and to insert code to either
copy the slot in a 'slot_copy' variable or set the variable to the
actual slot (if it's so been specified) which is then passed on to the
C function.
ChangeLog | 39 ++++++++++++
tools/m4/vfunc.m4 | 23 ++++++-
tools/pm/Output.pm | 154 ++++++++++++++++++++++++++++++++++++-----------
tools/pm/WrapParser.pm | 41 +++++++++++--
4 files changed, 213 insertions(+), 44 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 6db2cb0..fd7c585 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,44 @@
2013-01-16 Josà Alburquerque <jaalburquerque gmail com>
+ gmmproc: _WRAP_VFUNC: Support the wrapping of slots.
+
+ * tools/pm/WrapParser.pm (on_wrap_vfunc): Add support for parsing the
+ additional 'slot_name', 'slot_callback', and 'no_slot_copy' options
+ that do the same thing as the corresponding _WRAP_METHOD options (ie.
+ specify the name of the C++ slot parameter, the name of the callback
+ function and whether to use the original slot or a copy of it,
+ respectively. Also pass the options along to:
+ (output_wrap_vfunc): Store the options in the C++ virtual function
+ object so they can be tested for when converting the parameters and
+ composing the _VFUNC* m4 macro calls.
+ * tools/pm/Output.pm (output_wrap_vfunc_cc):
+ - Append the additional 'slot_type', 'slot_name' and 'no_slot_copy'
+ parameters to the _VFUNC_CC m4 macro invocation so that it can include
+ code for the vfunc to copy the slot parameter and pass it on to the C
+ function.
+ - Also append the additional 'slot_type' and 'c_data_param_name' to
+ the _VFUNC_PCC m4 macro so that it knows the slot type and the C
+ gpointer parameter name that contains the slot so that the macro can
+ generate code to extract the slot from the data parameter and pass the
+ slot on to the C++ virtual function.
+ (convert_args_c_to_cpp):
+ - Rewritten so that it loops through the C++ parameters so that it is
+ possible to re-order the parameters using the existing mapping
+ functionality that allows parameters to be re-ordered for the
+ _WRAP_[CREATE|CTOR|METHOD] macros. Also re-written so that it knows
+ how to deal with slot parameters.
+ * tools/m4/vfunc.m4 (_VFUNC_PCC): Modified to accept the additional
+ 'slot_type' and 'c_data_param_name' arguments and to insert code to
+ extract the slot from the C gpointer data parameter to be passed on
+ to the C++ virtual function.
+ (_VFUNC_CC): Modified to accept the additional 'slot_type',
+ 'slot_name' and 'no_slot_copy' arguments and to insert code to either
+ copy the slot in a 'slot_copy' variable or set the variable to the
+ actual slot (if it's so been specified) which is then passed on to the
+ C function.
+
+2013-01-16 Josà Alburquerque <jaalburquerque gmail com>
+
gmmproc: _WRAP_[CREATE|CTOR|METHOD]: Allow any order of {} options.
* tools/pm/Function.pm: Make it possible to use any order desired of
diff --git a/tools/m4/vfunc.m4 b/tools/m4/vfunc.m4
index c361162..53f8714 100644
--- a/tools/m4/vfunc.m4
+++ b/tools/m4/vfunc.m4
@@ -21,7 +21,9 @@ _POP()')
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 `<cargs and names>',`<cnames>',`<cpparg names>',firstarg, refreturn_ctype, ifdef, errthrow,
+dnl $12 $13
+dnl slot_type, c_data_param_name)
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_(),
@@ -32,6 +34,10 @@ ifelse(`$10',,,`#ifdef $10'
)dnl
$4 __CPPNAME__`'_Class::$2_vfunc_callback`'($5)
{
+ifelse(`$13',,,dnl
+` const $12* slot = static_cast<$12*>($13);
+
+')dnl
dnl First, do a simple cast to ObjectBase. We will have to do a dynamic_cast
dnl eventually, but it is not necessary to check whether we need to call
dnl the vfunc.
@@ -106,8 +112,8 @@ ifelse(`$10',,,`#endif // $10
')dnl
_POP()')
-# $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)
+# $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13
+# _VFUNC_CC(vfunc_name, gtkname, cpp_rettype, c_rettype, `<cppargs>', `<carg_names>', is_const, refreturn, $ifdef, $errthrow, $slot_type, $slot_name, $no_slot_copy)
#
define(`_VFUNC_CC',`dnl
_PUSH(SECTION_CC_VFUNCS)
@@ -115,6 +121,17 @@ ifelse(`$9',,,`#ifdef $9'
)dnl
$3 __NAMESPACE__::__CPPNAME__::$1`'($5) ifelse($7,1,const,)
{
+dnl If a slot type has been specified, insert code to create a copy of it.
+ifelse(`$11',,,dnl
+dnl See if the slot should or should not be copied
+`ifelse(`$13',,dnl
+` // Create a copy of the slot.
+ $11* slot_copy = new $11($12); ',dnl
+dnl
+` // Use the original slot (not a copy).
+ $11* slot_copy = const_cast<$11*>(&$12);')
+
+')dnl
BaseClassType *const base = static_cast<BaseClassType*>(
ifdef(`__BOOL_IS_INTERFACE__',`dnl
_IFACE_PARENT_FROM_OBJECT(gobject_)dnl
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index a17dcce..7a03dce 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -173,7 +173,10 @@ sub output_wrap_vfunc_cc($$$$$$$$)
my ($conversions, $declarations, $initializations) =
convert_args_cpp_to_c($objCppfunc, $objCFunc, 0, $line_num, $errthrow);
- my $str = sprintf("_VFUNC_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s)dnl\n",
+ my $no_slot_copy = "";
+ $no_slot_copy = "no_slot_copy" if ($$objCppfunc{no_slot_copy});
+
+ my $str = sprintf("_VFUNC_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s)dnl\n",
$$objCppfunc{name},
$cname,
$$objCppfunc{rettype},
@@ -183,7 +186,10 @@ sub output_wrap_vfunc_cc($$$$$$$$)
$objCppfunc->get_is_const(),
$refreturn,
$ifdef,
- $errthrow);
+ $errthrow,
+ $$objCppfunc{slot_type},
+ $$objCppfunc{slot_name},
+ $no_slot_copy);
$self->append($str);
}
@@ -195,18 +201,24 @@ 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,%s)dnl\n",
+ # Get the conversions.
+ my $conversions =
+ convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num);
+
+ my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s)dnl\n",
$$objCppfunc{name},
$cname,
$$objCppfunc{rettype},
$$objCFunc{rettype},
$objCFunc->args_types_and_names(),
$objCFunc->args_names_only(),
- convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num),
+ $conversions,
${$objCFunc->get_param_names()}[0],
$refreturn_ctype,
$ifdef,
- $errthrow);
+ $errthrow,
+ $$objCppfunc{slot_type},
+ $$objCppfunc{c_data_param_name});
$self->append($str);
}
@@ -398,9 +410,9 @@ sub output_wrap_meth($$$$$$$)
# convert_args_cpp_to_c() to not be included, then don't.
if ($$objCppfunc{include_slot})
{
- $no_slot_copy = "no_slot_copy" if ($$objCppfunc{no_slot_copy});
$slot_type = $$objCppfunc{slot_type};
$slot_name = $$objCppfunc{slot_name};
+ $no_slot_copy = "no_slot_copy" if ($$objCppfunc{no_slot_copy});
}
$str = sprintf("_STATIC_METHOD(%s,%s,\`%s\',%s,\`%s\',\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,`%s',`%s',`%s',%s)dnl\n",
@@ -436,9 +448,9 @@ sub output_wrap_meth($$$$$$$)
# convert_args_cpp_to_c() to not be included, then don't.
if ($$objCppfunc{include_slot})
{
- $no_slot_copy = "no_slot_copy" if ($$objCppfunc{no_slot_copy});
$slot_type = $$objCppfunc{slot_type};
$slot_name = $$objCppfunc{slot_name};
+ $no_slot_copy = "no_slot_copy" if ($$objCppfunc{no_slot_copy});
}
$str = sprintf("_METHOD(%s,%s,\`%s\',%s,\`%s\',\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,\`%s\',%s,%s,%s,`%s',`%s',`%s',%s)dnl\n",
@@ -984,15 +996,15 @@ sub convert_args_cpp_to_c($$$$$)
# Get the desired argument list combination.
my $possible_arg_list = $$objCppfunc{possible_args_list}[$index];
+ # Tells if slot code should be included or not based on if a slot
+ # parameter is optional.
+ $$objCppfunc{include_slot} = 0;
+
# Loop through the parameters:
my $i;
my $cpp_param_max = $num_cpp_args;
# if( !($static) ) { $cpp_param_max++; }
- # Tells if slot code should be included or not based on if a slot
- # parameter is optional.
- $$objCppfunc{include_slot} = 0;
-
for ($i = 0; $i < $cpp_param_max; $i++)
{
# Skip the output parameter because it is handled in output_wrap_meth().
@@ -1075,6 +1087,9 @@ sub convert_args_cpp_to_c($$$$$)
Output::error(
"convert_args_cpp_to_c(): Missing a slot callback. " .
"Specify it with the 'slot_callback' option.\n",);
+ $objCppfunc->dump();
+ $objCDefsFunc->dump();
+ return ("", "", "");
}
# Get the slot type without the const and the & and store it so
@@ -1104,14 +1119,16 @@ sub convert_args_cpp_to_c($$$$$)
}
}
- # Append the final slot copy parameter to the C function if the
- # method has a slot. The parameter name is consistent with the name
- # in the _*METHOD() m4 macros.
+ # Append the final slot copy parameter to the C function if the method
+ # has a slot. The m4 macros assume that that parameter name is
+ # "slot_copy". The m4 macros will either copy the slot to the
+ # "slot_copy variable or set it to the address of the slot itself if
+ # the slot should not be copied.
if ($$objCppfunc{slot_name})
{
if ($$objCppfunc{include_slot})
{
- push(@conversions, "slot_copy")
+ push(@conversions, "slot_copy");
}
else
{
@@ -1130,19 +1147,32 @@ sub convert_args_c_to_cpp($$$)
{
my ($objCDefsFunc, $objCppfunc, $wrap_line_number) = @_;
+ my $cpp_param_names = $$objCppfunc{param_names};
my $cpp_param_types = $$objCppfunc{param_types};
my $c_param_types = $$objCDefsFunc{param_types};
my $c_param_names = $$objCDefsFunc{param_names};
+ # This variable stores the C++ parameter mappings from the C++
+ # index to the C param name if the mappings exist.
+ my %cpp_index_param_mappings;
+
+ @cpp_index_param_mappings{values $$objCppfunc{param_mappings}}
+ = keys $$objCppfunc{param_mappings};
+
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.
+ # 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});
+
+ # If the method has a slot temporarily increment the C++ arg count when
+ # comparing the C++ and C argument count because the C function would
+ # have a final 'gpointer data' parameter and the C++ method would not.
+ $num_cpp_args++ if ($$objCppfunc{slot_name});
if ( ($num_cpp_args + 1) != $num_c_args )
{
@@ -1155,30 +1185,82 @@ sub convert_args_c_to_cpp($$$)
return "";
}
+ # Re-decrement the expected C++ argument count if there is a slot.
+ $num_cpp_args-- if ($$objCppfunc{slot_name});
- # Loop through the c parameters:
- my $i;
- my $c_param_max = $num_c_args;
+ # Loop through the C++ parameters:
+ my $i;
+ my $cpp_param_max = $num_cpp_args;
- for ($i = 1; $i < $c_param_max; $i++)
- {
- #index of C parameter:
- my $iCppParam = $i - 1;
+ for ($i = 0; $i < $cpp_param_max; $i++)
+ {
+ my $cParamName = "";
+ my $c_index = 0;
- my $cppParamType = $$cpp_param_types[$iCppParam];
- $cppParamType =~ s/ &/&/g; #Remove space between type and &.
- $cppParamType =~ s/ \*/*/g; #Remove space between type and *
+ if (defined $cpp_index_param_mappings{$i})
+ {
+ # If a mapping exists from the current index to a C param name,
+ # use that C param for the conversion.
+ $cParamName = $cpp_index_param_mappings{$i};
- my $cParamName = $$c_param_names[$i];
- my $cParamType = $$c_param_types[$i];
+ # Get the C index based on the C param name.
+ ++$c_index until $$c_param_names[$c_index] eq $cParamName;
+ }
+ else
+ {
+ # If no mapping exists, the C index is the C++ index + 1 (to skip
+ # The 'self' argument of the C function).
+ $c_index = $i + 1;
+ $cParamName = $$c_param_names[$c_index];
+ }
- if ($cParamType ne $cppParamType) #If a type conversion is needed.
- {
- push(@result, sprintf("_CONVERT(%s,%s,%s,%s)\n",
- $cParamType,
- $cppParamType,
- $cParamName,
- $wrap_line_number) );
+ my $cParamType = $$c_param_types[$c_index];
+
+ my $cppParamName = $$cpp_param_names[$i];
+ my $cppParamType = $$cpp_param_types[$i];
+ $cppParamType =~ s/ &/&/g; #Remove space between type and &.
+ $cppParamType =~ s/ \*/*/g; #Remove space between type and *
+
+ if ($$objCppfunc{slot_name})
+ {
+ # If the current parameter is the slot parameter insert the
+ # derefenced name of the variable containing the slot which is
+ # assumed to be '*slot'. The m4 macro is responsible for ensuring
+ # that the variable is declared and the slot in the 'user_data' C
+ # param is placed in the variable.
+ if ($$objCppfunc{slot_name} eq $cppParamName)
+ {
+ push(@result, "*slot");
+
+ # Get the slot type without the const and the '&' and store it so
+ # it can be passed to the m4 macro.
+ $cppParamType =~ /^const\s+(.*)&/;
+
+ # If the type does not contain
+ # any '::' then assume that it is in the library standard namespace
+ # by prepending '__NAMESPACE__::' to it which the m4 macros will
+ # translate to the library namespace.
+ my $plainCppParamType = $1;
+ $plainCppParamType = "__NAMESPACE__::" . $plainCppParamType
+ if (!($plainCppParamType =~ /::/));
+
+ $$objCppfunc{slot_type} = $plainCppParamType;
+
+ # Store the name of the C data parameter so it can be passed
+ # to the m4 macro so it can extract the slot.
+ $$objCppfunc{c_data_param_name} = $$c_param_names[$num_c_args - 1];
+
+ next;
+ }
+ }
+
+ if ($cParamType ne $cppParamType) #If a type conversion is needed.
+ {
+ push(@result, sprintf("_CONVERT(%s,%s,%s,%s)\n",
+ $cParamType,
+ $cppParamType,
+ $cParamName,
+ $wrap_line_number) );
}
else
{
diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm
index 82c148f..8235218 100644
--- a/tools/pm/WrapParser.pm
+++ b/tools/pm/WrapParser.pm
@@ -1252,6 +1252,9 @@ sub on_wrap_vfunc($)
my $custom_vfunc_callback = 0;
my $ifdef = "";
my $errthrow = 0;
+ my $slot_name = "";
+ my $slot_callback = "";
+ my $no_slot_copy = 0;
while($#args >= 2) # If optional arguments are there.
{
@@ -1282,11 +1285,31 @@ sub on_wrap_vfunc($)
{
$ifdef = $1;
}
+ # The "slot_name" option tells gmmproc the name of the parameter
+ # that is a slot in the virtual function if there is one.
+ elsif($argRef =~ /^slot_name\s+(\w+)/)
+ {
+ $slot_name = $1;
+ }
+ # The "slot_callback" option tells gmmproc the name of the
+ # callback function that should be passed to the C function if the
+ # virtual function has a slot.
+ elsif($argRef =~ /^slot_callback\s+(\w+)/)
+ {
+ $slot_callback = $1;
+ }
+ # The "no_slot_copy" options tells gmmproc to pass the actual slot
+ # and not a copy of it to the C function in the data parameter.
+ elsif($argRef eq "no_slot_copy")
+ {
+ $no_slot_copy = 1;
+ }
}
$self->output_wrap_vfunc($argCppDecl, $argCName, $$self{filename}, $$self{line_num},
$refreturn, $refreturn_ctype, $custom_vfunc,
- $custom_vfunc_callback, $ifdef, $errthrow);
+ $custom_vfunc_callback, $ifdef, $errthrow,
+ $slot_name, $slot_callback, $no_slot_copy);
}
sub on_wrap_enum($)
@@ -1454,12 +1477,15 @@ sub output_wrap_signal($$$$$$$$$$$)
}
}
-# void output_wrap($CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype,
-# $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow)
-sub output_wrap_vfunc($$$$$$$$$)
+# 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)
+sub output_wrap_vfunc($$$$$$$$$$$$)
{
my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype,
- $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow) = @_;
+ $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow,
+ $slot_name, $slot_callback, $no_slot_copy) = @_;
#Some checks:
return if ($self->output_wrap_check($CppDecl, $vfunc_name, $filename, $line_num, '_WRAP_VFUNC'));
@@ -1491,6 +1517,11 @@ sub output_wrap_vfunc($$$$$$$$$)
$$objCppVfunc{rettype_needs_ref} = $refreturn;
$$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.
+ $$objCppVfunc{slot_name} = $slot_name if ($slot_name);
+ $$objCppVfunc{slot_callback} = $slot_callback if ($slot_callback);
+ $$objCppVfunc{no_slot_copy} = $no_slot_copy if ($no_slot_copy);
$$objCVfunc{rettype_needs_ref} = $refreturn_ctype;
$$objCVfunc{throw_any_errors} = 1 if($errthrow);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]