diff options
author | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2015-03-17 10:19:03 +0100 |
---|---|---|
committer | Kjell Ahlstedt <kjell.ahlstedt@bredband.net> | 2015-03-17 10:19:03 +0100 |
commit | d1f1eca2d3a5044d6b31c4acf49879fda5306fd8 (patch) | |
tree | 90c9f3fc13541d90e629624023c40029d13e3a48 | |
parent | aa9793638c55e1cb62935af4b6587b2078d96585 (diff) | |
download | glibmm-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.h | 11 | ||||
-rw-r--r-- | tools/m4/vfunc.m4 | 54 | ||||
-rw-r--r-- | tools/pm/Output.pm | 6 | ||||
-rw-r--r-- | tools/pm/WrapParser.pm | 16 |
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. |