[glibmm/gmmproc-refactor] Add OldOutput.



commit 36fe3af08bda34ac8fc7c8ba79c65dca76d18008
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Sat Apr 7 16:34:03 2012 +0200

    Add OldOutput.
    
    Maybe will be helpful in future to check how something was
    implemented.

 tools/pm/Common/OldOutput.pm | 1091 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 1091 insertions(+), 0 deletions(-)
---
diff --git a/tools/pm/Common/OldOutput.pm b/tools/pm/Common/OldOutput.pm
new file mode 100644
index 0000000..e1a5ff0
--- /dev/null
+++ b/tools/pm/Common/OldOutput.pm
@@ -0,0 +1,1091 @@
+# Gtkmmproc Output module
+#
+# Copyright 2001 Free Software Foundation
+#
+# 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 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, "    ");
+
+  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);
+}
+
+1; # indicate proper module load.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]