summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjell.ahlstedt@bredband.net>2015-03-17 10:19:03 +0100
committerKjell Ahlstedt <kjell.ahlstedt@bredband.net>2015-03-17 10:19:03 +0100
commitd1f1eca2d3a5044d6b31c4acf49879fda5306fd8 (patch)
tree90c9f3fc13541d90e629624023c40029d13e3a48
parentaa9793638c55e1cb62935af4b6587b2078d96585 (diff)
downloadglibmm-d1f1eca2d3a5044d6b31c4acf49879fda5306fd8.tar.gz
gmmproc: _WRAP_VFUNC: Add the keep_return parameter
* glib/glibmm/utility.h: Add template function destroy_notify_delete(). * tools/pm/WrapParser.pm: * tools/pm/Output.pm: * tools/m4/vfunc.m4: Add optional parameter keep_return to _WRAP_VFUNC(). Bug #705124.
-rw-r--r--glib/glibmm/utility.h11
-rw-r--r--tools/m4/vfunc.m454
-rw-r--r--tools/pm/Output.pm6
-rw-r--r--tools/pm/WrapParser.pm16
4 files changed, 63 insertions, 24 deletions
diff --git a/glib/glibmm/utility.h b/glib/glibmm/utility.h
index 6e5319b8..79fecb6b 100644
--- a/glib/glibmm/utility.h
+++ b/glib/glibmm/utility.h
@@ -1,4 +1,3 @@
-// -*- c++ -*-
#ifndef _GLIBMM_UTILITY_H
#define _GLIBMM_UTILITY_H
@@ -113,6 +112,16 @@ std::string convert_return_gchar_ptr_to_stdstring(char* str)
// Append type_name to dest, while replacing special characters with '+'.
void append_canonical_typename(std::string& dest, const char* type_name);
+// Delete data referred to by a void*.
+// Instantiations can be used as destroy callbacks in glib functions
+// that take a GDestroyNotify parameter, such as g_object_set_qdata_full()
+// and g_option_group_set_translate_func().
+template <typename T>
+void destroy_notify_delete(void* data)
+{
+ delete static_cast<T*>(data);
+}
+
} // namespace Glib
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
diff --git a/tools/m4/vfunc.m4 b/tools/m4/vfunc.m4
index beac4c86..156a3a4b 100644
--- a/tools/m4/vfunc.m4
+++ b/tools/m4/vfunc.m4
@@ -20,22 +20,24 @@ _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 $12 $13 $14 $15
-dnl slot_type, c_data_param_name, return_value, exception_handler)
+dnl $5 $6 $7 $8
+dnl `<cargs and names>',`<cnames>',`<cpparg names>',firstarg,
+dnl $9 $10 $11 $12
+dnl refreturn_ctype, keep_return, ifdef, errthrow,
+dnl $13 $14 $15 $16
+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_(),
dnl but it is not yet clear whether that would be a worthwhile performance optimization.
define(`_VFUNC_PCC',`dnl
_PUSH(SECTION_PCC_VFUNCS)
-ifelse(`$10',,,`#ifdef $10'
+ifelse(`$11',,,`#ifdef $11'
)dnl
$4 __CPPNAME__`'_Class::$2_vfunc_callback`'($5)
{
-ifelse(`$13',,,dnl
-` const $12* slot = static_cast<$12*>($13);
+ifelse(`$14',,,dnl
+` const $13* slot = static_cast<$13*>($14);
')dnl
dnl First, do a simple cast to ObjectBase. We will have to do a dynamic_cast
@@ -65,26 +67,42 @@ dnl C++ vfunc on it.
ifelse($4,void,`dnl
obj->$1`'($7);
return;
-',`dnl
+',`dnl not void
ifelse($9,refreturn_ctype,`dnl Assume Glib::unwrap_copy() is correct if refreturn_ctype is requested.
return Glib::unwrap_copy`'(`obj->$1'($7));
-',`dnl
+',`dnl not refreturn_ctype
+ifelse($10,keep_return,`dnl
+ static GQuark quark_return_value = g_quark_from_static_string("__NAMESPACE__::__CPPNAME__::$1");
+
+ $3* return_value = static_cast<$3*>(g_object_get_qdata(obj_base->gobj(), quark_return_value));
+ if (!return_value)
+ {
+ return_value = new $3`'();
+ g_object_set_qdata_full(obj_base->gobj(), quark_return_value, return_value,
+ &Glib::destroy_notify_delete<$3>);
+ }
+ // Keep a copy of the return value. The caller is not expected
+ // to free the object that the returned pointer points to.
+ *return_value = obj->$1`'($7);
+ return _CONVERT($3,$4,`(*return_value)');
+',`dnl not keep_return
return _CONVERT($3,$4,`obj->$1`'($7)');
-')dnl
-')dnl
+')dnl end keep_return
+')dnl end refreturn_ctype
+')dnl end void
#ifdef GLIBMM_EXCEPTIONS_ENABLED
}
catch(...)
{
-ifelse($15, `', `dnl
+ifelse($16, `', `dnl
Glib::exception_handlers_invoke`'();
', `dnl
try
{
ifelse($9,refreturn_ctype,`dnl
- return Glib::unwrap_copy`'(obj->$15`'());
+ return Glib::unwrap_copy`'(obj->$16`'());
', `dnl
- return _CONVERT($3, $4, `obj->$15`'()');
+ return _CONVERT($3, $4, `obj->$16`'()');
')dnl
}
catch(...)
@@ -109,7 +127,7 @@ dnl g_assert(base != 0);
if(base && base->$2)
{
ifelse($4,void,,`$4 retval = ')(*base->$2)`'($6);
-ifelse($11,errthrow,`dnl
+ifelse($12,errthrow,`dnl
if(*error)
::Glib::Error::throw_exception(*error);
')dnl
@@ -118,15 +136,15 @@ ifelse($4,void,,` return retval;
}
ifelse($4,void,,`dnl
-ifelse(`$14', `',`dnl
+ifelse(`$15', `',`dnl
typedef $4 RType;
return RType`'();
',`dnl
- return _CONVERT($3,$4,`$14');
+ return _CONVERT($3,$4,`$15');
')dnl
')dnl
}
-ifelse(`$10',,,`#endif // $10
+ifelse(`$11',,,`#endif // $11
')dnl
_POP()')
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index 1b12f4e6..3ae40d5a 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -205,6 +205,9 @@ sub output_wrap_vfunc_cc($$$$$$$$)
my $refreturn_ctype = "";
$refreturn_ctype = "refreturn_ctype" if($$objCFunc{rettype_needs_ref});
+ my $keep_return = "";
+ $keep_return = "keep_return" if($$objCppfunc{keep_return});
+
# Get the conversions.
my $conversions =
convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num);
@@ -212,7 +215,7 @@ sub output_wrap_vfunc_cc($$$$$$$$)
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,%s)dnl\n",
+ my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s,%s,%s)dnl\n",
$$objCppfunc{name},
$cname,
$$objCppfunc{rettype},
@@ -222,6 +225,7 @@ sub output_wrap_vfunc_cc($$$$$$$$)
$conversions,
${$objCFunc->get_param_names()}[0],
$refreturn_ctype,
+ $keep_return,
$ifdef,
$errthrow,
$$objCppfunc{slot_type},
diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm
index dc12eb47..337b4cf6 100644
--- a/tools/pm/WrapParser.pm
+++ b/tools/pm/WrapParser.pm
@@ -1279,6 +1279,7 @@ sub on_wrap_vfunc($)
$argCName = string_unquote($argCName);
my $refreturn = 0;
+ my $keep_return = 0;
my $refreturn_ctype = 0;
my $returnValue = "";
my $exceptionHandler = "";
@@ -1299,6 +1300,12 @@ sub on_wrap_vfunc($)
{
$refreturn = 1;
}
+ # Must a copy of the return value be kept, because the caller does not
+ # get its own copy?
+ elsif($argRef eq "keep_return")
+ {
+ $keep_return = 1;
+ }
elsif($argRef eq "refreturn_ctype")
{
$refreturn_ctype = 1;
@@ -1354,7 +1361,7 @@ sub on_wrap_vfunc($)
}
$self->output_wrap_vfunc($argCppDecl, $argCName, $$self{filename}, $$self{line_num},
- $refreturn, $refreturn_ctype, $custom_vfunc,
+ $refreturn, $keep_return, $refreturn_ctype, $custom_vfunc,
$custom_vfunc_callback, $ifdef, $errthrow,
$slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler);
}
@@ -1570,12 +1577,12 @@ sub output_wrap_signal($$$$$$$$$$$$)
}
# void output_wrap_vfunc($CppDecl, $vfunc_name, $filename, $line_num,
-# $refreturn, $refreturn_ctype,
+# $refreturn, $keep_return, $refreturn_ctype,
# $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow,
# $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler)
-sub output_wrap_vfunc($$$$$$$$$$$$$$)
+sub output_wrap_vfunc($$$$$$$$$$$$$$$$$)
{
- my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype,
+ my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $keep_return, $refreturn_ctype,
$custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow,
$slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler) = @_;
@@ -1608,6 +1615,7 @@ sub output_wrap_vfunc($$$$$$$$$$$$$$)
# These macros are defined in vfunc.m4:
$$objCppVfunc{rettype_needs_ref} = $refreturn;
+ $$objCppVfunc{keep_return} = $keep_return;
$$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.