[glibmm/gmmproc-refactor] Added m4 macros implementations.
- From: Krzesimir Nowak <krnowak src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm/gmmproc-refactor] Added m4 macros implementations.
- Date: Sat, 7 Apr 2012 14:35:55 +0000 (UTC)
commit 84045ff835ad3d3a51a557c0c4cfef054a9ce7a9
Author: Krzesimir Nowak <qdlacz gmail com>
Date: Sat Apr 7 16:23:17 2012 +0200
Added m4 macros implementations.
Some miscellaneous macros are still unwrapped. Also, this code will
need review.
tools/pm/Common/Output.pm | 1089 +---------------------------
tools/pm/Common/Output/BoxedType.pm | 237 ++++++
tools/pm/Common/Output/BoxedTypeStatic.pm | 188 +++++
tools/pm/Common/Output/Ctor.pm | 145 ++++
tools/pm/Common/Output/Enum.pm | 124 ++++
tools/pm/Common/Output/GError.pm | 127 ++++
tools/pm/Common/Output/GObject.pm | 502 +++++++++++++
tools/pm/Common/Output/Generic.pm | 55 ++
tools/pm/Common/Output/Gobject.pm | 461 ------------
tools/pm/Common/Output/GtkObject.pm | 26 +
tools/pm/Common/Output/Interface.pm | 378 ++++++++++
tools/pm/Common/Output/Method.pm | 183 +++++
tools/pm/Common/Output/OpaqueCopyable.pm | 188 +++++
tools/pm/Common/Output/OpaqueRefcounted.pm | 191 +++++
tools/pm/Common/Output/Property.pm | 97 +++
tools/pm/Common/Output/Shared.pm | 548 ++++++++++++++-
tools/pm/Common/Output/Signal.pm | 359 +++++++++
tools/pm/Common/Output/VFunc.pm | 255 +++++++
18 files changed, 3598 insertions(+), 1555 deletions(-)
---
diff --git a/tools/pm/Common/Output.pm b/tools/pm/Common/Output.pm
index e1a5ff0..200061d 100644
--- a/tools/pm/Common/Output.pm
+++ b/tools/pm/Common/Output.pm
@@ -1,6 +1,7 @@
-# Gtkmmproc Output module
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output module
#
-# Copyright 2001 Free Software Foundation
+# Copyright 2012 glibmm development team
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,1076 +17,22 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
#
-package Output;
-use strict;
-use open IO => ":utf8";
-
-BEGIN { @Namespace::ISA=qw(main); }
-
-# $objOutputter new()
-sub new
-{
- my ($m4path, $macrodirs) = @_;
- my $self = {};
- bless $self;
-
- $$self{out} = [];
-
- $$self{source} = "";
- $$self{tmpdir} = File::Spec->tmpdir();
- $$self{destdir} = "";
- $$self{objDefsParser} = undef; # It will be set in set_defsparser()
-
- $$self{m4path} = $m4path;
- $$self{m4args} = "-I";
- $$self{m4args} .= join(" -I", @$macrodirs);
-
- return $self;
-}
-
-sub set_defsparser($$)
-{
- my ($self, $objDefsParser) = @_;
-
- $$self{objDefsParser} = $objDefsParser; #Remember it so that we can use it in our output methods.
-}
-
-sub m4args_append($$)
-{
- my ($self, $str) = @_;
- $$self{m4args} .= $str;
-}
-
-sub append($$)
-{
- my ($self, $str) = @_;
-
- push(@{$$self{out}}, $str);
-}
-
-# void output_wrap_failed($cname, $error)
-# Puts a comment in the header about the error during code-generation.
-sub output_wrap_failed($$$)
-{
- my ($self, $cname, $error) = @_;
-
- my $str = sprintf("//gtkmmproc error: %s : %s", $cname, $error);
- print STDERR "Output.pm: $cname : $error\n";
- $self->append($str);
-}
-
-sub error
-{
- my $format=shift @_;
- printf STDERR "Output.pm: $format",@_;
-}
-
-sub ifdef($$)
-{
- my ($self, $ifdef) = @_;
- if ($ifdef)
- {
- $self->append("\n#ifdef $ifdef\n");
- }
-}
-
-sub endif($$)
-{
- my ($self, $ifdef) = @_;
- if ($ifdef)
- {
- $self->append("\n#endif // $ifdef\n");
- }
-}
-
-### Convert _WRAP to a virtual
-# _VFUNC_H(signame,rettype,`<cppargs>')
-# _VFUNC_PH(gtkname,crettype,cargs and names)
-# void output_wrap_vfunc_h($filename, $line_num, $objCppfunc, $objCDefsFunc)
-sub output_wrap_vfunc_h($$$$$$)
-{
- my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef) = @_;
-
-#Old code. We removed _VFUNC_H from the .m4 file
-# my $str = sprintf("_VFUNC_H(%s,%s,\`%s\',%s)dnl\n",
-# $$objCppfunc{name},
-# $$objCppfunc{rettype},
-# $objCppfunc->args_types_and_names(),
-# $objCppfunc->get_is_const()
-# );
-# $self->append($str);
-
- my $cppVfuncDecl = "virtual " . $$objCppfunc{rettype} . " " . $$objCppfunc{name} . "(" . $objCppfunc->args_types_and_names() . ")";
- if($objCppfunc->get_is_const())
- {
- $cppVfuncDecl .= " const";
- }
-
- $self->ifdef($ifdef);
- $self->append(" $cppVfuncDecl;\n");
- $self->endif($ifdef);
-
- #The default callback, which will call *_vfunc, which will then call the base default callback.
- #Declares the callback in the private *Class class and sets it in the class_init function.
-
- my $str = sprintf("_VFUNC_PH(%s,%s,\`%s\',%s)dnl\n",
- $$objCDefsFunc{name},
- $$objCDefsFunc{rettype},
- $objCDefsFunc->args_types_and_names(),
- $ifdef
- );
- $self->append($str);
-}
-
-# _VFUNC_CC(signame,gtkname,rettype,crettype,`<cppargs>',`<cargs>')
-sub output_wrap_vfunc_cc($$$$$$$)
-{
- my ($self, $filename, $line_num, $objCppfunc, $objCFunc,
- $custom_vfunc, $custom_vfunc_callback, $ifdef) = @_;
-
- my $cname = $$objCFunc{name};
-
- # e.g. Gtk::Button::draw_indicator:
-
- #Use a different macro for Interfaces, to generate an extra convenience method.
-
- if (!$custom_vfunc)
- {
- my $refreturn = "";
- $refreturn = "refreturn" if($$objCppfunc{rettype_needs_ref});
-
- my $str = sprintf("_VFUNC_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s)dnl\n",
- $$objCppfunc{name},
- $cname,
- $$objCppfunc{rettype},
- $$objCFunc{rettype},
- $objCppfunc->args_types_and_names(),
- convert_args_cpp_to_c($objCppfunc, $objCFunc, 0, $line_num), #$objCppfunc->args_names_only(),
- $objCppfunc->get_is_const(),
- $refreturn,
- $ifdef);
-
- $self->append($str);
- }
-
- # e.g. Gtk::ButtonClass::draw_indicator():
-
- if (!$custom_vfunc_callback)
- {
- 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)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),
- ${$objCFunc->get_param_names()}[0],
- $refreturn_ctype,
- $ifdef);
-
- $self->append($str);
- }
-}
-
-### Convert _WRAP to a signal
-# _SIGNAL_H(signame,rettype, ifdef, `<cppargs>')
-# _SIGNAL_PH(gtkname,crettype, ifdef, cargs and names)
-# void output_wrap_default_signal_handler_h($filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef. @args)
-sub output_wrap_default_signal_handler_h($$$$$$$)
-{
- my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $ifdef) = @_;
-
- my $str = sprintf("_SIGNAL_H(%s,%s,\`%s\',%s)dnl\n",
- $$objCppfunc{name},
- $$objCppfunc{rettype},
- $objCppfunc->args_types_and_names(),
- $ifdef
- );
- $self->append($str);
-
-
- #The default callback, which will call *_impl, which will then call the base default callback.
- #Declares the callback in the private *Class class and sets it in the class_init function.
-
- $str = sprintf("_SIGNAL_PH(%s,%s,\`%s\',%s)dnl\n",
- $$objCDefsFunc{name},
- $$objCDefsFunc{rettype},
- $objCDefsFunc->args_types_and_names(),
- $ifdef
- );
- $self->append($str);
-}
-
-# _SIGNAL_CC(signame, gtkname, rettype, crettype,`<cppargs>',`<cargs>')
-sub output_wrap_default_signal_handler_cc($$$$$$$$$)
-{
- my ($self, $filename, $line_num, $objCppfunc, $objDefsSignal, $bImplement, $bCustomCCallback, $bRefreturn, $ifdef) = @_;
- my $cname = $$objDefsSignal{name};
- # $cname = $1 if ($args[3] =~ /"(.*)"/); #TODO: What's this about?
-
- # e.g. Gtk::Button::on_clicked:
- if($bImplement eq 1)
- {
- my $refreturn = "";
- $refreturn = "refreturn" if($bRefreturn eq 1);
-
- my $str = sprintf("_SIGNAL_CC(%s,%s,%s,%s,\`%s\',\`%s\',%s,%s,%s)dnl\n",
- $$objCppfunc{name},
- $cname,
- $$objCppfunc{rettype},
- $$objDefsSignal{rettype},
- $objCppfunc->args_types_and_names(),
- convert_args_cpp_to_c($objCppfunc, $objDefsSignal, 0, $line_num), #$objCppfunc->args_names_only(),
- $$objCppfunc{const},
- $refreturn,
- $ifdef);
- $self->append($str);
- }
-
-
- # e.g. Gtk::ButtonClass::on_clicked():
-
- #Callbacks always take the object instance as the first argument:
-# my $arglist_names = "object";
-# my $arglist_names_extra = $objDefsSignal->args_names_only();
-# if ($arglist_names_extra)
-# {
-# $arglist_names .= ", ";
-# $arglist_names .= $arglist_names_extra;
-# }
-
- if($bCustomCCallback ne 1)
- {
- my $str = sprintf("_SIGNAL_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',%s)dnl\n",
- $$objCppfunc{name},
- $cname,
- $$objCppfunc{rettype},
- $$objDefsSignal{rettype},
- $objDefsSignal->args_types_and_names(),
- $objDefsSignal->args_names_only(),
- convert_args_c_to_cpp($objDefsSignal, $objCppfunc, $line_num),
- ${$objDefsSignal->get_param_names()}[0],
- $ifdef);
- $self->append($str);
- }
-}
-
-### Convert _WRAP to a method
-# _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
-# void output_wrap_meth($filename, $line_num, $objCppFunc, $objCDefsFunc, $cppMethodDecl, $documentation, $ifdef)
-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
- # deprecation docs to the generated documentation.
- my $deprecated = "";
- if($$objCDefsFunc{deprecated})
- {
- $deprecated = "deprecated";
- }
-
- #Declaration:
- if($deprecated ne "")
- {
- $self->append("\n_DEPRECATE_IFDEF_START");
- }
-
- if($arg_list == 0)
- {
- # Doxygen documentation before the method declaration:
- $self->output_wrap_meth_docs_only($filename, $line_num, $documentation);
- }
- else
- {
- $self->append("\n\n /// A $$objCppfunc{name}() convenience overload.\n");
- }
-
- $self->ifdef($ifdef);
-
- $self->append(" " . $objCppfunc->get_declaration($arg_list));
-
- $self->endif($ifdef);
-
-
- if($deprecated ne "")
- {
- $self->append("\n_DEPRECATE_IFDEF_END\n");
- }
-
- my $refneeded = "";
- if($$objCDefsFunc{rettype_needs_ref})
- {
- $refneeded = "refreturn"
- }
-
- my $errthrow = "";
- if($$objCDefsFunc{throw_any_errors})
- {
- $errthrow = "errthrow"
- }
-
- my $constversion = ""; #Whether it is just a const overload (so it can reuse code)
- if($$objCDefsFunc{constversion})
- {
- $constversion = "constversion"
- }
-
- #Implementation:
- my $str;
- if ($$objCppfunc{static}) {
- $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},
- $objCDefsFunc->get_return_type_for_methods(),
- $objCppfunc->args_types_and_names($arg_list),
- convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 1, $line_num,
- $errthrow, $arg_list), #1 means it's static, so it has 'object'.
- $refneeded,
- $errthrow,
- $deprecated,
- $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,%s,%s,%s)dnl\n",
- $$objCppfunc{name},
- $$objCDefsFunc{c_name},
- $$objCppfunc{rettype},
- $objCDefsFunc->get_return_type_for_methods(),
- $objCppfunc->args_types_and_names($arg_list),
- convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 0, $line_num,
- $errthrow, $arg_list),
- $$objCppfunc{const},
- $refneeded,
- $errthrow,
- $deprecated,
- $constversion,
- $objCppfunc->args_names_only($arg_list),
- $ifdef,
- $output_var_name,
- $output_var_type,
- $line_num
- );
- }
- $self->append($str);
- }
-}
-
-### Convert _WRAP to a method
-# _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
-# void output_wrap_meth($filename, $line_num, $documentation)
-sub output_wrap_meth_docs_only($$$$)
-{
- my ($self, $filename, $line_num, $documentation) = @_;
- my $objDefsParser = $$self{objDefsParser};
-
- # Doxygen documentation before the method declaration:
- $self->append("\n${documentation}");
-}
-
-### Convert _WRAP_CTOR to a ctor
-# _METHOD(cppname,cname,cpprettype,crettype,arglist,cargs,const)
-# void output_wrap_ctor($filename, $line_num, $objCppFunc, $objCDefsFunc, $cppMethodDecl)
-sub output_wrap_ctor($$$$$)
-{
- my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $cppMethodDecl) = @_;
- my $objDefsParser = $$self{objDefsParser};
-
- my $num_args_list = $objCppfunc->get_num_possible_args_list();
-
- for(my $arg_list = 0; $arg_list < $num_args_list; $arg_list++)
- {
- if ($arg_list > 0)
- {
- $self->append("\n\n /// A $$objCppfunc{name}() convenience overload.\n");
- }
-
- #Ctor Declaration:
- #TODO: Add explicit.
- $self->append(" explicit " . $objCppfunc->get_declaration($arg_list) . "\n");
-
- #Implementation:
- my $str = sprintf("_CTOR_IMPL(%s,%s,\`%s\',\`%s\')dnl\n",
- $$objCppfunc{name},
- $$objCDefsFunc{c_name},
- $objCppfunc->args_types_and_names($arg_list),
- get_ctor_properties($objCppfunc, $objCDefsFunc, $line_num, $arg_list)
- );
-
- $self->append($str);
- }
-}
-
-sub output_wrap_create($$$)
-{
- my ($self, $args_type_and_name_with_default_values, $objWrapParser) = @_;
-
- #Re-use Function in a very hacky way, to separate the argument types_and_names.
- my $fake_decl = "void fake_func(" . $args_type_and_name_with_default_values . ")";
-
- my $objFunction = &Function::new($fake_decl, $objWrapParser);
-
- my $num_args_list = $objFunction->get_num_possible_args_list();
-
- for(my $arg_list = 0; $arg_list < $num_args_list; $arg_list++)
- {
- my $args_names_only = $objFunction->args_names_only($arg_list);
- my $args_type_and_name_hpp =
- $objFunction->args_types_and_names_with_default_values($arg_list);
- my $args_type_and_name_cpp = $objFunction->args_types_and_names($arg_list);
-
- if ($arg_list > 0) {
- $self->append("\n /// A create() convenience overload.");
- }
-
- my $str = sprintf("_CREATE_METHOD(\`%s\',\`%s\',\`%s\')dnl\n",
- $args_type_and_name_hpp, , $args_type_and_name_cpp, $args_names_only);
-
- $self->append($str)
- }
-}
-
-# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback)
-# custom_signalproxy_name is "" when no type conversion is required - a normal templates SignalProxy will be used instead.
-sub output_wrap_sig_decl($$$$$$$$)
-{
- my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $merge_doxycomment_with_previous) = @_;
-
-# _SIGNAL_PROXY(c_signal_name, c_return_type, `<c_arg_types_and_names>',
-# cpp_signal_name, cpp_return_type, `<cpp_arg_types>',`<c_args_to_cpp>',
-# refdoc_comment)
-
- my $doxycomment = $objCppfunc->get_refdoc_comment();
-
- # If there was already a previous doxygen comment, we want to merge this
- # one with the previous so it is one big comment. If it were two separate
- # comments, doxygen would ignore the first one. If
- # $merge_doxycomment_with_previous is nonzero, the first comment is
- # already open but not yet closed.
- if($merge_doxycomment_with_previous)
- {
- # Strip leading whitespace
- $doxycomment =~ s/^\s+//;
- # We don't have something to add, so just close the comment.
- if($doxycomment eq "")
- {
- $doxycomment = " */";
- }
- else
- {
- # Append the new comment, but remove the first three leading characters
- # (which are /**) that mark the beginning of the comment.
- $doxycomment = substr($doxycomment, 3);
- $doxycomment =~ s/^\s+//;
- $doxycomment = " " . $doxycomment;
- }
- }
-
- my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',\`%s\',%s)dnl\n",
- $signal_name,
- $$objCSignal{rettype},
- $objCSignal->args_types_and_names_without_object(),
- $$objCppfunc{name},
- $$objCppfunc{rettype},
- $objCppfunc->args_types_only(),
- convert_args_c_to_cpp($objCSignal, $objCppfunc, $line_num),
- $bCustomCCallback, #When this is true, it will not write the *_callback implementation for you.
- $doxycomment,
- $ifdef
- );
-
- $self->append($str);
-}
-
-# void output_wrap_enum($filename, $line_num, $cpp_type, $c_type, $comment, @flags)
-sub output_wrap_enum($$$$$$$)
-{
- my ($self, $filename, $line_num, $cpp_type, $c_type, $comment, @flags) = @_;
-
- my $objEnum = GtkDefs::lookup_enum($c_type);
- if(!$objEnum)
- {
- $self->output_wrap_failed($c_type, "enum defs lookup failed.");
- return;
- }
-
- $objEnum->beautify_values();
-
- my $no_gtype = "";
- my $elements = $objEnum->build_element_list(\ flags, \$no_gtype, " ");
-
- if(!$elements)
- {
- $self->output_wrap_failed($c_type, "unknown _WRAP_ENUM() flag");
- return;
- }
-
- my $value_suffix = "Enum";
- $value_suffix = "Flags" if($$objEnum{flags});
-
- my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\')dnl\n",
- $cpp_type,
- $c_type,
- $value_suffix,
- $elements,
- $no_gtype,
- $comment
- );
-
- $self->append($str);
-}
-
-# void output_wrap_gerror($filename, $line_num, $cpp_type, $c_enum, $domain, @flags)
-sub output_wrap_gerror($$$$$$$)
-{
- my ($self, $filename, $line_num, $cpp_type, $c_enum, $domain, @flags) = @_;
-
- my $objDefsParser = $$self{objDefsParser};
-
- my $objEnum = GtkDefs::lookup_enum($c_enum);
- if(!$objEnum)
- {
- $self->output_wrap_failed($c_enum, "enum defs lookup failed.");
- return;
- }
-
- # Shouldn't happen, and if it does, I'd like to know that.
- warn if($$objEnum{flags});
-
- $objEnum->beautify_values();
-
- # cut off the module prefix, e.g. GDK_
- my $prefix = $domain;
- $prefix =~ s/^[^_]+_//;
-
- # Chop off the domain prefix, because we put the enum into the class.
- unshift(@flags, "s#^${prefix}_##");
- my $no_gtype = "";
- my $elements = $objEnum->build_element_list(\ flags, \$no_gtype, " ");
+package Common::Output;
- my $str = sprintf("_GERROR(%s,%s,%s,\`%s\',%s)dnl\n",
- $cpp_type,
- $c_enum,
- $domain,
- $elements,
- $no_gtype
- );
-
- $self->append($str);
-}
-
-# _PROPERTY_PROXY(name, cpp_type)
-# void output_wrap_property($filename, $line_num, $name, $cpp_type)
-sub output_wrap_property($$$$$$)
-{
- my ($self, $filename, $line_num, $name, $cpp_type, $c_class) = @_;
-
- my $objDefsParser = $$self{objDefsParser};
-
- my $objProperty = GtkDefs::lookup_property($c_class, $name);
- if($objProperty eq 0) #If the lookup failed:
- {
- $self->output_wrap_failed($name, "property defs lookup failed.");
- }
- else
- {
- # We use a suffix to specify a particular Glib::PropertyProxy* class.
- my $proxy_suffix = "";
-
- # Read/Write:
- if($objProperty->get_construct_only() eq 1)
- {
- # construct-only functions can be read, but not written.
- $proxy_suffix = "_ReadOnly";
-
- if($objProperty->get_readable() ne 1)
- {
- $self->output_wrap_failed($name, "attempt to wrap write-only and construct-only property.");
- return;
- }
- }
- elsif($objProperty->get_readable() ne 1)
- {
- $proxy_suffix = "_WriteOnly";
- }
- elsif($objProperty->get_writable() ne 1)
- {
- $proxy_suffix = "_ReadOnly";
- }
-
- # Convert - to _ so we can use it in C++ method and variable names:
- my $name_underscored = $name;
- $name_underscored =~ tr/-/_/;
-
- # Get the property documentation, if any, and add m4 quotes.
- my $documentation = $objProperty->get_docs();
- add_m4_quotes(\$documentation) if ($documentation ne "");
-
- my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,`%s')dnl\n",
- $name,
- $name_underscored,
- $cpp_type,
- $proxy_suffix,
- $documentation
- );
- $self->append($str);
- $self->append("\n");
-
- # If the property is not already read-only, and the property can be read,
- # then add a second const accessor for a read-only propertyproxy:
- if( ($proxy_suffix ne "_ReadOnly") && ($objProperty->get_readable()) )
- {
- my $str = sprintf("_PROPERTY_PROXY(%s,%s,%s,%s,`%s')dnl\n",
- $name,
- $name_underscored,
- $cpp_type,
- "_ReadOnly",
- $documentation
- );
- $self->append($str);
- }
- }
-}
-
-sub add_m4_quotes($)
-{
- my ($text) = @_;
-
- # __BT__ and __FT__ are M4 macros defined in the base.m4 file that produce
- # a "`" and a "'" resp. without M4 errors.
- my %m4_quotes = (
- "`" => "'__BT__`",
- "'" => "'__FT__`",
- );
-
- $$text =~ s/([`'])/$m4_quotes{$1}/g;
- $$text = "`" . $$text . "'";
-}
-
-# vpod output_temp_g1($filename, $section) e.g. output_temp_g1(button, gtk)
-sub output_temp_g1($$)
-{
- my ($self, $section) = @_;
-
- # Write out *.g1 temporary file
- open(FILE, '>', "$$self{tmpdir}/gtkmmproc_$$.g1"); # $$ is the Process ID
-
- print FILE "include(base.m4)dnl\n";
-
- my $module = $section;
- my $module_canonical = Util::string_canonical($module); #In case there is a / character in the module.
- print FILE "_START($$self{source},$module,$module_canonical)dnl\n";
- print FILE join("", @{$$self{out}});
- print FILE "_END()\n";
- close(FILE);
-}
-
-sub make_g2_from_g1($)
-{
- my ($self) = @_;
-
- # Execute m4 to get *.g2 file:
- system("$$self{m4path} $$self{m4args} \"$$self{tmpdir}/gtkmmproc_$$.g1\" > \"$$self{tmpdir}/gtkmmproc_$$.g2\""); #"
- return ($? >> 8);
-}
-
-# void write_sections_to_files()
-# This is where we snip the /tmp/gtkmmproc*.g2 file into sections (,h, .cc, _private.h)
-sub write_sections_to_files()
-{
- my ($self) = @_;
-
- my $fname_h = "$$self{destdir}/$$self{source}.h";
- my $fname_ph = "$$self{destdir}/private/$$self{source}_p.h";
- my $fname_cc = "$$self{destdir}/$$self{source}.cc";
-
- open(INPUT, '<', "$$self{tmpdir}/gtkmmproc_$$.g2"); # $$ is the process ID.
-
- # open temporary file for each section
- open(OUTPUT_H, '>', "$fname_h.tmp");
- open(OUTPUT_PH, '>', "$fname_ph.tmp");
- open(OUTPUT_CC, '>', "$fname_cc.tmp");
-
- my $oldfh = select(OUTPUT_H);
- my $blank = 0;
-
- while(<INPUT>)
- {
- # section switching
- if(/^#S 0/) { select(OUTPUT_H); next; }
- if(/^#S 1/) { select(OUTPUT_PH); next; }
- if(/^#S 2/) { select(OUTPUT_CC); next; }
-
- # get rid of bogus blank lines
- if(/^\s*$/) { ++$blank; } else { $blank = 0; }
- next if($blank > 2);
-
- print $_;
- }
-
- select($oldfh);
- close(INPUT);
- close(OUTPUT_H);
- close(OUTPUT_PH);
- close(OUTPUT_CC);
-
- foreach($fname_h, $fname_ph, $fname_cc)
- {
- # overwrite the source file only if it has actually changed
-
- # Win32 does fail at this, so we do the two steps separately:
- #system("cmp -s '$_.tmp' '$_' || cp '$_.tmp' '$_'" ; rm -f '$_.tmp');
-
- system("cmp -s '$_.tmp' '$_' || cp '$_.tmp' '$_'");
- system("rm -f '$_.tmp'");
- }
-}
-
-
-sub remove_temp_files($)
-{
- my ($self) = @_;
-
- system("rm -f \"$$self{tmpdir}/gtkmmproc_$$.g1\"");#"
- system("rm -f \"$$self{tmpdir}/gtkmmproc_$$.g2\"");#"
-}
-
-
-
-# procedure for generating CONVERT macros
-# $string convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, $static, $wrap_line_number,$automatic_error, $index = 0)
-# The optional index specifies which arg list out of the possible combination
-# of arguments based on whether any arguments are optional. index = 0 ==> all
-# the arguments.
-sub convert_args_cpp_to_c($$$$$)
-{
- my ($objCppfunc, $objCDefsFunc, $static, $wrap_line_number, $automatic_error, $index) = @_;
-
- $automatic_error = "" unless defined $automatic_error;
- $index = 0 unless defined $index;
-
- my $cpp_param_names = $$objCppfunc{param_names};
- my $cpp_param_types = $$objCppfunc{param_types};
- my $cpp_param_optional = $$objCppfunc{param_optional};
- my $cpp_param_mappings = $$objCppfunc{param_mappings};
- my $c_param_types = $$objCDefsFunc{param_types};
- my $c_param_names = $$objCDefsFunc{param_names};
-
- my @result;
-
- my $num_c_args_expected = scalar(@{$c_param_types});
- if( !($static) ) { $num_c_args_expected--; } #The cpp method will need an Object* paramater at the start.
-
- 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) &&
- ${$c_param_types}[-1] eq "GError**" )
- {
- $num_cpp_args++;
- $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.
- # 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 )
- {
- Output::error( "convert_args_cpp_to_c(): Incorrect number of arguments. (%d != %d)\n",
- $num_cpp_args,
- $num_c_args_expected );
- $objCppfunc->dump();
- $objCDefsFunc->dump();
-
- 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];
-
- # Loop through the parameters:
- my $i;
- my $cpp_param_max = $num_cpp_args;
- # if( !($static) ) { $cpp_param_max++; }
-
- 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}));
-
- my $cppParamType = $$cpp_param_types[$cpp_param_index];
- $cppParamType =~ s/ &/&/g; #Remove space between type and &
- $cppParamType =~ s/ \*/*/g; #Remove space between type and *
-
- my $cppParamName = $$cpp_param_names[$cpp_param_index];
- my $cParamType = $$c_param_types[$iCParam];
-
- if(!($possible_arg_list =~ /\b$cpp_param_index\b/))
- {
- # If the C++ index is not found in the list of desired parameters, pass
- # NULL to the C func unless the param is not optional (applies to a
- # possibly added GError parameter).
- if ($$cpp_param_optional[$cpp_param_index])
- {
- push(@result, "0");
- next;
- }
- }
-
- if ($cppParamType ne $cParamType) #If a type conversion is needed.
- {
-
-
- push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
- $cppParamType,
- $cParamType,
- $cppParamName,
- $wrap_line_number) );
- }
- else
- {
- push(@result, $cppParamName);
- }
- }
-
- return join(", ", @result);
-}
-
-# procedure for generating CONVERT macros
-# Ignores the first C 'self' argument.
-# $string convert_args_c_to_cpp($objCDefsFunc, $objCppFunc, $wrap_line_number)
-sub convert_args_c_to_cpp($$$)
-{
- my ($objCDefsFunc, $objCppfunc, $wrap_line_number) = @_;
-
- my $cpp_param_types = $$objCppfunc{param_types};
- my $c_param_types = $$objCDefsFunc{param_types};
- my $c_param_names = $$objCDefsFunc{param_names};
-
- my @result;
-
- my $num_c_args = scalar(@{$c_param_types});
-
- my $num_cpp_args = scalar(@{$cpp_param_types});
-
- if ( ($num_cpp_args + 1) != $num_c_args )
- {
- Output::error( "convert_args_c_to_cpp(): Incorrect number of arguments. (%d != %d)\n",
- $num_cpp_args + 1,
- $num_c_args);
- $objCppfunc->dump();
- $objCDefsFunc->dump();
-
- return "";
- }
-
-
- # Loop through the c parameters:
- my $i;
- my $c_param_max = $num_c_args;
-
- for ($i = 1; $i < $c_param_max; $i++)
- {
- #index of C parameter:
- my $iCppParam = $i - 1;
-
- my $cppParamType = $$cpp_param_types[$iCppParam];
- $cppParamType =~ s/ &/&/g; #Remove space between type and &.
- $cppParamType =~ s/ \*/*/g; #Remove space between type and *
-
- my $cParamName = $$c_param_names[$i];
- my $cParamType = $$c_param_types[$i];
-
- 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
- {
- push(@result, $cParamName);
- }
- }
-
- return join(", ",@result);
-}
-
-
-# generates the XXX in g_object_new(get_type(), XXX): A list of property names and values.
-# Uses the cpp arg name as the property name.
-# The optional index specifies which arg list out of the possible combination
-# of arguments based on whether any arguments are optional. index = 0 ==> all
-# the arguments.
-# $string get_ctor_properties($objCppfunc, $objCDefsFunc, $wrap_line_number, $index = 0)
-sub get_ctor_properties($$$$$)
-{
- my ($objCppfunc, $objCDefsFunc, $wrap_line_number, $index) = @_;
-
- $index = 0 unless defined $index;
-
- my $cpp_param_names = $$objCppfunc{param_names};
- my $cpp_param_types = $$objCppfunc{param_types};
- my $cpp_param_optional = $$objCppfunc{param_optional};
- my $cpp_param_mappings = $$objCppfunc{param_mappings};
- my $c_param_types = $$objCDefsFunc{param_types};
- my $c_param_names = $$objCDefsFunc{param_names};
-
- my @result;
-
- my $num_args = scalar(@{$c_param_types});
-
- my $num_cpp_args = scalar(@{$cpp_param_types});
- if ( $num_cpp_args != $num_args )
- {
- Output::error("get_ctor_properties(): Incorrect number of arguments. (%d != %d)\n",
- $num_cpp_args,
- $num_args );
- return "";
- }
-
-
- # Get the desired argument list combination.
- my $possible_arg_list = $$objCppfunc{possible_args_list}[$index];
-
- # Loop through the parameters:
- my $i = 0;
-
- for ($i = 0; $i < $num_args; $i++)
- {
- my $c_param_name = @$c_param_names[$i];
- my $cpp_param_index = $i;
- $cpp_param_index = $$cpp_param_mappings{$c_param_name} if(defined($$cpp_param_mappings{$c_param_name}));
-
- my $cppParamType = $$cpp_param_types[$cpp_param_index];
- $cppParamType =~ s/ &/&/g; #Remove space between type and &
- $cppParamType =~ s/ \*/*/g; #Remove space between type and *
-
- my $cppParamName = $$cpp_param_names[$cpp_param_index];
- my $cParamType = $$c_param_types[$i];
-
- # Property name:
- push(@result, "\"" . $cppParamName . "\"");
-
- if(!($possible_arg_list =~ /\b$cpp_param_index\b/))
- {
- # If the C++ index is not found in the list of desired parameters, pass
- # NULL to the C func unless the param is not optional.
- if ($$cpp_param_optional[$cpp_param_index])
- {
- push(@result, "0");
- next;
- }
- }
-
- # C property value:
- if ($cppParamType ne $cParamType) #If a type conversion is needed.
- {
- push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
- $cppParamType,
- $cParamType,
- $cppParamName,
- $wrap_line_number) );
- }
- else
- {
- push(@result, $cppParamName);
- }
- }
-
- return join(", ", @result);
-}
-
-### Convert _WRAP to a corba method
-# _CORBA_METHOD(retype, method_name,args, arg_names_only) - implemented in libbonobomm.
-# void output_wrap_corba_method($filename, $line_num, $objCppFunc)
-sub output_wrap_corba_method($$$$)
-{
- my ($self, $filename, $line_num, $objCppfunc) = @_;
-
- my $str = sprintf("_CORBA_METHOD(%s,%s,\`%s\',\`%s\')dnl\n",
- $$objCppfunc{rettype},
- $$objCppfunc{name},
- $objCppfunc->args_types_and_names(),
- $objCppfunc->args_names_only()
- );
-
- $self->append($str);
-}
-
-sub output_implements_interface($$)
-{
- my ($self, $interface, $ifdef) = @_;
-
- my $str = sprintf("_IMPLEMENTS_INTERFACE_CC(%s, %s)dnl\n",
- $interface,
- $ifdef);
-
- $self->append($str);
-}
+use strict;
+use warnings;
+
+use Common::Output::BoxedTypeStatic;
+use Common::Output::BoxedType;
+use Common::Output::Enum;
+use Common::Output::Generic;
+use Common::Output::GError;
+use Common::Output::GObject;
+use Common::Output::GtkObject;
+use Common::Output::Interface;
+use Common::Output::OpaqueCopyable;
+use Common::Output::OpaqueRefcounted;
+use Common::Output::VFunc;
1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/BoxedType.pm b/tools/pm/Common/Output/BoxedType.pm
new file mode 100644
index 0000000..cefa3ee
--- /dev/null
+++ b/tools/pm/Common/Output/BoxedType.pm
@@ -0,0 +1,237 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::BoxedType module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::BoxedType;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_before_first_namespace ($$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_STRUCT_PROTOTYPE;
+ my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ my $code_string = nl (Common::Output::Shared::doxy_skip_begin) .
+ nl ('extern "C" { typedef struct _' . $c_type . ' ' . $c_type . '; }') .
+ nl (Common::Output::Shared::doxy_skip_end);
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_BEFORE_FIRST_NAMESPACE;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional_to_section ($conditional, $section);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+}
+
+sub _output_h_in_class ($$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $code_string = nl ('public:') .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' typedef ' . $cpp_type . 'CppObjectType;') .
+ nl (' typedef ' . $c_type . 'BaseObjectType;') .
+ nl () .
+ nl ( 'static GType get_type() G_GNUC_CONST;') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl ();
+
+ $section_manager->push_section ($main_section);
+ $section_manager->append_string ($code_string);
+
+ my $conditional = Common::Output::Shared::default_ctor_proto $wrap_parser, $cpp_type;
+ my $copy_proto = 'const';
+ my $reinterpret = 0;
+ my $definitions = 1;
+ my $virtual_dtor = 0;
+
+ $section_manager->append_conditional ($conditional);
+ $code_string = nl () .
+ nl ('explicit ' . $cpp_type . '(' . $c_type . '* gobject, bool make_a_copy = true);') .
+ nl () .
+ nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+ nl () .
+ nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+ nl () .
+ nl (' void swap(' . $cpp_type . '& other);') .
+ nl () .
+ nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+ nl () .
+ nl ('protected:') .
+ nl (' ' . $c_type . '* gobject_;') .
+ nl () .
+ nl ('private:');
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_h_after_first_namespace ($$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+ my $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl () .
+ nl ('/** @relates ' . $full_cpp_type) .
+ nl (' *') .
+ nl (' * @param lhs The left-hand side') .
+ nl (' * @param rhs The right-hand side') .
+ nl (' */') .
+ nl ('inline void swap(' . $cpp_type . '& lhs, ' . $cpp_type . '& rhs)') .
+ nl ('{ lhs.swap(rhs); }') .
+ nl () .
+ nl (Common::Output::Shared::close_namespaces $wrap_parser) .
+ nl () .
+ nl ('namespace Glib') .
+ nl ('{') .
+ nl ();
+
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+
+ my $result_type = 'plain';
+ my $take_copy_by_default = 'no';
+ my $open_glib_namespace = 0;
+ my $const_function = 0;
+ my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+
+ $section_manager->append_conditional ($conditional);
+ $code_string = nl (Common::Output::Shared::doxy_skip_begin) .
+ nl ('template <>') .
+ nl ('class Value< ' . $full_cpp_type . ' > : public Glib::Value_Boxed< ' . $full_cpp_type . ' >') .
+ nl ('{};') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl ('} // namespace Glib');
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$$$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $get_type_func, $new_func, $copy_func, $free_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $prefix = Common::Output::Shared::get_var_prefix $wrap_parser;
+ my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+ my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $code_string = nl ('namespace Glib') .
+ nl ('{') .
+ nl () .
+ nl ($full_cpp_type . ' wrap(' . $c_type . '* object, bool take_copy)') .
+ nl ('{') .
+ nl (' return ' . $full_cpp_type . '(object, take_copy);') .
+ nl ('}') .
+ nl () .
+ nl ('} // namespace Glib') .
+ nl ();
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->push_section ($section);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+ $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl ('// static') .
+ nl ('GType ' . $cpp_type . '::get_type()') .
+ nl ('{') .
+ nl (' return ' . $get_type_func . '();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+ $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ $code_string = nl($cpp_type . '::' . $cpp_type . '()') .
+ nl(':');
+ if (defined $new_func and $new_func != '' and $new_func != 'NONE')
+ {
+ $code_string += nl ('gobject_ (' . $new_func . '())');
+ }
+ else
+ {
+ $code_string += nl ('gobject_ (0) // Allows creation of invalid wrapper, e.g. for output arguments to methods.');
+ }
+ $code_string += nl ('{}');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+ $code_string = nl ($cpp_type . '::' . $cpp_type . '(const ' . $cpp_type . '& other)') .
+ nl (':') .
+ nl (' gobject_ ((other.gobject_) ? ' . $copy_func . '(other.gobject_) : 0)') .
+ nl ('{}') .
+ nl () .
+ nl ($cpp_type . '::' . $cpp_type . '(' . $c_type . '* gobject, bool make_a_copy)') .
+ nl (':') .
+ nl ('// For BoxedType wrappers, make_a_copy is true by default. The static') .
+ nl ('// BoxedTyoe wrappers always take a copy, thus make_a_copy = true') .
+ nl ('// ensures identical behaviour if the default argument is used.') .
+ nl (' gobject_ ((make_a_copy && gobject) ? ' . $copy_func . '(gobject) : gobject)') .
+ nl ('{}') .
+ nl () .
+ nl ($cpp_type . '& ' . $cpp_type . '::operator=(const ' . $cpp_type . '& other)') .
+ nl ('{') .
+ nl (' ' . $cpp_type . ' temp (other);') .
+ nl (' swap(temp);') .
+ nl (' return *this;') .
+ nl ('}') .
+ nl () .
+ nl ($cpp_type . '::~' . $cpp_type . '()') .
+ nl ('{') .
+ nl (' if (gobject_)') .
+ nl (' ' . $free_func . '(gobject_);') .
+ nl ('}') .
+ nl () .
+ nl ('void ' . $cpp_type . '::swap(' . $cpp_type . '& other)') .
+ nl ('{') .
+ nl (' ' . $c_type . '* const temp = gobject_;') .
+ nl (' gobject_ = other.gobject_;') .
+ nl (' other.gobject_ = temp;') .
+ nl ('}') .
+ nl () .
+ nl ($c_type . '* ' . $cpp_type . '::gobj_copy() const') .
+ nl ('{') .
+ nl (' return ' . $copy_func . '(gobject_);') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+ $section_manager->append_section ($section);
+ $code_string = nl (Common::Output::Shared::close_namespaces $wrap_parser);
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub output ($)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $get_type_func, $new_func, $copy_func, $free_func) = @_;
+
+ _output_h_before_first_namespace $wrap_parser, $c_type, $cpp_type;
+ _output_h_in_class $wrap_parser, $c_type, $cpp_type;
+ _output_h_after_first_namespace $wrap_parser, $c_type, $cpp_type;
+ _output_cc $wrap_parser, $c_type, $cpp_type, $get_type_func, $new_func, $copy_func, $free_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/BoxedTypeStatic.pm b/tools/pm/Common/Output/BoxedTypeStatic.pm
new file mode 100644
index 0000000..ef9c565
--- /dev/null
+++ b/tools/pm/Common/Output/BoxedTypeStatic.pm
@@ -0,0 +1,188 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::BoxedTypeStatic module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::BoxedTypeStatic;
+
+use strict;
+use warnings;
+
+use Common::Output::Shared;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_in_class ($$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = nl ('public:') .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' typedef ' . $cpp_type . 'CppObjectType;') .
+ nl (' typedef ' . $c_type . 'BaseObjectType;') .
+ nl () .
+ nl (' static GType get_type() G_GNUC_CONST') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl ();
+ my $main_section = $wrap_parser->get_main_section;
+
+ $section_manager->push_section ($main_section);
+ $section_manager->append_string ($code_string);
+
+ my $conditional = Common::Output::Shared::default_ctor_proto $wrap_parser, $cpp_type;
+
+ $section_manager->append_conditional ($conditional);
+
+ my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_CTOR_CAST;
+
+ $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ $code_string = nl (' explicit ' . $cpp_type . '(const ' . $c_type . '* gobject); // always takes a copy');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+ my $copy_proto = 'no';
+ my $reinterpret = 0;
+ my $definitions = 1;
+
+ $code_string = nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+ nl () .
+ nl ('protected:') .
+ nl (' ' . $c_type . ' gobject_;') .
+ nl () .
+ nl ('private:');
+ $section_manager->append_string ($code_string, $main_section);
+ $section_manager->pop_entry;
+}
+
+sub _output_h_after_namespace ($$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = nl ('namespace Glib') .
+ nl ('{');
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+
+ my $result_type = 'ref';
+ my $take_copy_by_default = 'N/A';
+ my $open_glib_namespace = 0;
+ my $const_function = 0;
+ my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+ $section_manager->append_conditional ($conditional);
+ $const_function = 1;
+ $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+ $section_manager->append_conditional ($conditional);
+
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type ($wrap_parser);
+
+ $code_string = nl () .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl ('template <>') .
+ nl ('class Value< ' . $full_cpp_type . ' > : public Glib::Value_Boxed< ' . $full_cpp_type . ' >') .
+ nl ('{};') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl ('} // namespace Glib') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $get_type_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+ my $complete_cpp_type = Common::Output::Shared::get_complete_cpp_type $wrap_parser;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $code_string = nl ('namespace Glib') .
+ nl ('{') .
+ nl () .
+ nl ($complete_cpp_type . '& wrap(' . $c_type . '* object)') .
+ nl ('{') .
+ nl (' return *reinterpret_cast< ' . $complete_cpp_type . '* >(object);') .
+ nl ('}') .
+ nl () .
+ nl ('} // namespace Glib') .
+ nl ();
+ my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->push_section ($section);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+ $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl ('// static') .
+ nl ('GType ' . $full_cpp_type . '::get_type()') .
+ nl ('{') .
+ nl (' return ' . $get_type_func . '();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+ $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ $code_string = nl ($full_cpp_type . '::' . $cpp_type . '()') .
+ nl ('{') .
+ nl (' GLIBMM_INITIALIZE_STRUCT(gobject_, ' . $c_type . ');') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+ $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_CTOR_CAST;
+ $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ $code_string = nl ($full_cpp_type . '::' . $cpp_type . '(const ' . $c_type . '* gobject)') .
+ nl ('{') .
+ nl (' if (gobject)') .
+ nl (' {') .
+ nl (' gobject_ = *gobject;') .
+ nl (' }') .
+ nl (' else') .
+ nl (' {') .
+ nl (' GLIBMM_INITIALIZE_STRUCT(gobject_, ' . $c_type . ');') .
+ nl (' }') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+ $section_manager->append_section ($section);
+ $code_string = nl () .
+ nl (Common::Output::Shared::close_namespaces $wrap_parser);
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub output ($$$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $get_type_func) = @_;
+
+ _output_h_in_class $wrap_parser, $c_type, $cpp_type;
+ _output_h_after_namespace $wrap_parser, $c_type, $cpp_type;
+ _output_cc $wrap_parser, $c_type, $cpp_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Ctor.pm b/tools/pm/Common/Output/Ctor.pm
new file mode 100644
index 0000000..86e3fb6
--- /dev/null
+++ b/tools/pm/Common/Output/Ctor.pm
@@ -0,0 +1,145 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Ctor module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Ctor;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+# TODO: This should be moved to Shared. Here should be a function usable from WrapParser.
+sub initially_unowned_sink ($)
+{
+ my ($wrap_parser) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DERIVES_INITIALLY_UNOWNED;
+ my $code_string = (nl ' if (gobject && g_object_is_floating(gobject_))') .
+ (nl ' {') .
+ (nl ' g_object_ref_sink(gobject_); // Stops it from being floating.') .
+ (nl ' }');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+ return $conditional;
+}
+
+sub ctor_default ($)
+{
+ my ($wrap_parser) = @_;
+ my $cpp_type = Common::Output::Shared::get_cpp_type $wrap_parser;
+
+ unless (defined $cpp_type)
+ {
+# TODO: warn.
+ return;
+ }
+
+ my $code_string = nl $cpp_type, '();';
+ my $main_section = $wrap_parser->get_main_section;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $base_member = (lc $cpp_class_type) . '_';
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+ my $conditional = initially_unowned_sink $wrap_parser;
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+ $code_string = (nl $full_cpp_type, '::', $cpp_type, '()') .
+ (nl ':') .
+ (nl ' // Mark this class as non-derived to allow C++ vfuncs to be skipped.') .
+ (nl ' Glib::ObjectBase(0),') .
+ (nl ' CppParentType(Glib::ConstructParams(', $base_member, '.init()))') .
+ (nl '{');
+# TODO: There is SECTION_CC_INITIALIZE_CLASS_EXTRA imported. Check if it is needed.
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+ $section_manager->append_conditional ($conditional);
+ $code_string = (nl '}') .
+ (nl);
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub wrap_ctor ($$$$)
+{
+ my ($wrap_parser, $c_param_types, $c_param_transfers, $c_prop_names, $cpp_param_types, $cpp_param_names) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $cpp_type = Common::Output::Shared::get_cpp_type $wrap_parser;
+ my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+ my $code_string = (nl 'explicit ', $cpp_type, '(', $cpp_param_str, ');') .
+ (nl);
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $base_member = (lc $cpp_class_type) . '_';
+ my $conditional = initially_unowned_sink $wrap_parser;
+ my $conversions_store = $wrap_parser->get_conversions_store;
+ my $ctor_params_str = '';
+
+ if (@{$cpp_param_types} > 0)
+ {
+ $ctor_params_str = join ', ', '', (map { join, '', '"', $c_prop_names->[$_], '"', $conversions_store->get_conversion ($cpp_param_types->[$_], $c_param_types->[$_], $c_param_transfers->[$_], $cpp_param_names->[$_]) } 0 .. @{$cpp_param_types}), 'static_cast<char*>(0)';
+ }
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+ $code_string = (nl $full_cpp_type, '::', $cpp_type, '(', $cpp_params_str, ')') .
+ (nl ':') .
+ (nl ' // Mark this class as non-derived to allow C++ vfuncs to be skipped.') .
+ (nl ' Glib::ObjectBase(0),') .
+ (nl ' CppParentType(Glib::ConstructParams(', $base_member, '.init()', $ctor_params_str, '))') .
+ (nl '{');
+# TODO: There is SECTION_CC_INITIALIZE_CLASS_EXTRA imported. Check if it is needed.
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+ $section_manager->append_conditional ($conditional);
+ $code_string = (nl '}') .
+ (nl);
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub wrap_create ($$$)
+{
+ my ($wrap_parser, $cpp_param_types, $cpp_param_names) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+ my $cpp_type = Common::Output::Shared::get_cpp_type $wrap_parser;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+ my $cpp_names_str = join ', ', @{$cpp_param_names};
+ my $code_string = (nl 'static Glib::RefPtr< ', $cpp_type, ' > create(', $cpp_params_str, ')');
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+ $code_string = (nl 'Glib::RefPtr< ', $full_cpp_type, ' > ', $full_cpp_type, '::create(', $cpp_params_str, ')') .
+ (nl '{') .
+ (nl ' return Glib::RefPtr< ', $cpp_type, ' >(new ', $cpp_type, '(', $cpp_names_str, '));') .
+ (nl '}') .
+ (nl);
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Enum.pm b/tools/pm/Common/Output/Enum.pm
new file mode 100644
index 0000000..527a2c5
--- /dev/null
+++ b/tools/pm/Common/Output/Enum.pm
@@ -0,0 +1,124 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Enum module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Enum;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_enum ($$$)
+{
+ my ($wrap_parser, $cpp_type, $members) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $string_members = Common::Output::Shared::convert_members_to_strings $members;
+ my $code_string = nl ('enum ' . $cpp_type) .
+ nl ('{') .
+ nl (join ((nl ','), @{$string_members})) .
+ nl ('};') .
+ nl ();
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_flag_ops ($$$)
+{
+ my ($wrap_parser, $cpp_type, $flags) = @_;
+
+ if ($flags)
+ {
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $container_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $full_cpp_type = join '::', $container_cpp_type, $cpp_type;
+ my $code_string .= nl ('inline ' . $full_cpp_type . ' operator|(' . $full_cpp_type . ' lhs, ' . $full_cpp_type . ' rhs)') .
+ nl (' { return static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs)); }') .
+ nl () .
+ nl ('inline ' . $full_cpp_type . ' operator&(' . $full_cpp_type . ' lhs, ' . $full_cpp_type . ' rhs)') .
+ nl (' { return static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs)); }') .
+ nl () .
+ nl ('inline ' . $full_cpp_type . ' operator^(' . $full_cpp_type . ' lhs, ' . $full_cpp_type . ' rhs)') .
+ nl ('{ return static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs)); }') .
+ nl () .
+ nl ('inline ' . $full_cpp_type . ' operator~(' . $full_cpp_type . ' flags)') .
+ nl (' { return static_cast<' . $full_cpp_type . '>(~static_cast<unsigned>(flags)); }') .
+ nl () .
+ nl ('inline ' . $full_cpp_type . '& operator|=(' . $full_cpp_type . '& lhs, ' . $full_cpp_type . ' rhs)') .
+ nl (' { return (lhs = static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs))); }') .
+ nl () .
+ nl ('inline ' . $full_cpp_type . '& operator&=(' . $full_cpp_type . '& lhs, ' . $full_cpp_type . ' rhs)') .
+ nl (' { return (lhs = static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs))); }') .
+ nl () .
+ nl ('inline ' . $full_cpp_type . '& operator^=(' . $full_cpp_type . '& lhs, ' . $full_cpp_type . ' rhs)') .
+ nl (' { return (lhs = static_cast<' . $full_cpp_type . '>(static_cast<unsigned>(lhs) ^ static_cast<unsigned>(rhs))); }') .
+ nl ();
+
+ if ($container_cpp_type)
+ {
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_CLASS;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+ }
+ else
+ {
+ $section_manager->append_string_to_section ($code_string, $wrap_parser->get_main_section);
+ }
+ }
+}
+
+sub _output_gtype_func_h ($$$$)
+{
+ my ($wrap_parser, $cpp_type, $flags, $get_type_func) = @_;
+ my $type = undef;
+
+ if ($flags)
+ {
+ $type = Common::Output::Shared::FLAGS_TYPE;
+ }
+ else
+ {
+ $type = Common::Output::Shared::ENUM_TYPE;
+ }
+
+ Common::Output::Shared::output_enum_gtype_func_h $wrap_parser, $cpp_type, $type, $get_type_func;
+}
+
+sub _output_gtype_func_cc ($$$)
+{
+ my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+ Common::Output::Shared::output_enum_gtype_func_cc $wrap_parser, $cpp_type, $get_type_func;
+}
+
+sub output ($$$$$)
+{
+ my ($wrap_parser, $cpp_type, $members, $flags, $get_type_func) = @_;
+
+ _output_enum $wrap_parser, $cpp_type, $members;
+ _output_flag_ops $wrap_parser, $cpp_type, $flags;
+ _output_gtype_func_h $wrap_parser, $cpp_type, $flags, $get_type_func;
+ _output_gtype_func_cc $wrap_parser, $cpp_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/GError.pm b/tools/pm/Common/Output/GError.pm
new file mode 100644
index 0000000..3dfba0d
--- /dev/null
+++ b/tools/pm/Common/Output/GError.pm
@@ -0,0 +1,127 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::GError module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::GError;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_gerror ($$$)
+{
+ my ($wrap_parser, $cpp_type, $members) = @_;
+ my $string_members = Common::Output::Shared::convert_members_to_strings ($members);
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $namespaces = $wrap_parser->get_namespaces;
+ my $wrap_init = 'wrap_init()';
+
+ if (@{$namespaces})
+ {
+ $wrap_init = '::' . $namespaces->[0] . '::' . $wrap_init;
+ }
+
+ my $code_string = nl ('class ' . $cpp_type . ' : public Glib::Error') .
+ nl ('{') .
+ nl ('public:') .
+ nl (' enum Code') .
+ nl (' {') .
+ nl (join nl (','), @{$string_members}) .
+ nl (' };') .
+ nl () .
+ nl (' ' . $cpp_type . '(Code error_code, const Glib::ustring& error_message);') .
+ nl (' explicit ' . $cpp_type . '(GError* gobject);') .
+ nl (' Code code() const;') .
+ nl () .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl ('private:') .
+ nl () .
+ nl (' static void throw_func(GError* gobject);') .
+ nl () .
+ nl (' friend void ' . $wrap_init . '; // uses throw_func()') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl ('};') .
+ nl ();
+
+ $section_manager->append_string_to_section ($code_string, $wrap_parser->get_main_section);
+}
+
+sub _output_gerror_gtype_h ($$$)
+{
+ my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+ Common::Output::Shared::output_enum_gtype_func_h $wrap_parser, $cpp_type, Common::Output::Shared::ENUM_TYPE, $get_type_func;
+}
+
+sub _output_gerror_impl ($$$)
+{
+ my ($wrap_parser, $cpp_type, $domain) = @_;
+ my $container_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $full_cpp_type = join '::', $container_cpp_type, $cpp_type;
+ my $section_manager->get_section_manager;
+ my $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl ($full_cpp_type . '::' . $cpp_type . '(' . $full_cpp_type . '::Code error_code, const Glib::ustring& error_message)') .
+ nl (':') .
+ nl (' Glib::Error(g_quark_from_static_string ("' . $domain . '"), error_code, error_message)') .
+ nl ('{}') .
+ nl () .
+ nl ($full_cpp_type . '::' . $cpp_type . '(GError* gobject)') .
+ nl (':') .
+ nl (' Glib::Error(gobject)') .
+ nl ('{}') .
+ nl () .
+ nl ($full_cpp_type . '::Code ' . $full_cpp_type . '::code() const') .
+ nl ('{') .
+ nl (' return static_cast<Code>(Glib::Error::code());') .
+ nl ('}') .
+ nl () .
+ nl ('// static') .
+ nl ('void ' . $full_cpp_type . '::throw_func(GError* gobject)') .
+ nl ('{') .
+ nl (' throw ' . $full_cpp_type . '(gobject);') .
+ nl ('}') .
+ nl () .
+ Common::Output::Shared::close_namespaces $wrap_parser;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub _output_gerror_gtype_cc ($$$)
+{
+ my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+ Common::Output::Shared::output_enum_gtype_func_cc ($wrap_parser, $cpp_type, $get_type_func);
+}
+
+sub output ($$$$$)
+{
+ my ($wrap_parser, $cpp_type, $members, $domain, $get_type_func) = @_;
+
+ _output_gerror $wrap_parser, $cpp_type, $members;
+ _output_gerror_gtype_h $wrap_parser, $cpp_type, $get_type_func;
+ _output_gerror_impl $wrap_parser, $cpp_type, $domain;
+ _output_gerror_gtype_cc $wrap_parser, $cpp_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/GObject.pm b/tools/pm/Common/Output/GObject.pm
new file mode 100644
index 0000000..c76f5b8
--- /dev/null
+++ b/tools/pm/Common/Output/GObject.pm
@@ -0,0 +1,502 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::GObject module
+#
+# Copyright 2011, 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::GObject;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_before_namespace ($$$)
+{
+ my ($wrap_parser, $c_type, $c_class_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $subconditional = Common::Output::Shared::struct_prototype $wrap_parser, $c_type, $c_class_type;
+ my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+ my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_BEFORE_FIRST_NAMESPACE;
+
+ $section_manager->append_conditional_to_conditional ($subconditional, $conditional, 0);
+ $section_manager->push_section ($section);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+ my $code_string = Common::Output::Shared::open_namespaces ($wrap_parser) .
+ nl ('class ' . $cpp_class_type . ';') .
+ Common::Output::Shared::close_namespaces ($wrap_parser) .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_h_in_class ($$$$$$)
+{
+ my ($wrap_parser, $c_type, $c_parent_type, $c_class_type, $cpp_type, $cpp_parent_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $code_string = nl (Common::Output::Shared::doxy_skip_begin) .
+ nl () .
+ nl ('public:') .
+ nl (' typedef ' . $cpp_type . ' CppObjectType;') .
+ nl (' typedef ' . $cpp_class_type . ' CppClassType;') .
+ nl (' typedef ' . $cpp_parent_type . ' CppParentType;') .
+ nl (' typedef ' . $c_type . ' BaseObjectType;') .
+ nl (' typedef ' . $c_class_type . ' BaseClassType;') .
+ nl (' typedef ' . $c_parent_type . ' BaseParentType;') .
+ nl ();
+
+ $section_manager->push_section ($main_section);
+ $section_manager->append_string ($code_string);
+
+ my $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::PROTECTED_GCLASS;
+ my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ $code_string = nl ('protected:');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $code_string = nl ('private:');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+ my $virtual_dtor = 1;
+ my $base_member = lc ($cpp_class_type) . '_';
+
+ $code_string = nl (' friend class ' . $cpp_class_type . ';') .
+ nl (' static CppClassType ' . $base_member . '_;') .
+ nl () .
+ nl ('private:') .
+ nl (' // noncopyable') .
+ nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+ nl () .
+ nl ('protected:') .
+ nl (' explicit ' . $cpp_type . '(const Glib::ConstructParams& construct_params);') .
+ nl (' explicit ' . $cpp_type . '(' . $c_type . '* castitem);') .
+ nl () .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl ('public:') .
+ nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+ nl () .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' static GType get_type() G_GNUC_CONST;');
+ $section_manager->append_string ($code_string);
+ $code_string = nl (' static GType get_type(GTypeModule* module) G_GNUC_CONST');
+ $variable = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+ my $copy_proto = 'no';
+ my $reinterpret = 1;
+ my $definitions = 1;
+
+ $code_string = nl (' static GType get_base_type() G_GNUC_CONST;') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+ nl () .
+ nl ('private:');
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_h_after_namespace ($$)
+{
+ my ($wrap_parser, $c_type) = @_;
+ my $result_type = 'refptr';
+ my $take_copy_by_default = 'no';
+ my $open_glib_namespace = 1;
+ my $const_function = 0;
+ my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+ $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_p_h ($$$$$)
+{
+ my ($wrap_parser, $c_type, $c_class_type, $c_parent_class_type, $cpp_parent_type) = @_;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $cpp_parent_class_type = $cpp_parent_type . '::CppClassType';
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = nl ('#include <glibmm/class.h>') .
+ nl () .
+ Common::Output::Shared::open_namespaces ($wrap_parser) .
+ nl () .
+ nl ('class ' . $cpp_class_type . ' : public Glib::Class') .
+ nl ('{') .
+ nl ('public:') .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' typedef ' . $full_cpp_type . ' CppObjectType;') .
+ nl (' typedef ' . $c_type . ' BaseObjectType;');
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_CONTENTS;
+
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+
+ my $do_not_derive_gtype_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DO_NOT_DERIVE_GTYPE;
+ my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ $code_string = nl (' typedef ' . $cpp_parent_class_type . ' CppClassParent;');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $code_string = nl (' typedef ' . $c_class_type . ' BaseClassType;') .
+ nl (' typedef ' . $cpp_parent_class_type . ' CppClassParent;') .
+ nl (' typedef ' . $c_parent_class_type . ' BaseClassParent;');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+ $code_string = nl () .
+ nl (' friend class ' . $full_cpp_type . ';') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl (' const Glib::Class& init();') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+ $code_string = nl (' const Glib::Class& init(GTypeModule* module);');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ $code_string = nl (' static void class_init_function(void* g_class, void* class_data);');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+ $code_string = nl (' static Glib::ObjectBase* wrap_new(GObject*);') .
+ nl () .
+ nl ('protected:');
+ $section_manager->append_string ($code_string);
+
+ my @h_sections =
+ (
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_DEFAULT_SIGNAL_HANDLERS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_VFUNCS)
+ );
+
+ foreach my $h_section (@h_sections)
+ {
+ $section_manager->append_section ($h_section);
+ $section_manager->append_string (nl);
+ }
+
+ $code_string = nl ('};') .
+ nl () .
+ Common::Output::Shared::close_namespaces ($wrap_parser);
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$$$)
+{
+ my ($wrap_parser, $c_type, $c_parent_type, $get_type_func, $cpp_type, $cpp_parent_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $complete_cpp_type = Common::Output::Shared::get_complete_cpp_type $wrap_parser;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $code_string = nl ('namespace Glib') .
+ nl ('{') .
+ nl () .
+ nl ('Glib::RefPtr< ' . $complete_cpp_type . ' > wrap(' . $c_type . '* object, bool take_copy)') .
+ nl ('{') .
+ nl (' return Glib::RefPtr< ' . $complete_cpp_type . ' >(dynamic_cast< ' . $complete_cpp_type . ' >(Glib::wrap_auto (static_cast< GObject* >(object), take_copy)));') .
+ nl (' // We use dynamic_cast<> in case of multiple inheritance.') .
+ nl ('}') .
+ nl () .
+ nl ('} // namespace Glib') .
+ nl ();
+ my $no_wrap_function_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+ my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->push_section ($section);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($no_wrap_function_var, $conditional);
+ $code_string = Common::Output::Shared::open_namespaces ($wrap_parser) .
+ nl ($c_type . '* ' . $full_cpp_type . '::gobj_copy()') .
+ nl ('{') .
+ nl (' reference();') .
+ nl (' return gobj();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ my $custom_ctor_cast_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_CTOR_CAST;
+
+ $code_string = nl ($full_cpp_type . '::' . $cpp_type . '(const Glib::ConstructParams& construct_params)') .
+ nl (':') .
+ nl (' ' . $cpp_parent_type . '(construct_params)') .
+ nl ('{');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+
+ my $subconditional = Common::Output::Ctor::initially_unowned_sink $wrap_parser;
+
+ $section_manager->append_conditional_to_conditional ($subconditional, $conditional, 0);
+ $code_string = nl ('}') .
+ nl () .
+ nl ($full_cpp_type . '::' . $cpp_type . '(' . $c_type . '* castitem)') .
+ nl (':') .
+ nl (' ' . $cpp_parent_type . '(static_cast< ' . $c_parent_type . '* >(castitem))') .
+ nl ('{}') .
+ nl ();
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($custom_ctor_cast_var, $conditional);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ my $custom_dtor_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DTOR;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+
+ $code_string = nl ($full_cpp_type . '::~' . $cpp_type . '()') .
+ nl ('{}') .
+ nl ();
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($custom_dtor_var, $conditional);
+
+ my $base_member = lc ($cpp_class_type) . '_';
+
+# TODO: move to Shared?
+ $code_string = nl ($full_cpp_type . '::CppClassType ' . $full_cpp_type . '::' . $base_member . '; // Initialize static member') .
+ nl () .
+ nl ('GType ' . $full_cpp_type . '::get_type()') .
+ nl ('{') .
+ nl (' return ' . $base_member . '_.init().get_type();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ $code_string = nl ('GType ' . $full_cpp_type . '::get_type(GTypeModule* module)') .
+ nl ('{') .
+ nl (' return ' . $base_member . '_.init(module).get_type();') .
+ nl ('}') .
+ nl ();
+
+ my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+ $code_string = nl ('GType ' . $full_cpp_type . '::get_base_type()') .
+ nl ('{') .
+ nl (' return ' . $get_type_func . '();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+
+ my @sections =
+ (
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_SIGNAL_PROXIES),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_PROPERTY_PROXIES),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_DEFAULT_SIGNAL_HANDLERS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS_CPP_WRAPPER),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE)
+ );
+
+ foreach my $cc_section (@sections)
+ {
+ $section_manager->append_section ($cc_section);
+ $section_manager->append_string (nl);
+ }
+
+ $section_manager->append_string (Common::Output::Shared::close_namespaces ($wrap_parser));
+}
+
+sub _output_p_cc ($$$$)
+{
+ my ($wrap_parser, $c_type, $c_type_class, $get_type_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $full_cpp_class_type = Common::Output::Shared::get_full_cpp_class_type $wrap_parser;
+ my $code_string = nl ('const Glib::Class& ' . $full_cpp_class_type . '::init()') .
+ nl ('{') .
+ nl (' if (!gtype_) // create the GType if necessary') .
+ nl (' {');
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE;
+
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+
+ my $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ my $do_not_derive_gtype_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DO_NOT_DERIVE_GTYPE;
+
+ $code_string = nl (' gtype_ = CppClassParent::CppObjectType::get_type();');
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $code_string = nl (' // Glib::Class has to know the class init function to clone custom types.') .
+ nl (' class_init_func_ = &' . $full_cpp_class_type . '::class_init_function;') .
+ nl () .
+ nl (' // This is actually just optimized away, apparently with no harm.') .
+ nl (' // Make sure that the parent type has been created.') .
+ nl (' //CppClassParent::CppObjectType::get_type();') .
+ nl () .
+ nl (' // Create the wrapper type, with the same class/instance size as the base type.') .
+ nl (' register_derived_type(' . $get_type_func . '());') .
+ nl () .
+ nl (' // Add derived versions of interfaces, if the C type implements any interfaces:');
+ $section_manager->push_conditional ($conditional, 0);
+ $section_manager->append_string ($code_string);
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_IMPLEMENTS_INTERFACES;
+ $section_manager->append_section ($section);
+ $section_manager->append_string (nl);
+ $section_manager->pop_entry;
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+ $code_string = nl (' }') .
+ nl () .
+ nl (' return *this;') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+ $code_string = nl ('const Glib::Class& ' . $full_cpp_class_type . '::init(GTypeModule* module)') .
+ nl ('{') .
+ nl (' if (!gtype_) // create the GType if necessary') .
+ nl (' {');
+ $section_manager->push_conditional ($conditional, 1);
+ $section_manager->append_string ($code_string);
+
+ my $subconditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ $code_string = nl (' // Do not derive a GType, or use a derived klass:') .
+ nl (' gtype_ = CppClassParent::CppObjectType::get_type();');
+ $section_manager->append_string_to_conditional ($code_string, $subconditional, 1);
+ $code_string = nl (' // Glib::Class has to know the class init function to clone custom types.') .
+ nl (' class_init_func_ = &' . $full_cpp_class_type . '::class_init_function;') .
+ nl () .
+ nl (' // This is actually just optimized away, apparently with no harm.') .
+ nl (' // Make sure that the parent type has been created.') .
+ nl (' //CppClassParent::CppObjectType::get_type();') .
+ nl () .
+ nl (' // Create the wrapper type, with the same class/instance size as the base type.') .
+ nl (' register_derived_type(' . $get_type_func . '(), module);') .
+ nl () .
+ nl (' // Add derived versions of interfaces, if the C type implements any interfaces:');
+ $section_manager->push_conditional ($subconditional, 1);
+ $section_manager->append_string ($code_string);
+ $section_manager->append_section ($section);
+ $section_manager->append_string (nl);
+ $section_manager->pop_entry; # subconditional, 1
+ $section_manager->append_conditional ($subconditional);
+ $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $subconditional);
+ $code_string = nl (' }') .
+ nl () .
+ nl (' return *this;') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry; # conditional, 1
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ $code_string = nl ('void ' . $full_cpp_class_type . '::class_init_function(void* g_class, void* class_data)') .
+ nl ('{') .
+ nl (' BaseClassType* const klass = static_cast< BaseClassType* >(g_class);') .
+ nl (' CppClassParent::class_init_function(klass, class_data);') .
+ nl ();
+ $section_manager->push_conditional ($conditional, 0);
+ $section_manager->append_string ($code_string);
+
+ my @p_cc_sections_inside_func =
+ (
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_VFUNCS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_DEFAULT_SIGNAL_HANDLERS)
+ );
+
+ foreach my $p_cc_section (@p_cc_sections_inside_func)
+ {
+ $section_manager->append_section ($section);
+ $section_manager->append_string (nl);
+ }
+ $code_string = nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry; # conditional, 0
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($do_not_derive_gtype_var, $conditional);
+
+ my @p_cc_sections_outside_func =
+ (
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_VFUNCS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_DEFAULT_SIGNAL_HANDLERS)
+ );
+
+ foreach my $p_cc_section (@p_cc_sections_outside_func)
+ {
+ $section_manager->append_section ($section);
+ $section_manager->append_string (nl);
+ }
+
+ $code_string = nl ('Glib::ObjectBase* ' . $full_cpp_class_type . '::wrap_new(GObject* object)') .
+ nl ('{') .
+ nl (' return new ' . $full_cpp_type . '(static_cast< ' . $c_type . '* >(object));') .
+ nl ('}') .
+ nl ();
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+
+ my $custom_wrap_new_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_WRAP_NEW;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($custom_wrap_new_var, $conditional);
+ $section_manager->append_string (Common::Output::Shared::close_namespaces $wrap_parser);
+ $section_manager->pop_entry;
+}
+
+sub output ($$$$$$$$)
+{
+ my ($wrap_parser, $c_type, $c_class_type, $c_parent_type, $c_parent_class_type, $get_type_func, $cpp_type, $cpp_parent_type) = @_;
+
+ _output_h_before_namespace $wrap_parser, $c_type, $c_class_type;
+ _output_h_in_class $wrap_parser, $c_type, $c_parent_type, $c_class_type, $cpp_type, $cpp_parent_type;
+ _output_h_after_namespace $wrap_parser, $c_type;
+ _output_p_h $wrap_parser, $c_type, $c_class_type, $c_parent_class_type, $cpp_parent_type;
+ _output_cc $wrap_parser, $c_type, $c_parent_type, $get_type_func, $cpp_type, $cpp_parent_type;
+ _output_p_cc $wrap_parser, $c_type, $c_class_type, $get_type_func;
+}
+
+sub implements_interface ($$$)
+{
+ my ($wrap_parser, $interface, $ifdef) = @_;
+ my $section_manager = $wrap_parser->get_section_interface;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_IMPLEMENTS_INTERFACES;
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ (nl ' ', $interface, '::add_interface(get_type());') .
+ (Common::Output::Shared::endif $ifdef);
+
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Generic.pm b/tools/pm/Common/Output/Generic.pm
new file mode 100644
index 0000000..8ec865f
--- /dev/null
+++ b/tools/pm/Common/Output/Generic.pm
@@ -0,0 +1,55 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Generic module
+#
+# Copyright 2011 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Generic;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub output ($$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $cc_end_section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+ my $cc_namespace_section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+ my $code_string = nl ('public:') .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' typedef ' . $cpp_type . ' CppObjectType;') .
+ nl (' typedef ' . $c_type . ' BaseObjectType;') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl ('private:') .
+ nl ();
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+ $section_manager->push_section ($cc_end_section);
+ $section_manager->append_string (Common::Output::Shared::open_namespaces $wrap_parser);
+ $section_manager->append_section ($cc_namespace_section);
+ $section_manager->append_string (Common::Output::Shared::close_namespaces $wrap_parser);
+ $section_manager->pop_entry;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/GtkObject.pm b/tools/pm/Common/Output/GtkObject.pm
new file mode 100644
index 0000000..0b34351
--- /dev/null
+++ b/tools/pm/Common/Output/GtkObject.pm
@@ -0,0 +1,26 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::GtkObject module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::GtkObject;
+
+use strict;
+use warnings;
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Interface.pm b/tools/pm/Common/Output/Interface.pm
new file mode 100644
index 0000000..a4b9b15
--- /dev/null
+++ b/tools/pm/Common/Output/Interface.pm
@@ -0,0 +1,378 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Interface module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Interface;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_before_first_namespace ($$$)
+{
+ my ($wrap_parser, $c_type, $c_class_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $conditional = Common::Output::Shared::struct_prototype $wrap_parser, $c_type, $c_class_type;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_BEFORE_FIRST_NAMESPACE;
+
+ $section_manager->push_section ($section);
+ $section_manager->append_conditional ($conditional);
+
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl () .
+ nl ('class ' . $cpp_class_type . ';') .
+ nl () .
+ nl (Common::Output::Shared::close_namespaces $wrap_parser) .
+ nl ();
+
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_h_in_class ($$$$)
+{
+ my ($wrap_parser, $c_type, $c_class_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $base_member = lc ($cpp_class_type) . '_';
+ my $virtual_dtor = 1;
+ my $copy_proto = 'no';
+ my $reinterpret = 1;
+ my $definitions = 1;
+ my $code_string = nl () .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl () .
+ nl ('public:') .
+ nl (' typedef ' . $cpp_type . ' CppObjectType;') .
+ nl (' typedef ' . $cpp_class_type . ' CppClassType;') .
+ nl (' typedef ' . $c_type . ' BaseObjectType;') .
+ nl (' typedef ' . $c_class_type . ' BaseClassType;') .
+ nl () .
+ nl ('private:') .
+ nl (' friend class ' . $cpp_class_type . ';') .
+ nl (' static CppClassType ' . $base_member . ';') .
+ nl () .
+ nl (' // noncopyable') .
+ nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+ nl () .
+ nl ('protected:') .
+ nl (' ' . $cpp_type . '(); // You must derive from this class.') .
+ nl () .
+ nl (' /** Called by constructors of derived classes. Provide the result of') .
+ nl (' * the Class init() function to ensure that it is properly') .
+ nl (' * initialized.') .
+ nl (' *') .
+ nl (' * @param interface_class The Class object for the derived type.') .
+ nl (' */') .
+ nl (' explicit ' . $cpp_type . '(const Glib::Interface_class& interface_class);') .
+ nl () .
+ nl ('public:') .
+ nl (' // This is public so that C++ wrapper instances can be') .
+ nl (' // created for C instances of unwrapped types.') .
+ nl (' // For instance, if an unexpected C type implements the C interface.') .
+ nl (' explicit ' . $cpp_type . '(' . $c_type . '* castitem);') .
+ nl () .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl ('public:') .
+ nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+ nl () .
+ nl (' static void add_interface(GType gtype_implementer);') .
+ nl () .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' static GType get_type() G_GNUC_CONST;') .
+ nl (' static GType get_base_type() G_GNUC_CONST;') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl () .
+ nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+ nl () .
+ nl ('private:') .
+ nl (' // import section_class2?') .
+ nl () .
+ nl ('public:') .
+ nl (' // import H_VFUNCS_AND_SIGNALS()') .
+ nl ();
+ my $main_section = $wrap_parser->get_main_section;
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_h_after_first_namespace ($$)
+{
+ my ($wrap_parser, $c_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $result_type = 'refptr';
+ my $take_copy_by_default = 'no';
+ my $open_glib_namespace = 1;
+ my $const_function = 0;
+ my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+ $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_p_h ($$$$)
+{
+ my ($wrap_parser, $c_type, $c_class_type, $cpp_parent_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $cpp_parent_class_type = $cpp_parent_type . '::CppClassType';
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $code_string = nl ('#include <glibmm/private/interface_p.h>') .
+ nl () .
+ nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl () .
+ nl ('class ' . $cpp_class_type . ' : public ' . $cpp_parent_class_type) .
+ nl ('{') .
+ nl ('public:') .
+ nl (' typedef ' . $full_cpp_type . ' CppObjectType;') .
+ nl (' typedef ' . $c_type . ' BaseObjectType;') .
+ nl (' typedef ' . $c_class_type . ' BaseClassType;') .
+ nl (' typedef ' . $cpp_parent_class_type . ' CppClassParent;') .
+ nl () .
+ nl (' friend class ' . $full_cpp_type . ';') .
+ nl () .
+ nl (' const Glib::Interface_Class& init();') .
+ nl () .
+ nl (' static void iface_init_function(void* g_iface, void* iface_data);') .
+ nl () .
+ nl (' static Glib::ObjectBase* wrap_new(GObject*);') .
+ nl () .
+ nl ('protected:') .
+ nl (' // Callbacks (default signal handlers):') .
+ nl (' // These will call the *_impl member methods, which will then call the existing default signal callbacks, if any.') .
+ nl (' // You could prevent the original default signal handlers being called by overriding the *_impl method.');
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_CONTENTS;
+
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_DEFAULT_SIGNAL_HANDLERS;
+ $section_manager->append_section ($section);
+ $code_string = nl () .
+ nl () .
+ nl (' // Callbacks (virtual functions):');
+ $section_manager->append_string ($code_string);
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_VFUNCS;
+ $section_manager->append_section ($section);
+ $code_string = nl () .
+ nl ('};') .
+ nl () .
+ nl (Common::Output::Shared::close_namespaces $wrap_parser) .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_cc ($$$$$$)
+{
+ my ($wrap_parser, $c_type, $c_parent_type, $cpp_type, $cpp_parent_type, $get_type_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ my $no_wrap_function_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+ my $complete_cpp_type = Common::Output::Shared::get_complete_cpp_type $wrap_parser;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+ my $code_string = nl ('namespace Glib') .
+ nl ('{') .
+ nl () .
+ nl ('Glib::RefPtr< ' . $complete_cpp_type . '> wrap(' . $c_type . '* object, bool take_copy)') .
+ nl ('{') .
+ nl (' return Glib::RefPtr< ' . $complete_cpp_type . ' >(dynamic_cast< ' . $complete_cpp_type . '* >(Glib::wrap_auto_interface< ' . $complete_cpp_type . ' >(static_cast<GObject*>(object), take_copy)));') .
+ nl (' // We use dynamic_cast<> in case of multiple inheritance.') .
+ nl ('}') .
+ nl () .
+ nl ('} // namespace Glib') .
+ nl ();
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->push_section ($section);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($no_wrap_function_var, $conditional);
+
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $base_member = lc ($cpp_class_type) . '_';
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+
+ $code_string = nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl ($full_cpp_type . '::' . $cpp_type . '()') .
+ nl (':') .
+ nl (' ' . $cpp_parent_type . '(' . $base_member . '.init())') .
+ nl ('{}') .
+ nl () .
+ nl ($full_cpp_type . '::' . $cpp_type . '(' . $c_type . '* castitem)') .
+ nl (':') .
+ nl (' ' . $cpp_parent_type . '(static_cast< ' . $c_parent_type . '* >(castitem))') .
+ nl ('{}') .
+ nl () .
+ nl ($full_cpp_type . '::' . $cpp_type . '(const Glib::Interface_Class& interface_class)') .
+ nl (':') .
+ nl (' ' . $cpp_parent_type . '(interface_class)') .
+ nl ('{}') .
+ nl () .
+ nl ($full_cpp_type . '::~' . $cpp_type . '()') .
+ nl ('{}') .
+ nl () .
+ nl ('// static') .
+ nl ('void ' . $full_cpp_type . '::add_interface(GType gtype_implementer)') .
+ nl ('{') .
+ nl (' ' . $base_member . '.init().add_interface(gtype_implementer);') .
+ nl ('}') .
+ nl () .
+ nl ($full_cpp_type . '::CppClassType ' . $full_cpp_type . '::' . $base_member . '; // initialize static member') .
+ nl () .
+ nl ('GType ' . $full_cpp_type . '::get_type()') .
+ nl ('{') .
+ nl (' return ' . $base_member . '.init().get_type();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+# TODO: move to Shared?
+ $code_string = nl ($full_cpp_type . '::CppClassType ' . $full_cpp_type . '::' . $base_member . '; // Initialize static member') .
+ nl () .
+ nl ('GType ' . $full_cpp_type . '::get_type()') .
+ nl ('{') .
+ nl (' return ' . $base_member . '.init().get_type();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+ $conditional = Common::Output::Shared::generate_conditional ($wrap_parser);
+ $code_string = nl ('GType ' . $full_cpp_type . '::get_type(GTypeModule* module)') .
+ nl ('{') .
+ nl (' return ' . $base_member . '.init(module).get_type();') .
+ nl ('}') .
+ nl ();
+
+ my $dynamic_gtype_registration_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::DYNAMIC_GTYPE_REGISTRATION;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 1);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($dynamic_gtype_registration_var, $conditional);
+ $code_string = nl ('GType ' . $full_cpp_type . '::get_base_type()') .
+ nl ('{') .
+ nl (' return ' . $get_type_func . '();') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+
+ my @sections =
+ (
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_SIGNAL_PROXIES),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_PROPERTY_PROXIES),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_DEFAULT_SIGNAL_HANDLERS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS_CPP_WRAPPER),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE)
+ );
+
+ foreach my $cc_section (@sections)
+ {
+ $section_manager->append_section ($cc_section);
+ $section_manager->append_string (nl);
+ }
+
+ $section_manager->append_string (Common::Output::Shared::close_namespaces ($wrap_parser));
+ $section_manager->pop_entry;
+}
+
+sub _output_p_cc ($$$)
+{
+ my ($wrap_parser, $c_type, $get_type_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $cpp_class_type = Common::Output::Shared::get_class_type $wrap_parser;
+ my $code_string = nl ('const Glib::Interface_Class& ' . $cpp_class_type . '::init()') .
+ nl ('{') .
+ nl (' if (!gtype) // create GType if necessary.') .
+ nl (' {') .
+ nl (' // Glib::Interface_Class has to know the interface init function') .
+ nl (' // in order to add interfaces to implementing types') .
+ nl (' class_init_func_ = &' . $cpp_class_type . '::iface_init_function;') .
+ nl () .
+ nl (' // We can not derive from another interface and it is not necessary anyway.') .
+ nl (' gtype_ = ' . $get_type_func . '();') .
+ nl (' }') .
+ nl () .
+ nl (' return *this;') .
+ nl ('}') .
+ nl () .
+ nl ('void ' . $cpp_class_type . '::iface_init_function(void* g_iface, void*)') .
+ nl ('{') .
+ nl (' BaseClassType* const klass(static_cast<BaseClassType*>(g_iface));') .
+ nl () .
+ nl (' // This is just to avoid an "unused variable" warning when there are no vfuncs or signal handlers to connect.') .
+ nl (' // This is a temporary fix until I find out why I can not seem to derive a GtkFileChooser interface. murrayc') .
+ nl (' g_assert(klass != 0);') .
+ nl ();
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_NAMESPACE;
+ my @cc_sections_inside_func =
+ (
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_VFUNCS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_DEFAULT_SIGNAL_HANDLERS),
+ );
+ my @cc_sections_outside_func =
+ (
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_VFUNCS),
+ (Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_DEFAULT_SIGNAL_HANDLERS)
+ );
+
+ $section_manager->push_section ($section);
+ $section_manager->append_string ($code_string);
+
+ foreach my $cc_section (@cc_sections_inside_func)
+ {
+ $section_manager->append_section ($cc_section);
+ $section_manager->append_string (nl);
+ }
+
+ $code_string = nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+
+ foreach my $cc_section (@cc_sections_outside_func)
+ {
+ $section_manager->append_section ($cc_section);
+ $section_manager->append_string (nl);
+ }
+
+ $code_string = nl ('Glib::ObjectBase* ' . $cpp_class_type . '::wrap_new(GObject* object)') .
+ nl ('{') .
+ nl (' return new ' . $full_cpp_type . '(static_cast< ' . $c_type .' >(object));') .
+ nl ('}');
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub output ($$$$$$$)
+{
+ my ($wrap_parser, $c_type, $c_class_type, $c_parent_type, $cpp_type, $cpp_parent_type, $get_type_func) = @_;
+
+ _output_h_before_first_namespace $wrap_parser, $c_type, $c_class_type;
+ _output_h_in_class $wrap_parser, $c_type, $c_class_type, $cpp_type;
+ _output_h_after_first_namespace $wrap_parser, $c_type;
+ _output_p_h $wrap_parser, $c_type, $c_class_type, $cpp_parent_type;
+ _output_cc $wrap_parser, $c_type, $c_parent_type, $cpp_type, $cpp_parent_type, $get_type_func;
+ _output_cc_p $wrap_parser, $c_type, $get_type_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Method.pm b/tools/pm/Common/Output/Method.pm
new file mode 100644
index 0000000..fc71542
--- /dev/null
+++ b/tools/pm/Common/Output/Method.pm
@@ -0,0 +1,183 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Method module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Method;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$$$$)
+{
+ my ($wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $code_string = '';
+
+ die if (scalar (@{$cpp_param_types}) != scalar(@{$cpp_param_names}));
+ die if ($static and $const);
+
+ if ($static)
+ {
+ $code_string += 'static ';
+ }
+ $code_string += $cpp_ret_type . ' ' . $cpp_func_name;
+
+ my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+
+ $code_string += '(' . $cpp_params_str . ')';
+ if ($const)
+ {
+ $code_string += ' const';
+ }
+ $code_string += ';';
+ $section_manager->append_string_to_section (nl ($code_string), $main_section);
+}
+
+sub _output_cc ($$$$$$$$$$$$$$$$)
+{
+ my ($wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const, $constversion, $deprecated, $ifdef, $c_ret_type, $ret_transfer, $c_func_name, $c_param_types, $c_param_transfers, $errthrow) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = '';
+ my $ret_void = ($cpp_ret_type eq 'void');
+
+# TODO: replace with exception throwing
+ # if dies then it is internal error. should not happen here.
+ die if ($static and ($const or $constversion));
+ die if (scalar (@{$types_list}) != scalar(@{$names_list}));
+ die if (scalar (@{$c_param_types}) != scalar(@{$types_list}));
+
+ if ($deprecated)
+ {
+ $code_string += Common::Output::Shared::deprecate_start $wrap_parser;
+ }
+ if ($ifdef)
+ {
+ $code_string += nl ('#ifdef ' . $ifdef);
+ }
+ if ($static)
+ {
+ $code_string += nl ('// static');
+ }
+
+ my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $c_type = Common::Output::Shared::get_c_type;
+
+ $code_string += nl ($cpp_ret_type . ' ' . $full_cpp_type . '::' . $cpp_func_name . '(' . $cpp_param_list_str . ')' . ($const ? ' const' : '')) .
+ nl ('{');
+
+ my $names_only = join ', ', @{$cpp_param_names};
+
+ if ($constversion)
+ {
+ my $ret = '';
+
+ unless ($ret_void)
+ {
+ $ret = 'return ';
+ }
+ $code_string += nl (' ' . $ret . 'const_cast< ' . $full_cpp_type . '* >(this)->' . $cpp_func_name . '(' . $names_only . ');');
+ }
+ else
+ {
+ my $this_param = '';
+
+ if ($const)
+ {
+ $this_param = 'const_cast< ' . $c_type . '* >(gobj()), ';
+ }
+ elsif (not $static)
+ {
+ $this_param = 'gobj(), ';
+ }
+
+ my $conversions_store = $wrap_parser->get_conversions_store;
+ my $c_param_list_str = $this_param . (Common::Output::Shared::convzipstr $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names) . ($errthrow ? ', &gerror' . '');
+ my $c_func_invocation = $c_func_name . '(' . $c_param_list_str . ')';
+ my $ret_convert = $conversions_store->get_conversion ($c_ret_type, $cpp_ret_type, $ret_transfer, $c_func_invocation);
+
+ if ($errthrow)
+ {
+ $code_string += nl (' GError* gerror(0);');
+
+ unless ($ret_void)
+ {
+ $code_string += nl (' ' . $cpp_ret_type . ' retvalue(' . $ret_convert . ');');
+ }
+ else
+ {
+ $code_string += nl () .
+ nl (' ' . $c_func_invocation . ';');
+ }
+ if ($errthrow)
+ {
+ $code_string += nl () .
+ nl (' if (gerror)') .
+ nl (' {') .
+ nl (' ::Glib::Error::throw_exception(gerror);') .
+ nl (' }');
+ }
+ unless ($ret_void)
+ {
+ $code_string += nl () .
+ nl ('return retvalue;');
+ }
+ }
+ else
+ {
+ if ($ret_void)
+ {
+ $code_string += nl (' return ' . $ret_convert . ';');
+ }
+ else
+ {
+ $code_string += nl (' ' . $c_func_invocation . ';');
+ }
+ }
+ }
+ $code_string += nl ('}');
+ if ($ifdef)
+ {
+ $code_string += nl ('#endif // ' . $ifdef);
+ }
+ if ($deprecated)
+ {
+ $code_string += Common::Output::Shared::deprecate_end $wrap_parser;
+ }
+
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$$$$$$$$$$$)
+{
+ my ($wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const, $constversion, $deprecated, $ifdef, $c_ret_type, $ret_transfer, $c_func_name, $c_param_types, $c_param_transfers, $errthrow) = @_;
+
+ _output_h $wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const;
+ _output_cc $wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $const, $constversion, $deprecated, $ifdef, $c_ret_type, $ret_transfer, $c_func_name, $c_param_types, $c_param_transfers, $errthrow;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/OpaqueCopyable.pm b/tools/pm/Common/Output/OpaqueCopyable.pm
new file mode 100644
index 0000000..0912b1c
--- /dev/null
+++ b/tools/pm/Common/Output/OpaqueCopyable.pm
@@ -0,0 +1,188 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::OpaqueCopyable module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::OpaqueCopyable;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_in_class ($$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = nl ('public:') .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' typedef ' . $cpp_type . ' CppObjectType;') .
+ nl (' typedef ' . $c_type . ' BaseObjectType;') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl ();
+ my $main_section = $wrap_parser->get_main_section;
+
+ $section_manager->push_section ($main_section);
+ $section_manager->append_string ($code_string);
+
+ my $conditional = Common::Output::Shared::default_ctor_proto $wrap_parser, $cpp_type;
+
+ $section_manager->append_conditional ($conditional);
+
+ my $copy_proto = 'const';
+ my $reinterpret = 0;
+ my $definitions = 1;
+ my $virtual_dtor = 0;
+
+ $code_string = nl (' // Use make_a_copy = true when getting it directly from a struct.') .
+ nl (' explicit ' . $cpp_type . '(' . $c_type . '* castitem, bool make_a_copy = false);') .
+ nl () .
+ nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+ nl () .
+ nl (Common::Output::Shared::dtor_proto_str $cpp_type, $virtual_dtor) .
+ nl () .
+ nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+ nl () .
+ nl ('protected:') .
+ nl (' ' . $c_type . '* gobject_;') .
+ nl () .
+ nl ('private:');
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub _output_h_after_first_namespace ($$)
+{
+ my ($wrap_parser, $c_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $result_type = 'plain';
+ my $take_copy_by_default = 'no';
+ my $open_glib_namespace = 1;
+ my $const_function = 0;
+ my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+ $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_cc ($$$$$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $new_func, $copy_func, $free_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $custom_default_ctor_var = Common::Output::Shared::get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+ my $conditional = Common::Output::Shared::generate_conditional $wrap_parser;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $code_string = nl ($full_cpp_type . '::' . $cpp_type . '()') .
+ nl (':');
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+
+ if (defined $new_func and $new_func ne '' and $new_func ne 'NONE')
+ {
+ $code_string += nl (' gobject_(' . $new_func . '())');
+ }
+ else
+ {
+ $code_string += nl (' gobject_(0) // Allows creation of invalid wrapper, e.g. for output arguments to methods.');
+ }
+ $code_string += nl ();
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->push_section ($section);
+ $section_manager->append_conditional ($conditional);
+ $section_manager->set_variable_for_conditional ($custom_default_ctor_var, $conditional);
+# TODO: we probably have to assume that copy func must be provided.
+ $code_string = nl ($full_cpp_type . '::' . $cpp_type . '(const ' . $cpp_type . '& src)') .
+ nl (':') .
+ nl (' gobject_((src.gobject_) ? ' . $copy_func . '(src.gobject_) : 0)') .
+ nl ('{}') .
+ nl () .
+ nl ($full_cpp_type . '::' . $cpp_type . '(' . $c_type . '* castitem, bool make_a_copy /* = false */)') .
+ nl ('{') .
+ nl (' if (!make_a_copy)') .
+ nl (' {') .
+ nl (' // It was given to use by a function which has already made a copy for us to keep.') .
+ nl (' gobject_ = castitem;') .
+ nl (' }') .
+ nl (' else') .
+ nl (' {') .
+ nl (' // We are probably getting it via direct access to a struct,') .
+ nl (' // so we can not just take ut - we have to take a copy if it.') .
+ nl (' if (castitem)') .
+ nl (' {') .
+ nl (' gobject_ = ' . $copy_func . '(castitem);') .
+ nl (' }') .
+ nl (' else') .
+ nl (' {') .
+ nl (' gobject_ = 0;') .
+ nl (' }') .
+ nl (' }') .
+ nl ('}') .
+ nl ();
+ if (defined $copy_func and $copy_func ne '' and $copy_func ne 'NONE')
+ {
+ $code_string += nl ($full_cpp_type . '& ' . $full_cpp_type . '::operator=(const ' . $full_cpp_type . '& src)') .
+ nl ('{') .
+ nl (' ' . $c_type . '* const new_gobject = (src.gobject_) ? ' . $copy_func . '(src.gobject_) : 0;') .
+ nl () .
+ nl (' if (gobject_)') .
+ nl (' {') .
+ nl (' ' . $free_func . '(gobject_);') .
+ nl (' }') .
+ nl () .
+ nl (' gobject_ = new_gobject;') .
+ nl () .
+ nl (' return *this') .
+ nl ('}') .
+ nl ();
+ }
+ $code_string += nl ($full_cpp_type . '::~' . $cpp_type . '()') .
+ nl ('{') .
+ nl (' if (gobject_)') .
+ nl (' {') .
+ nl (' ' . $free_func . '(gobject_);') .
+ nl (' }') .
+ nl ('}') .
+ nl () .
+ nl ($c_type . '* ' . $full_cpp_type . '::gobj_copy() const') .
+ nl ('{') .
+ nl (' return ' . $copy_func . '(gobject_);') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string ($code_string);
+
+ my $cc_namespace_section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_NAMESPACE;
+
+ $section_manager->append_section ($cc_namespace_section);
+ $code_string = nl () .
+ Common::Output::Shared::close_namespaces $wrap_parser;
+ $section_manager->append_string ($code_string);
+ $section_manager->pop_entry;
+}
+
+sub output ($$$$$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $new_func, $copy_func, $free_func) = @_;
+
+ _output_h_in_class $wrap_parser, $c_type, $cpp_type;
+ _output_h_after_first_namespace $wrap_parser, $c_type;
+ _output_cc $wrap_parser, $c_type, $cpp_type, $new_func, $copy_func, $free_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/OpaqueRefcounted.pm b/tools/pm/Common/Output/OpaqueRefcounted.pm
new file mode 100644
index 0000000..1fbb278
--- /dev/null
+++ b/tools/pm/Common/Output/OpaqueRefcounted.pm
@@ -0,0 +1,191 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::OpaqueRefcounted module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::OpaqueRefcounted;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h_in_class ($$$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $new_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = nl ('public:') .
+ nl (Common::Output::Shared::doxy_skip_begin) .
+ nl (' typedef ' . $cpp_type . ' CppObjectType;') .
+ nl (' typedef ' . $c_type . ' BaseObjectType;') .
+ nl (Common::Output::Shared::doxy_skip_end) .
+ nl ();
+
+ if (defined $new_func and $new_func ne '' and $new_func ne 'NONE')
+ {
+ $code_string += nl (' static Glib::RefPtr< ' . $cpp_type . ' > create();') .
+ nl ();
+ }
+
+ my $copy_proto = 'const';
+ my $reinterpret = 0;
+ my $definitions = 0;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $main_section = $wrap_parser->get_main_section;
+
+ $code_string += nl (' /** Increment the reference count for this object.') .
+ nl (' * You should never need to do this manually - use the object via a RefPtr instead.') .
+ nl (' */') .
+ nl (' void reference() const;') .
+ nl () .
+ nl (' /** Decrement the reference count for this object.') .
+ nl (' * You should never need to do this manually - use the object via a RefPtr instead.') .
+ nl (' */') .
+ nl (' void unreference() const;') .
+ nl () .
+ nl (Common::Output::Shared::gobj_protos_str $c_type, $copy_proto, $reinterpret, $definitions) .
+ nl () .
+ nl ('protected:') .
+ nl (' // Do not derive this. ' . $full_cpp_type . ' can neither be constructed nor deleted.') .
+ nl (' ' . $cpp_type . '();') .
+ nl (' void operator delete(void*, size_t);') .
+ nl () .
+ nl ('private:') .
+ nl (Common::Output::Shared::copy_protos_str $cpp_type) .
+ nl ();
+ $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_h_after_first_namespace ($$)
+{
+ my ($wrap_parser, $c_type) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $result_type = 'refptr';
+ my $take_copy_by_default = 'no';
+ my $open_glib_namespace = 1;
+ my $const_function = 0;
+# TODO: This should not be a conditional, but a plain string.
+ my $conditional = Common::Output::Shared::wrap_proto $wrap_parser, $c_type, $result_type, $take_copy_by_default, $open_glib_namespace, $const_function;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_NAMESPACE;
+
+ $section_manager->append_conditional_to_section ($conditional, $section);
+}
+
+sub _output_cc ($$$$$)
+{
+ my ($wrap_parser, $c_type, $new_func, $ref_func, $unref_func) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_END;
+ my $code_string = nl ('/* Why reinterpret_cast< ' . $full_cpp_type . '* >(gobject) is needed:') .
+ nl (' *') .
+ nl (' * A ' . $full_cpp_type . ' instance is in fact always a ' . $c_type . ' instance.') .
+ nl (' * Unfortunately, ' . $c_type . ' cannot be a member of ' . $full_cpp_type . ',') .
+ nl (' * because it is an opaque struct. Also, the C interface does not provide') .
+ nl (' * any hooks to install a destroy notification handler, thus we cannot') .
+ nl (' * wrap it dynamically either.') .
+ nl (' *') .
+ nl (' * The cast works because ' . $full_cpp_type . ' does not have any member data, and') .
+ nl (' * it is impossible to derive from it. This is ensured by not implementing') .
+ nl (' * the (protected) default constructor. The ctor is protected rather than') .
+ nl (' * private just to avoid a compile warning.') .
+ nl (' */') .
+ nl ('/* krnowak:') .
+ nl (' * This is an awful hack and I think it is not necessary.') .
+ nl (' * We could store a pointer to C instance.') .
+ nl (' * We just would not be an owner of this pointer.') .
+ nl (' */') .
+ nl () .
+ nl ('namespace Glib') .
+ nl ('{') .
+ nl () .
+ nl ('Glib::RefPtr< ' . $full_cpp_type . ' > wrap(' . $c_type . '* object, bool take_copy)') .
+ nl ('{') .
+ nl (' if (take_copy && object)') .
+ nl (' ' . $ref_func . '(object);') .
+ nl () .
+ nl (' // See the comment at the top of this file, if you want to know why the cast works.') .
+ nl (' return Glib::RefPtr< ' . $full_cpp_type . ' >(reinterpret_cast< ' . $full_cpp_type . '* >(object));') .
+ nl ('}') .
+ nl () .
+ nl ('} // namespace Glib') .
+ nl () .
+ nl (Common::Output::Shared::open_namespaces $wrap_parser) .
+ nl ();
+ if (defined $new_func and $new_func ne '' and $new_func ne 'NONE')
+ {
+ $code_string += nl ('// static') .
+ nl ('Glib::RefPtr< ' . $full_cpp_type . ' > ' . $full_cpp_type . '::create()') .
+ nl ('{') .
+ nl (' // See the comment at the top of this file, if you want to know why the cast works.') .
+ nl (' return Glib::RefPtr< ' . $full_cpp_type . ' >(reinterpret_cast< ' . $full_cpp_type . ' >(' . $new_func . '()));') .
+ nl ('}') .
+ nl ();
+ }
+
+ $code_string += nl ('void ' . $full_cpp_type . '::reference() const') .
+ nl ('{') .
+ nl (' // See the comment at the top of this file, if you want to know why the cast works.') .
+ nl (' ' . $ref_func . '(reinterpret_cast< ' . $c_type . '* >(const_cast< ' . $full_cpp_type . '* >(this)));') .
+ nl ('}') .
+ nl () .
+ nl ('void ' . $full_cpp_type . '::unreference() const') .
+ nl ('{') .
+ nl (' // See the comment at the top of this file, if you want to know why the cast works.') .
+ nl (' ' . $unref_func . '(reinterpret_cast< ' . $c_type . '* >(const_cast< ' . $full_cpp_type . '* >(this)));') .
+ nl ('}') .
+ nl () .
+ nl ($c_type . '* ' . $full_cpp_type . '::gobj()') .
+ nl ('{') .
+ nl (' // See the comment at the top of this file, if you want to know why the cast works.') .
+ nl (' return reinterpret_cast< ' . $c_type . '* >(this);') .
+ nl ('}') .
+ nl () .
+ nl ('const ' . $c_type . '* ' . $full_cpp_type . '::gobj() const') .
+ nl ('{') .
+ nl (' // See the comment at the top of this file, if you want to know why the cast works.') .
+ nl (' return reinterpret_cast< const ' . $c_type . '* >(this);') .
+ nl ('}') .
+ nl () .
+ nl ($c_type . '* ' . $full_cpp_type . '::gobj_copy() const') .
+ nl ('{') .
+ nl (' // See the comment at the top of this file, if you want to know why the cast works.') .
+ nl (' ' . $c_type . '* const gobject = reinterpret_cast< ' . $c_type . '* >(const_cast< ' . $full_cpp_type . '* >(this));') .
+ nl (' ' . $ref_func . '(gobject);') .
+ nl (' return gobject;') .
+ nl ('}') .
+ nl ();
+ $section_manager->append_string_to_section ($code_string, $section);
+ $code_string = nl () .
+ Common::Output::close_namespaces $wrap_parser;
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$)
+{
+ my ($wrap_parser, $c_type, $cpp_type, $new_func, $ref_func, $unref_func) = @_;
+
+ _output_h_in_class $wrap_parser, $c_type, $cpp_type, $new_func;
+ _output_h_after_first_namespace $wrap_parser, $c_type;
+ _output_cc $wrap_parser, $c_type, $new_func, $ref_func, $unref_func;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Property.pm b/tools/pm/Common/Output/Property.pm
new file mode 100644
index 0000000..4fb5bda
--- /dev/null
+++ b/tools/pm/Common/Output/Property.pm
@@ -0,0 +1,97 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Property module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Property;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$)
+{
+ my ($wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $proxy_type = 'Glib::PropertyProxy' . $proxy_suffix . '< ' . $prop_cpp_type . ' >';
+ my $method_suffix = ($proxy_suffix eq '_ReadOnly' ? ' const' : '');
+ my $code_string = (nl ' /** You rarely need to use properties because there are get_and _set_ methods for almost all of them.') .
+ (nl ' * @return A PropertyProxy that allows you to get or set the property of the value, or receive notification when') .
+ (nl ' * the value of the property changes.') .
+ (nl ' */') .
+ (nl ' ' . $proxy_type . ' property_' . $prop_cpp_name . '()' . $method_suffixP);
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_cc ($$$$$)
+{
+ my ($wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name, $prop_c_name) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_PROPERTY_PROXIES;
+ my $proxy_type = 'Glib::PropertyProxy' . $proxy_suffix . '< ' . $prop_cpp_type . ' >';
+ my $method_suffix = ($proxy_suffix eq '_ReadOnly' ? ' const' : '');
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $code_string = (nl $proxy_type . ' ' . $full_cpp_type . '::property_' . $prop_cpp_name . '()' . $method_suffix) .
+ (nl '{') .
+ (nl ' ' . $proxy_type . '(this, "' . $prop_c_name'");') .
+ (nl '}') .
+ (nl);
+
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$$)
+{
+ my ($wrap_parser, $construct_only, $readable, $writable, $prop_cpp_type, $prop_cpp_name, $prop_c_name) = @_;
+ my $read_only = 0;
+ my $write_only = 0;
+
+ if ($construct_only)
+ {
+ $read_only = 1;
+ }
+ elsif (not $readable)
+ {
+ $write_only = 1;
+ }
+ elsif (not $writable)
+ {
+ $read_only = 1;
+ }
+
+ my $proxy_suffix = ($read_only ? '_ReadOnly' : ($write_only ? '_WriteOnly' : ''));
+
+ _output_h $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name;
+ _output_cc $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name, $prop_c_name;
+
+ if (not $read_only and $readable)
+ {
+ $proxy_suffix = '_ReadOnly';
+
+ _output_h $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name;
+ _output_cc $wrap_parser, $proxy_suffix, $prop_cpp_type, $prop_cpp_name, $prop_c_name;
+ }
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Shared.pm b/tools/pm/Common/Output/Shared.pm
index 85b87cd..7b47dd9 100644
--- a/tools/pm/Common/Output/Shared.pm
+++ b/tools/pm/Common/Output/Shared.pm
@@ -22,23 +22,20 @@ package Common::Output::Shared;
use strict;
use warnings;
+use feature ':5.10';
use constant
{
- 'PROTECTED_GCLASS_VAR' => 'PROTECTED_GCLASS_BOOL_VARIABLE',
- 'DYNAMIC_GTYPE_REGISTRATION_VAR' => 'DYNAMIC_GTYPE_REGISTRATION_BOOL_VARIABLE',
- 'STRUCT_NOT_HIDDEN_VAR' => 'STRUCT_NOT_HIDDEN_BOOL_VARIABLE',
- 'NO_WRAP_FUNCTION_VAR' => 'NO_WRAP_FUNCTION_BOOL_VARIABLE',
- 'DO_NOT_DERIVE_GTYPE_VAR' => 'DO_NOT_DERIVE_GTYPE_BOOL_VARIABLE',
- 'CUSTOM_WRAP_NEW_VAR' => 'CUSTOM_WRAP_NEW_BOOL_VARIABLE',
- 'CUSTOM_CTOR_CAST_VAR' => 'CUSTOM_CTOR_CAST_BOOL_VARIABLE',
- 'DERIVES_INITIALLY_UNOWNED_VAR' => 'DERIVES_INITIALLY_UNOWNED_BOOL_VARIABLE',
- 'CUSTOM_DTOR_VAR' => 'CUSTOM_DTOR_BOOL_VARIABLE'
+ 'FLAGS_TYPE' => 'Flags',
+ 'ENUM_TYPE' => 'Enum',
};
+use Common::Variables;
+use Common::Sections;
+
sub nl
{
- return (shift or '') . "\n";
+ return join '', @_, "\n";
}
sub doxy_skip_begin ()
@@ -53,10 +50,11 @@ sub doxy_skip_end ()
sub open_namespaces ($)
{
- my ($namespaces) = @_;
+ my ($wrap_parser) = @_;
+ my $namespaces = $wrap_parser->get_namespaces;
my $code_string = '';
- foreach my $opened_name (reverse @{$namespaces})
+ foreach my $opened_name (@{$namespaces})
{
$code_string .= nl ('namespace ' . $opened_name) .
nl ('{') .
@@ -67,10 +65,11 @@ sub open_namespaces ($)
sub close_namespaces ($)
{
- my ($namespaces) = @_;
+ my ($wrap_parser) = @_;
+ my $namespaces = $wrap_parser->get_namespaces;
my $code_string = '';
- foreach my $closed_name (@{$namespaces})
+ foreach my $closed_name (reverse @{$namespaces})
{
$code_string .= nl ('} // namespace ' . $closed_name) .
nl ();
@@ -78,22 +77,525 @@ sub close_namespaces ($)
return $code_string;
}
-sub join_namespaces ($)
+# returns VteTerminal
+sub get_c_type ($)
+{
+ my ($wrap_parser) = @_;
+
+ return $wrap_parser->get_c_class;
+}
+
+# returns Terminal
+sub get_cpp_type ($)
+{
+ my ($wrap_parser) = @_;
+ my $classes = $wrap_parser->get_classes;
+
+ if (@{$classes})
+ {
+ return $classes->[-1];
+ }
+ return undef;
+}
+
+# returns Terminal, the difference is that it can also return Foo::Bar if Bar is
+# a class inside a Foo class
+sub get_full_cpp_type ($)
+{
+ my ($wrap_parser) = @_;
+ my $classes = $wrap_parser->get_classes;
+ my $full_cpp_class = join '::', @{$classes};
+
+ return $full_cpp_class;
+}
+
+# returns Gnome::Vte
+sub get_full_namespace ($)
+{
+ my ($wrap_parser) = @_;
+ my $namespaces = $wrap_parser->get_namespaces;
+ my $full_namespace = join '::', @{$namespaces};
+
+ return $full_namespace;
+}
+
+# returns Gnome::Vte::Terminal
+sub get_complete_cpp_type ($)
+{
+ my ($wrap_parser) = @_;
+ my $namespaces = get_full_namespace $wrap_parser;
+ my $classes = get_full_cpp_class $wrap_parser;
+
+ return join '::', $namespaces, $classes;
+}
+
+# returns Terminal_Class for Gnome::Vte::Terminal.
+# returns Terminal_Foo_Class for Gnome::Vte::Terminal::Foo.
+sub get_cpp_class_type ($)
{
- my ($namespaces) = @_;
+ my ($wrap_parser) = @_;
+ my $full_cpp_type = get_full_cpp_type $wrap_parser;
- return join ('::', reverse @{$namespaces});
+ $full_cpp_type =~ s/::/_/g;
+ return $full_cpp_type . '_Class';
}
-sub create_class_local_prefix ($$)
+# returns Gnome::Vte::Terminal_Class for Gnome::Vte::Terminal.
+# returns Gnome::Vte::Terminal_Foo_Class for Gnome::Vte::Terminal::Foo.
+sub get_complete_cpp_class_type ($)
{
- my ($namespaces, $class) = @_;
- my $single_string = join_namespaces ($namespaces) . '_' . $class;
+ my ($wrap_parser) = @_;
+ my $full_namespace = get_full_namespace $wrap_parser;
+ my $cpp_class_type = get_cpp_class_type $wrap_parser;
- $single_string =~ s/\W+/_/g;
- $single_string =~ s/_+/_/g;
- return uc ($single_string) . '_';
+ return join '::', $full_namespace, $cpp_class_type;
}
+# TODO: implement beautifying if I am really bored.
+sub convert_members_to_strings ($)
+{
+ my ($members) = @_;
+ my @strings = ();
+
+ foreach my $pair (@{$members})
+ {
+ my $name = $pair->[0];
+ my $value = $pair->[1];
+
+ push @strings, ' ' . $name . ' = ' . $value;
+ }
+ return \ strings;
+}
+
+sub get_section ($$);
+sub get_variable ($$);
+
+sub output_enum_gtype_func_h ($$$$)
+{
+ my ($wrap_parser, $cpp_type, $type, $get_type_func) = @_;
+
+ if (defined $get_type_func)
+ {
+ my $namespaces = $wrap_parser->get_namespaces;
+ my $main_section = $wrap_parser->get_main_section;
+ my $classes = $wrap_parser->get_classes;
+ my $full_cpp_type = join '::', (get_full_cpp_type $wrap_parser), $cpp_type;
+ my $close = 1;
+ my $value_base = 'Glib::Value_' . $type;
+ my $code_string = '';
+ my $section_manager = $wrap_parser->get_section_manager;
+
+ if (@{$namespaces} == 1 and $namespaces->[0] eq 'Glib')
+ {
+ $close = 0;
+ }
+
+ if ($close)
+ {
+ $code_string .= close_namespaces ($wrap_parser) .
+ nl (doxy_skip_begin) .
+ nl ('namespace Glib') .
+ nl ('{') .
+ nl ();
+ }
+ else
+ {
+ $code_string .= nl (doxy_skip_begin);
+ }
+
+ $code_string .= nl ('template <>') .
+ nl ('class Value< ' . $full_cpp_type . ' > : public ' . $value_base . '< ' . $full_cpp_type . ' >') .
+ nl ('{') .
+ nl ('public:') .
+ nl (' static GType value_type() G_GNUC_CONST;') .
+ nl ('};') .
+ nl ();
+
+ if ($close)
+ {
+ $code_string .= nl ('} // namespace Glib') .
+ nl (doxy_skip_end) .
+ nl () .
+ open_namespaces ($wrap_parser);
+ }
+ else
+ {
+ $code_string .= nl (doxy_skip_end) .
+ nl ();
+ }
+
+ if (@{$classes} > 0)
+ {
+ my $section = get_section $wrap_parser, Common::Sections::H_AFTER_FIRST_CLASS;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+ }
+ else
+ {
+ $section_manager->append_string_to_section ($code_string, $main_section);
+ }
+ }
+}
+
+sub output_enum_gtype_func_cc ($$$)
+{
+ my ($wrap_parser, $cpp_type, $get_type_func) = @_;
+
+ if (defined $get_type_func)
+ {
+ my $container_cpp_type = get_full_cpp_type $wrap_parser;
+ my $full_cpp_type = join '::', $container_cpp_type, $cpp_type;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = nl ('namespace Glib') .
+ nl ('{') .
+ nl () .
+ nl ('// static') .
+ nl ('GType Glib::Value< ' . $full_cpp_type . ' >::value_type()') .
+ nl ('{') .
+ nl (' return ' . $get_type_func . '();') .
+ nl ('}') .
+ nl () .
+ nl ('} // namespace Glib') .
+ nl ();
+ my $section = get_section $wrap_parser, Common::Sections::CC_END;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+ }
+}
+
+sub generate_conditional ($)
+{
+ my ($wrap_parser) = @_;
+ my $number = $wrap_parser->get_number;
+
+ return 'CONDITIONAL#' . $number;
+}
+
+sub struct_prototype ($$$)
+{
+ my ($wrap_parser, $c_name, $c_class_name) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $code_string = nl (doxy_skip_begin) .
+ nl ('typedef struct _' . $c_name . ' ' . $c_name . ';') .
+ nl ('typedef struct _' . $c_class_name . ' ' . $c_class_name . ';') .
+ nl (doxy_skip_end) .
+ nl ();
+ my $variable = get_variable $wrap_parser, Common::Variables::STRUCT_NOT_HIDDEN;
+ my $conditional = generate_conditional $wrap_parser;
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+ return $conditional;
+}
+
+sub wrap_proto ($$$$$$)
+{
+ my ($wrap_parser, $c_name, $result_type, $take_copy, $open, $const) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $result = undef;
+ my $full_cpp_name = get_full_cpp_name $wrap_parser;
+
+# TODO: make result type constant
+ if ($result_type eq 'refptr')
+ {
+ $result = 'Glib::RefPtr< ' . $full_cpp_name . ' >';
+ }
+ elsif ($result_type eq 'ref')
+ {
+ $result = $full_cpp_name . '&';
+ }
+ elsif ($result_type eq 'ptr')
+ {
+ $result = $full_cpp_name . '*';
+ }
+ elsif ($result_type eq 'plain')
+ {
+ $result = $full_cpp_name;
+ }
+ else
+ {
+ die;
+ }
+
+ if ($const)
+ {
+ $result = 'const ' . $result;
+ }
+
+ my $params = ($const ? 'const ' : '') . $c_name . '* object';
+ my $params_doc = ' * @param object The C instance.';
+
+ if ($take_copy ne 'N/A')
+ {
+ $params_doc = nl ($params_doc) .
+ nl (' * @param take_copy @c false if the result should take ownership') .
+ ' * of the C instance. @c true if it should take a new copy or reference.';
+ $params += ', bool take_copy = ';
+ if ($take_copy eq 'yes')
+ {
+ $params += 'true';
+ }
+ elsif ($take_copy eq 'no')
+ {
+ $params += 'false';
+ }
+ else
+ {
+ die;
+ }
+ }
+
+ my $conditional = generate_conditional $wrap_parser;
+ my $variable = get_variable $wrap_parser, Common::Variables::NO_WRAP_FUNCTION;
+ my $code_string = '';
+
+ if ($open)
+ {
+ $code_string += nl ('namespace Glib') .
+ nl ('{') .
+ nl ();
+ }
+
+ $code_string += nl ('/** A Glib::wrap() method for this object.') .
+ nl (' *') .
+ nl ($params_doc) .
+ nl (' * @result A C++ instance that wraps this C instance') .
+ nl (' *') .
+ nl (' * @relates ' . $full_cpp_name) .
+ nl (' */') .
+ nl ($result . ' wrap(' . $params . ');') .
+ nl ();
+ if ($open)
+ {
+ $code_string += nl ('} //namespace Glib') .
+ nl ();
+ }
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+ return $conditional;
+}
+
+sub default_ctor_proto ($$)
+{
+ my ($wrap_parser, $cpp_name) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $variable = get_variable $wrap_parser, Common::Variables::CUSTOM_DEFAULT_CTOR;
+ my $conditional = generate_conditional $wrap_parser;
+ my $code_string = nl (' ' . $cpp_name . '();');
+
+ $section_manager->append_string_to_conditional ($code_string, $conditional, 0);
+ $section_manager->set_variable_for_conditional ($variable, $conditional);
+
+ return $conditional;
+}
+
+# wrap output of this function with nl();
+sub copy_protos_str ($)
+{
+ my ($cpp_name) = @_;
+ my $code_string = nl (' ' . $cpp_name . '(const ' . $cpp_name . '& src);') .
+ ' ' . $cpp_name . '& operator=(const ' . $cpp_name . '& src);';
+
+ return $code_string;
+}
+
+sub dtor_proto_str ($$)
+{
+ my ($cpp_name, $virtual_dtor) = @_;
+ my $code_string = ' ' . ($virtual_dtor ? 'virtual ' : '') . '~' . $cpp_name . '();';
+
+ return $code_string;
+}
+
+sub gobj_protos_str ($$$$)
+{
+ my ($c_name, $copy_proto, $reinterpret, $definitions) = @_;
+ my $gobj = ($reinterpret ? 'reinterpret_cast< ' . $c_name . '* >(gobject_)' : 'gobject_');
+ my $code_string = nl (' /// Provides access to the underlying C instance.') .
+ nl (' ' . $c_name . '* gobj()' . ($definitions ? ' { return ' . $gobj . '; }' : ';')) .
+ nl () .
+ nl (' /// Provides access to the underlying C instance.') .
+ ' const ' . $c_name . '* gobj() const' . ($definitions ? ' { return ' . $gobj . '; }' : ';');
+
+ if ($copy_proto ne 'no')
+ {
+ $code_string = nl ($code_string) .
+ nl () .
+ nl (' /// Provides access to the underlying C instance. The caller is responsible for freeing it. Use when directly setting fields in structs.') .
+ ' ' . $c_name . '* gobj_copy()';
+ if ($copy_proto eq 'const')
+ {
+ $code_string += ' const';
+ }
+ elsif ($copy_proto ne 'yes')
+ {
+ die;
+ }
+ $code_string += ';';
+ }
+ return $code_string;
+}
+
+sub _get_prefixed_name ($$$)
+{
+ my ($wrap_parser, $name, $name_type) = @_;
+ my $prefixed_name = undef;
+
+ given ($name_type)
+ {
+ when (Common::Constants::CLASS)
+ {
+ my $complete_type = get_complete_cpp_type $wrap_parser;
+
+ $complete_type =~ s/::/_/g;
+ $prefixed_name = join '_', $complete_type, $name;
+ }
+ when (Common::Constants::NAMESPACE)
+ {
+ my $full_namespace = get_full_namespace $wrap_parser;
+
+ $full_namespace =~ s/::/_/g;
+ $prefixed_name = join '_', $full_namespace, $name;
+ }
+ when (Common::Constants::FILE)
+ {
+ $prefixed_name = $name;
+ }
+ when (Common::Constants::FIRST_NAMESPACE)
+ {
+ my $first_namespace = get_first_namespace $wrap_parser;
+ my $first_namespace_number = $wrap_parser->get_first_namespace_number;
+
+ $prefixed_name = join '_', $first_namespace, $first_namespace_number, $name;
+ }
+ when (Common::Constants::FIRST_CLASS)
+ {
+ my $full_namespace = get_full_namespace $wrap_parser;
+ my $first_class = get_first_class $wrap_parser;
+ my $first_class_number = $wrap_parser->get_first_class_number;
+
+ $full_namespace =~ s/::/_/g;
+
+ $prefixed_name = join '_', $full_namespace, $first_class, $first_class_number, $name;
+ }
+ default
+ {
+ die;
+ }
+ }
+
+ return $prefixed_name;
+}
+
+sub get_variable ($$)
+{
+ my ($wrap_parser, $variable) = @_;
+
+ return _get_prefixed_name $wrap_parser, $variable->[0], $variable->[1];
+}
+
+sub get_section ($$)
+{
+ my ($wrap_parser, $section) = @_;
+
+ return _get_prefixed_name $wrap_parser, $section->[0], $section->[1];
+}
+
+sub ifdef ($)
+{
+ my ($ifdef) = @_;
+
+ if ($ifdef)
+ {
+ my $str = nl ('#ifdef ' . $ifdef) .
+ nl ();
+
+ return $str;
+ }
+
+ return '';
+}
+
+sub endif ($)
+{
+ my ($ifdef) = @_;
+
+ if ($ifdef)
+ {
+ my $str = nl ('#endif // ' . $ifdef) .
+ nl();
+
+ return $str;
+ }
+
+ return '';
+}
+
+sub paramzipstr ($$)
+{
+ my ($array1, $array2) = @_;
+ my $count = @{$array1};
+
+# TODO: throw runtime error or internal error or whatever.
+ die if $count != scalar(@{$array2});
+ return join ', ', map { join ' ', $array1->[$_], $array2->[$_] } 0 .. $count;
+}
+
+sub get_parent_from_object ($$)
+{
+ my ($wrap_parser, $object) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $variable = get_variable $wrap_parser, Common::Variables::IS_INTERFACE;
+ my $code_string = '';
+
+ if ($section_manager->get_variable ($variable))
+ {
+ $code_string = (nl 'g_type_interface_peek_parent( // Get the parent interface of the interface (The original underlying C inteface)') .
+ (nl ' g_type_interface_peek(G_OBJECT_GET_CLASS(', $object, '), CppObjectType::get_type()) // Get the interface.') .
+ ' )';
+ }
+ else
+ {
+ $code_string = 'g_type_class_peek_parent(G_OBJECT_GET_CLASS(' . $object . ')) // Get the parent class of the object class (The original underlying C class).';
+ }
+
+ return $code_string;
+}
+
+sub convzipstr ($$$$$)
+{
+ my ($wrap_parser, $from_types, $to_types, $transfers, $from_names) = @_;
+ my $conversions_store = $wrap_parser->get_conversions_store;
+ my $from_types_count = @{$from_types};
+ my $to_types_count = @{$to_types};
+ my $transfers_count = @{$transfers};
+ my $from_names_count = @{$from_names};
+
+# TODO: throw runtime error or internal error or whatever.
+ die if $from_types_count != $to_types_count or $to_types_count != $transfers_count or $transfers_count != $from_names_count;
+ return join ', ', map { $conversions_store->get_conversion ($from_types->[$_], $to_types->[$_], $transfers->[$_], $from_names->[$_]) } 0 .. $from_types_count;
+}
+
+sub deprecate_start ($)
+{
+ my ($wrap_parser) = @_;
+ my $mm_module = $wrap_parser->get_mm_module;
+
+ return (nl '#ifdef ' . (uc $mm_module) . '_DISABLE_DEPRECATED') .
+ (nl);
+}
+
+sub deprecate_end ($)
+{
+ my ($wrap_parser) = @_;
+ my $mm_module = $wrap_parser->get_mm_module;
+
+ return (nl '#endif // ' . (uc $mm_module) . '_DISABLE_DEPRECATED') .
+ (nl);
+
+}
1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/Signal.pm b/tools/pm/Common/Output/Signal.pm
new file mode 100644
index 0000000..f1ffd92
--- /dev/null
+++ b/tools/pm/Common/Output/Signal.pm
@@ -0,0 +1,359 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::Signal module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::Signal;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$$$)
+{
+ my ($wrap_parser, $ifdef, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $cpp_param_types_str = join ', ', @{$cpp_param_types};
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ nl (' Glib::SignalProxy' . (scalar @{$cpp_param_types}) . '< ' . $cpp_return_type . ', ' . $cpp_param_types_str . ' > signal_' . $cpp_signal_name . '();') .
+ nl () .
+ Common::Output::Shared::endif $ifdef;
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+
+ if ($default_signal_handler_enabled)
+ {
+ $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ nl (' virtual ' . $cpp_return_type . ' on_' . $cpp_signal_name . '(' . $cpp_param_types_str . ');') .
+ nl () .
+ Common::Output::Shared::endif $ifdef;
+
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::H_DEFAULT_SIGNAL_HANDLERS;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+ }
+}
+
+sub _output_p_h ($$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_signal_name, $c_param_types, $c_param_names, $default_signal_handler_enabled) = @_;
+
+ if ($default_signal_handler_enabled)
+ {
+ my $section_manager = $wrap_parset->get_section_manager;
+ my $c_params_str = Common::Output::Shared::paramzipstr $c_param_types, $c_param_names;
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ nl (' static ' . $c_return_type . ' ' . $c_signal_name . '_callback(' . $c_params_str . ');') .
+ nl () .
+ Common::Output::Shared::endif $ifdef;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_DEFAULT_SIGNAL_HANDLERS;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+ }
+}
+
+sub _output_cc ($$$$$$$$$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_signal_string, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $custom_c_callback, $default_signal_handler_enabled) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $signal_prefix = $full_cpp_type;
+ my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+
+ $signal_prefix =~ s/::/_/g;
+
+ my $proxy_info = $signal_prefix . '_signal_' . $cpp_signal_name . '_info';
+ my $ret_void = ($c_return_type eq 'void');
+ my $cpp_param_types_str = join ', ', @cpp_param_types;
+ my $conversions_store = $wrap_parser->get_conversions_store;
+ my $code_string = Common::Output::Shared::ifdef $ifdef;
+
+ if ($ret_void and not @{$c_param_types} and $cpp_return_type eq 'void' and not @{$cpp_param_types})
+ {
+ $code_string += nl ('// Use predefined callback for SignalProxy0<void> to reduce code size.') .
+ nl ('const Glib::SignalProxyInfo ' . $proxy_info . ' =') .
+ nl ('{') .
+ nl (' ' . $c_signal_string . ',') .
+ nl (' G_CALLBACK(&Glib::SignalProxyNormal::slot0_void_callback),') .
+ nl (' G_CALLBACK(&Glib::SignalProxyNormal::slot0_void_callback)') .
+ nl ('};') .
+ nl ();
+ }
+ else
+ {
+ my $signal_callback = $signal_prefix . '_signal_' . $cpp_signal_name . '_callback';
+ my $signal_notify = undef;
+
+ if ($ret_void)
+ {
+ $signal_notify = $signal_callback;
+ }
+ else
+ {
+ $signal_notify = $signal_prefix . '_signal_' . $cpp_signal_name . '_notify_callback';
+ }
+ unless ($custom_c_callback)
+ {
+ my $callback_cpp_params_str = Common::Output::Shared::convzipstr $wrap_parser, $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
+ my $c_params_str = Common::Output::Shared::paramzipstr $c_param_types, $c_param_names;
+ my $partial_return_string = '(*static_cast<SlotType*>(slot))(' . $callback_cpp_params_str . ')';
+ my $return_string = $partial_return_string;
+ my $last_return = '';
+
+ unless ($ret_void)
+ {
+ if ($c_return_transfer == Common::ConversionsStore and $c_return_type =~ /\*$/)
+ {
+# TODO: print a warning - pointers returned from signals ought to have ownership transferred fully.
+# TODO continued: need warning or error with fixed line number for this.
+ }
+ my $conv = $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $return_string);
+
+ $return_string = 'return ' . $conv;
+ $last_return = nl () .
+ nl (' typedef ' . $c_return_type . ' RType;') .
+ nl (' return RType();');
+ }
+ $code_string += nl ($c_return_type . ' ' . $signal_callback . '(' . $c_type . '* self, ' . $c_params_str . ', gpointer data)') .
+ nl ('{') .
+ nl (' using namespace ' . (Common::Output::Shared::get_full_namespace $wrap_parser) . ';') .
+ nl (' typedef sigc::slot< ' . $cpp_return_type . ', ' . $cpp_param_types_str . ' > SlotType;') .
+ nl () .
+ nl (' // Do not try to call a signal on a disassociated wrapper.') .
+ nl (' if (Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self)))') .
+ nl (' {') .
+ nl (' try') .
+ nl (' {') .
+ nl (' sigc::slot_base* const slot(Glib::SignalProxyNormal::data_to_slot(data));') .
+ nl () .
+ nl (' if (slot)') .
+ nl (' {') .
+ nl (' ' . $return_string . ';') .
+ nl (' }') .
+ nl (' }') .
+ nl (' catch (...)') .
+ nl (' {') .
+ nl (' Glib::exception_handlers_invoke();') .
+ nl (' }') .
+ nl (' }') .
+ nl ($last_return . '}') .
+ nl ();
+ unless ($ret_void)
+ {
+ $code_string += nl ($c_return_type . ' ' . $signal_notify . '(' . $c_type . '* self, ' . $c_params_str . ', gpointer data)') .
+ nl ('{') .
+ nl (' using namespace ' . (Common::Output::Shared::get_full_namespace $wrap_parser) . ';') .
+ nl (' typedef sigc::slot< void, ' . $cpp_param_types_str . ' > SlotType;') .
+ nl () .
+ nl (' // Do not try to call a signal on disassociated wrapper.') .
+ nl (' if (Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self)))') .
+ nl (' {') .
+ nl (' try') .
+ nl (' {') .
+ nl (' if (sigc::slot_base* const slot = Glib::SignalProxyNormal::data_to_slot(data))') .
+ nl (' {') .
+ nl (' ' . $partial_return_string . ';') .
+ nl (' }') .
+ nl (' }') .
+ nl (' catch (...)') .
+ nl (' {') .
+ nl (' Glib::exception_handlers_invoke();') .
+ nl (' }') .
+ nl (' }') .
+ nl () .
+ nl (' typedef ' . $c_return_type . ' RType;') .
+ nl (' return RType();') .
+ nl ('}') .
+ nl ();
+ }
+ }
+ $code_string += nl ('const Glib::SignalProxyInfo ' . $proxy_info . ' =') .
+ nl ('{') .
+ nl (' ' . $c_signal_string . ',') .
+ nl (' G_CALLBACK(&' . $signal_callback . '),') .
+ nl (' G_CALLBACK(&' . $signal_notify . ')') .
+ nl ('};') .
+ nl ();
+ }
+
+ $code_string += Common::Output::Shared::endif $ifdef;
+
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_UNNAMED_NAMESPACE;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+
+ my $signal_proxy_type = 'Glib::SignalProxy' . (scalar @{$cpp_param_types}) . '< ' . $cpp_return_type . ', ' . $cpp_param_types_str . ' >';
+
+ $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ nl ($signal_proxy_type . ' ' . $full_cpp_type . '::signal_' . $cpp_signal_name . '()') .
+ nl ('{') .
+ nl (' ' . $signal_proxy_type . '(this, &' . $proxy_info . ');') .
+ nl ('}') .
+ nl () .
+ Common::Output::Shared::endif $endif;
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_SIGNAL_PROXIES;
+ $section_manager->append_string_to_section ($code_string, $section);
+
+ if ($default_signal_handler_enabled)
+ {
+ $code_string = Common::Output::Shared::ifdef $ifdef;
+
+ my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'gobject_';
+ my $cpp_params_str = Common::Output::paramzipstr $cpp_param_types, $cpp_param_names;
+ my $cpp_to_c_params_str = Common::Output::Shared::convzipstr $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names;
+ my $c_func_invocation = '(*base->' . $c_signal_name . ')(gobj(), ' . $cpp_to_c_params_str . ')';
+ my $last_return = '';
+
+ $code_string += nl ($cpp_return_type . ' ' . $full_cpp_type . '::on_' . $cpp_signal_name . '(' . $cpp_params_str . ')') .
+ nl ('{') .
+ nl (' BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+ nl () .
+ nl (' if (base && base->' . $c_signal_name . ')') .
+ nl (' {');
+
+ if ($ret_void)
+ {
+ $code_string += nl (' ' . $c_func_invocation . ';') .
+ }
+ else
+ {
+ my $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
+
+ $code_string += nl (' return ' . $conv . ';');
+ $last_return = nl () .
+ nl (' typedef ' . $cpp_return_type . ' RType;') .
+ nl (' return RType();');
+
+ }
+
+ $code_string += nl (' }') .
+ nl($last_return . '}') .
+ Common::Output::Shared::endif $ifdef;
+
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_DEFAULT_SIGNAL_HANDLERS;
+ $section_manager->append_string_to_section ($code_string, $section);
+ }
+}
+
+sub _output_p_cc ($$$$$$$$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled) = @_;
+
+ if ($default_signal_handler_enabled)
+ {
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_DEFAULT_SIGNAL_HANDLERS;
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ nl (' klass->' . $c_signal_name . ' = &' . $c_signal_name . '_callback;') .
+ nl () .
+ Common::Output::Shared::endif $ifdef;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+
+ my $c_params_str = Common::Output::Shared::zupstr $c_param_types, $c_param_names, ' ', ', ';
+ my $ret_void = ($c_return_type eq 'void');
+ my $conversions_store = $wrap_parser->get_conversions_store;
+ my $convs_str = Common::Output::Shared::convzipstr $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
+ my $vfunc_call = 'obj->on_' . $cpp_signal_name . '(' . $convs_str . ')';
+ my $c_callback_call = '(*base->' . $c_signal_name . '(self, ' . (join ', ', @{$c_param_names}) . ')';
+ my $last_return = '';
+
+ unless ($ret_void)
+ {
+ $vfunc_call = 'return ' . $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
+ $c_callback_call = 'return ' . $c_callback_call;
+ $last_return = nl () .
+ nl (' typedef ' . $c_return_type . ' RType;') .
+ ' return RType();';
+ }
+ else
+ {
+ $vfunc_call = nl ($vfunc_call . ';') .
+ nl (' return');
+ }
+
+ my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'self';
+ my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+
+ $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ nl ($c_return_type . ' ' . $cpp_class_type . '::' . $c_signal_name . '_callback(' . $c_type . '* self, ' . $c_params_str . ')') .
+ nl ('{') .
+ nl (' // First, do a simple cast to ObjectBase. We will have to do a dynamic cast') .
+ nl (' // eventually, but it is not necessary to check whether we need to call') .
+ nl (' // the vfunc.') .
+ nl (' Glib::ObjectBase* const obj_base(static_cast<Glib::ObjectBase*>(') .
+ nl (' Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self))));') .
+ nl (' // Non-gmmproc-generated custom classes implicitly call the default') .
+ nl (' // Glib::ObjectBase constructor, which sets is_derived_. But gmmproc-generated') .
+ nl (' // classes can use this optimisation, which avoids the unnecessary parameter') .
+ nl (' // parameter conversions if there is no possibility of the virtual function being') .
+ nl (' // overriden:') .
+ nl (' if (obj_base && obj_base->is_derived_())') .
+ nl (' {') .
+ nl (' // We need to do a dynamic cast to get the real object type, to call the C++') .
+ nl (' // vfunc on it.') .
+ nl (' CppObjectBase* const obj(dynamic_cast<CppObjectType* const>(obj_base));') .
+ nl () .
+ nl (' if (obj) // This can be NULL during destruction.') .
+ nl (' {') .
+ nl (' try // Trap C++ exceptions which would normally be lost because this is a C callback.') .
+ nl (' {') .
+ nl (' // Call the virtual member method, which derived classes might override.') .
+ nl (' ' . $vfunc_call . ';')
+ nl (' }') .
+ nl (' catch (...)') .
+ nl (' {') .
+ nl (' Glib::exception_handlers_invoke();') .
+ nl (' }') .
+ nl (' }') .
+ nl (' }') .
+ nl () .
+ nl (' BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+ nl () .
+ nl (' // Call the original underlying C function:') .
+ nl (' if (base && base->' . $c_signal_name . ')') .
+ nl (' {') .
+ nl (' ' . $c_callback_call . ';') .
+ nl (' }' ) .
+ nl ($last_return . '}') .
+ nl () .
+ (Common::Output::Shared::endif $ifdef);
+
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_DEFAULT_SIGNAL_HANDLERS;
+ $section_manager->append_string_to_section ($code_string, $section);
+ }
+}
+
+# TODO: Add custom_signal_handler.
+sub output ($$$$$$$$$$$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_signal_string, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $cpp_param_names, $custom_c_callback, $default_signal_handler_enabled) = @_;
+
+ _output_h $wrap_parser, $ifdef, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled;
+ _output_p_h $wrap_parser, $ifdef, $c_return_type, $c_signal_name, $c_param_types, $c_param_names, $default_signal_handler_enabled;
+ _output_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_signal_string, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $custom_c_callback, $default_signal_handler_enabled;
+ _output_p_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_signal_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_signal_name, $cpp_param_types, $default_signal_handler_enabled;
+}
+
+1; # indicate proper module load.
diff --git a/tools/pm/Common/Output/VFunc.pm b/tools/pm/Common/Output/VFunc.pm
new file mode 100644
index 0000000..f24978a
--- /dev/null
+++ b/tools/pm/Common/Output/VFunc.pm
@@ -0,0 +1,255 @@
+# -*- mode: perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# gmmproc - Common::Output::VFunc module
+#
+# Copyright 2012 glibmm development team
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+#
+
+package Common::Output::VFunc;
+
+use strict;
+use warnings;
+
+sub nl
+{
+ return Common::Output::Shared::nl @_;
+}
+
+sub _output_h ($$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $main_section = $wrap_parser->get_main_section;
+ my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ (nl 'virtual ', $cpp_return_type, ' ', $cpp_vfunc_name, '(', $cpp_params_str, ($const ? ') const;' : ');')) .
+ (nl) .
+ Common::Output::Shared::endif $ifdef;
+
+ $section_manager->append_string_to_section ($code_string, $main_section);
+}
+
+sub _output_p_h ($$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_vfunc_name, $c_param_types, $c_param_names, $errthrow) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $c_params_str = (Common::Output::Shared::paramzipstr $c_param_types, $c_param_names) . ($errthrow ? ', GError** gerror' : '');
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ (nl ' static ', $c_return_type, ' ', $c_vfunc_name, '_vfunc_callback(', $c_params_str, ');') .
+ (nl) .
+ Common::Output::Shared::endif $ifdef;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_H_VFUNCS;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub _output_cc ($$$$$$$$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const, $errthrow) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $full_cpp_type = Common::Output::Shared::get_full_cpp_type $wrap_parser;
+ my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'gobject_';
+ my $cpp_params_str = Common::Output::Shared::paramzipstr $cpp_param_types, $cpp_param_names;
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ (nl $cpp_return_type, ' ', $full_cpp_type, '::', $cpp_vfunc_name, '(', $cpp_params_str, ($const ? ') const' : ')')) .
+ (nl '{') .
+ (nl ' BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+ (nl) .
+ (nl ' if (base && base->' . $c_vfunc_name . ')') .
+ (nl ' {');
+ my $ret_void = ($cpp_return_type eq 'void');
+ my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+ my $gobj = ($const ? 'const_cast< ' . $c_type . ' >(gobj())' : 'gobj()');
+ my $cpp_to_c_params_str = (Common::Output::Shared::convzipstr $wrap_parser, $cpp_param_types, $c_param_types, $c_param_transfers, $cpp_param_names) . ($errthrow ? ', &temp_error' : '');
+ my $c_func_invocation = join '', '(*base->', $c_vfunc_name, ')(', $gobj, ', ', $cpp_to_c_params_str . ')';
+ my $last_return = '';
+ my $conversions_store = $wrap_parser->get_conversions_store;
+ my $error_init_string = (nl ' GError* temp_error(0);');
+ my $errthrow_string = (nl ' if (temp_error)') .
+ (nl ' {') .
+ (nl ' ::Glib::Error::throw_exception(temp_error);') .
+ (nl ' }');
+
+ if ($ret_void)
+ {
+ if ($errthrow)
+ {
+ $code_string += $error_init_string .
+ (nl) .
+ (nl ' ', $c_func_invocation, ';') .
+ (nl) .
+ $errthrow_string .
+ (nl) .
+ (nl ' return;');
+ }
+ else
+ {
+ $code_string += (nl ' ', $c_func_invocation, ';') .
+ (nl ' return;');
+ }
+ }
+ else
+ {
+ my $conv = '';
+
+ if ($errthrow)
+ {
+ $code_string += $error_init_string .
+ (nl ' ', $c_return_type, ' temp_retval(', $c_func_invocation, ');') .
+ (nl) .
+ $errthrow_string .
+ (nl);
+ $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, 'temp_retval');
+ }
+ else
+ {
+ $conv = $conversions_store->get_conversion ($c_return_type, $cpp_return_type, $c_return_transfer, $c_func_invocation);
+ }
+ $code_string += nl (' return ' . $conv . ';');
+ $last_return = (nl) .
+ (nl ' typedef ' . $cpp_return_type . ' RType;') .
+ (nl ' return RType();');
+ }
+ $code_string += (nl ' }') .
+ (nl $last_return . '}') .
+ Common::Output::Shared::endif $ifdef;
+
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::CC_VFUNCS;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub _output_p_cc ($$$$$$$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $errthrow) = @_;
+ my $section_manager = $wrap_parser->get_section_manager;
+ my $cpp_class_type = Common::Output::Shared::get_cpp_class_type $wrap_parser;
+ my $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_INIT_VFUNCS;
+ my $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ (nl ' klass->' . $c_vfunc_name . ' = &' . $c_vfunc_name . '_vfunc_callback;') .
+ (nl) .
+ Common::Output::Shared::endif $ifdef;
+
+ $section_manager->append_string_to_section ($code_string, $section);
+
+ my $c_params_str = (Common::Output::Shared::paramzipstr $c_param_types, $c_param_names) . ($errthrow ? ', GError** gerror' : '');
+ my $ret_void = ($c_return_type eq 'void');
+ my $conversions_store = $wrap_parser->get_conversions_store;
+ my $convs_str = Common::Output::Shared::convzipstr $wrap_parser, $c_param_types, $cpp_param_types, $c_param_transfers, $c_param_names;
+ my $vfunc_call = 'obj->' . $cpp_vfunc_name . '(' . $convs_str . ')';
+ my $c_callback_call = '(*base->' . $c_vfunc_name . '(self, ' . (join ', ', @{$c_param_names}) . ($errthrow ? ', gerror' : '') . ')';
+ my $last_return = '';
+ my $after_catch_return = '';
+
+ unless ($ret_void)
+ {
+ $vfunc_call = 'return ' . $conversions_store->get_conversion ($cpp_return_type, $c_return_type, $c_return_transfer, $vfunc_call);
+ $c_callback_call = 'return ' . $c_callback_call;
+ $after_catch_return = (nl) .
+ (nl ' typedef ', $c_return_type, ' RType;') .
+ (nl ' return RType();');
+ $last_return = (nl) .
+ (nl ' typedef ' . $c_return_type . ' RType;') .
+ ' return RType();';
+ }
+ else
+ {
+ $vfunc_call = (nl $vfunc_call . ';') .
+ (nl ' return');
+ $after_catch_return = (nl) .
+ (nl ' return;');
+ }
+
+ my $parent_from_object = Common::Output::Shared::get_parent_from_object $wrap_parser, 'self';
+ my $c_type = Common::Output::Shared::get_c_type $wrap_parser;
+
+ $code_string = (Common::Output::Shared::ifdef $ifdef) .
+ (nl $c_return_type, ' ', $cpp_class_type . '::' . $c_vfunc_name . '_vfunc_callback(', $c_type, '* self, ', $c_params_str, ')') .
+ (nl '{') .
+ (nl ' // First, do a simple cast to ObjectBase. We will have to do a dynamic cast') .
+ (nl ' // eventually, but it is not necessary to check whether we need to call') .
+ (nl ' // the vfunc.') .
+ (nl ' Glib::ObjectBase* const obj_base(static_cast<Glib::ObjectBase*>(') .
+ (nl ' Glib::ObjectBase::_get_current_wrapper(static_cast<GObject*>(self))));') .
+ (nl ' // Non-gmmproc-generated custom classes implicitly call the default') .
+ (nl ' // Glib::ObjectBase constructor, which sets is_derived_. But gmmproc-generated') .
+ (nl ' // classes can use this optimisation, which avoids the unnecessary parameter') .
+ (nl ' // parameter conversions if there is no possibility of the virtual function being') .
+ (nl ' // overriden:') .
+ (nl ' if (obj_base && obj_base->is_derived_())') .
+ (nl ' {') .
+ (nl ' // We need to do a dynamic cast to get the real object type, to call the C++') .
+ (nl ' // vfunc on it.') .
+ (nl ' CppObjectBase* const obj(dynamic_cast<CppObjectType* const>(obj_base));') .
+ (nl) .
+ (nl ' if (obj) // This can be NULL during destruction.') .
+ (nl ' {') .
+ (nl ' try // Trap C++ exceptions which would normally be lost because this is a C callback.') .
+ (nl ' {') .
+ (nl ' // Call the virtual member method, which derived classes might override.') .
+ (nl ' ' . $vfunc_call . ';') .
+ (nl ' }');
+
+ if ($errthrow)
+ {
+ $code_string += (nl ' catch (const Glib::Error& error)') .
+ (nl ' {') .
+ (nl ' error.propagate(gerror);') .
+ (nl ' }');
+ }
+
+ $code_string += (nl ' catch (...)') .
+ (nl ' {') .
+ (nl ' Glib::exception_handlers_invoke();') .
+ (nl ' }') .
+ $after_catch_return .
+ (nl ' }') .
+ (nl ' }') .
+ (nl) .
+ (nl ' BaseClassType* const base(static_cast<BaseClassType*>(' . $parent_from_object . '));') .
+ (nl) .
+ (nl ' // Call the original underlying C function:') .
+ (nl ' if (base && base->' . $c_vfunc_name . ')') .
+ (nl ' {') .
+ (nl ' ' . $c_callback_call . ';') .
+ (nl ' }' ) .
+ (nl $last_return . '}') .
+ (nl) .
+ (Common::Output::Shared::endif $ifdef);
+
+ $section = Common::Output::Shared::get_section $wrap_parser, Common::Sections::P_CC_VFUNCS;
+ $section_manager->append_string_to_section ($code_string, $section);
+}
+
+sub output ($$$$$$$$$$$$$$$$)
+{
+ my ($wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const, $custom_vfunc, $custom_vfunc_callback, $errthrow) = @_;
+
+ _output_h $wrap_parser, $ifdef, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const;
+ _output_p_h $wrap_parser, $ifdef, $c_return_type, $c_vfunc_name, $c_param_types, $c_param_names, $errthrow;
+
+ unless ($custom_vfunc)
+ {
+ _output_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $cpp_param_names, $const, $errthrow;
+ }
+
+ unless ($custom_vfunc_callback)
+ {
+ _output_p_cc $wrap_parser, $ifdef, $c_return_type, $c_return_transfer, $c_vfunc_name, $c_param_types, $c_param_names, $c_param_transfers, $cpp_return_type, $cpp_vfunc_name, $cpp_param_types, $errthrow;
+ }
+}
+
+1; # indicate proper module load.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]