[glibmm/gmmproc-refactor] Add support for optional and out parameters.



commit bdb6d6284053ab7e0487373c0306d0434fcea5f8
Author: Krzesimir Nowak <qdlacz gmail com>
Date:   Mon Jun 11 04:41:07 2012 +0200

    Add support for optional and out parameters.
    
    Optional parameters are denoted by {?} and out ones by either
    old {RET} or new {OUT}.

 tools/pm/Common/CxxFunctionInfo.pm |   30 ++++++++++
 tools/pm/Common/Output/Method.pm   |   12 +++--
 tools/pm/Common/Output/Shared.pm   |  106 ++++++++++++++++++++++++++++++++++--
 tools/pm/Common/Shared.pm          |   47 +++++++++++-----
 tools/pm/Common/WrapParser.pm      |    3 +
 tools/pm/TODO                      |    4 ++
 6 files changed, 179 insertions(+), 23 deletions(-)
---
diff --git a/tools/pm/Common/CxxFunctionInfo.pm b/tools/pm/Common/CxxFunctionInfo.pm
index 3c72406..ea47a2f 100644
--- a/tools/pm/Common/CxxFunctionInfo.pm
+++ b/tools/pm/Common/CxxFunctionInfo.pm
@@ -36,12 +36,18 @@ sub new_from_string ($$)
   my $params = Common::Shared::parse_params $cxx_parts->[3];
   my $param_types = [];
   my $param_names = [];
+  my $param_values = [];
+  my $param_nullables = [];
+  my $param_outs = [];
   my $const = ($cxx_parts->[4] =~ /\bconst\b/);
 
   foreach my $desc (@{$params})
   {
     push @{$param_types}, $desc->{'type'};
     push @{$param_names}, $desc->{'name'};
+    push @{$param_values}, $desc->{'value'};
+    push (@{$param_nullables}, $desc->{'nullable'});
+    push (@{$param_outs}, $desc->{'out'});
   }
 
   $params = undef;
@@ -53,6 +59,9 @@ sub new_from_string ($$)
     'name' => $name,
     'param_types' => $param_types,
     'param_names' => $param_names,
+    'param_values' => $param_values,
+    'param_nullables' => $param_nullables,
+    'param_outs' => $param_outs,
     'const' => $const
   };
 
@@ -94,6 +103,27 @@ sub get_param_names ($)
   return $self->{'param_names'};
 }
 
+sub get_param_values ($)
+{
+  my ($self) = @_;
+
+  return $self->{'param_values'};
+}
+
+sub get_param_nullables ($)
+{
+  my ($self) = @_;
+
+  return $self->{'param_nullables'};
+}
+
+sub get_param_outs ($)
+{
+  my ($self) = @_;
+
+  return $self->{'param_outs'};
+}
+
 sub get_const ($)
 {
   my ($self) = @_;
diff --git a/tools/pm/Common/Output/Method.pm b/tools/pm/Common/Output/Method.pm
index c87f934..725ba80 100644
--- a/tools/pm/Common/Output/Method.pm
+++ b/tools/pm/Common/Output/Method.pm
@@ -191,12 +191,16 @@ sub _output_cc ($$$$$$$$$$$$$$$$)
   $section_manager->append_string_to_section ($code_string, $section);
 }
 
-sub output ($$$$$$$$$$$$$$$$)
+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) = @_;
+  my ($wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $cpp_param_types, $cpp_param_names, $cxx_param_nullables, $const, $constversion, $deprecated, $ifdef, $c_ret_type, $ret_transfer, $c_func_name, $c_param_types, $c_param_transfers, $errthrow) = @_;
+  my $permutations = Common::Output::Shared::get_types_permutations ($cpp_param_types, $cxx_param_nullables);
 
-  _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;
+  foreach my $permutation (@{$permutations})
+  {
+    _output_h $wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $permutation, $cpp_param_names, $const;
+    _output_cc $wrap_parser, $static, $cpp_ret_type, $cpp_func_name, $permutation, $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/Shared.pm b/tools/pm/Common/Output/Shared.pm
index 7f41ada..494dc25 100644
--- a/tools/pm/Common/Output/Shared.pm
+++ b/tools/pm/Common/Output/Shared.pm
@@ -560,12 +560,26 @@ sub endif ($)
 
 sub paramzipstr ($$)
 {
-  my ($array1, $array2) = @_;
-  my $count = @{$array1};
+  my ($types, $names) = @_;
+  my $count = @{$types};
 
 # TODO: throw runtime error or internal error or whatever.
-  die if $count != scalar(@{$array2});
-  return join ', ', map { join ' ', $array1->[$_], $array2->[$_] } 0 .. $count - 1;
+  die if ($count != scalar (@{$names}));
+
+  my @params = ();
+
+  foreach my $index (0 .. $count - 1)
+  {
+    my $type = $types->[$index];
+    my $name = $names->[$index];
+
+    if (defined ($type))
+    {
+      push (@params, join (' ', $type, $name));
+    }
+  }
+
+  return join (', ', @params);
 }
 
 sub get_parent_from_object ($$)
@@ -600,7 +614,28 @@ sub convzipstr ($$$$$)
 
 # 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 { $type_info_local->get_conversion ($from_types->[$_], $to_types->[$_], $transfers->[$_], $from_names->[$_]) } 0 .. $from_types_count - 1;
+
+  my @conversions = ();
+
+  foreach my $index (0 .. $from_types_count - 1)
+  {
+    if (defined ($from_types->[$index]))
+    {
+      push (@conversions,
+            $type_info_local->get_conversion ($from_types->[$index],
+                                              $to_types->[$index],
+                                              $transfers->[$index],
+                                              $from_names->[$index]));
+    }
+    else
+    {
+# TODO: consider using C++11 nullptr
+      push (@conversions,
+            join ('', 'static_cast< ', $to_types->[$index], ' >(0)'));
+    }
+  }
+
+  return join (', ', @conversions);
 }
 
 sub deprecate_start ($)
@@ -647,4 +682,65 @@ sub already_included ($$)
   return 1;
 }
 
+sub get_types_permutations;
+
+sub get_types_permutations
+{
+  my ($param_types, $param_nullables, $index) = @_;
+
+  unless (defined ($index))
+  {
+    $index = 0;
+  }
+
+  my $count = @{$param_types};
+
+  unless ($count)
+  {
+    return [[]];
+  }
+
+  if ($index == $count - 1)
+  {
+    my $permutations = [[$param_types->[$index]]];
+
+    if ($param_nullables->[$index])
+    {
+      push (@{$permutations}, [undef]);
+    }
+
+    return $permutations;
+  }
+
+  my $tail_permutations = get_types_permutations ($param_types, $param_nullables, $index + 1);
+
+  if ($param_nullables->[$index])
+  {
+    my $permutations = [];
+
+    foreach my $tail_permutation (@{$tail_permutations})
+    {
+      push (@{$permutations}, [$param_types->[$index],
+                               @{$tail_permutation}]);
+    }
+
+    foreach my $tail_permutation (@{$tail_permutations})
+    {
+      push (@{$permutations}, [undef,
+                               @{$tail_permutation}]);
+    }
+
+    return $permutations;
+  }
+  else
+  {
+    foreach my $tail_permutation (@{$tail_permutations})
+    {
+      unshift (@{$tail_permutation}, $param_types->[$index]);
+    }
+
+    return $tail_permutations;
+  }
+}
+
 1; # indicate proper module load.
diff --git a/tools/pm/Common/Shared.pm b/tools/pm/Common/Shared.pm
index cca770e..384ac32 100644
--- a/tools/pm/Common/Shared.pm
+++ b/tools/pm/Common/Shared.pm
@@ -169,12 +169,12 @@ sub string_split_func_params ($)
   my @out = ();
   my $level = 0;
   my $str = '';
-  my @tokens = split(/([,()"'\\<>])/, $in);
+  my @tokens = split (/([,()"'\\<>{}])/, $in);
   my $sq = 0;
   my $dq = 0;
   my $escape = 0;
   my @close_stack = ();
-  my %closes = ('(' => ')', '<' => '>');
+  my %closes = ('(' => ')', '<' => '>', '{' => '}');
 
   while (@tokens)
   {
@@ -220,12 +220,12 @@ sub string_split_func_params ($)
     {
       $dq = 1;
     }
-    elsif ($token eq '(' or $token eq '<')
+    elsif ($token eq '(' or $token eq '<' or $token eq '{')
     {
       ++$level;
       push @close_stack, $closes{$token};
     }
-    elsif ($token eq ')' or $token eq '>')
+    elsif ($token eq ')' or $token eq '>' or $token eq '}')
     {
       my $expected = pop @close_stack;
 
@@ -292,27 +292,46 @@ sub parse_params ($)
   {
     my @subparts = split ('=', $part);
     my $value = undef;
-    my $rest = Common::Util::string_trim $subparts[0];
-    my $name = undef;
-    my $type = undef;
+    my $rest = Common::Util::string_trim (shift (@subparts));
 
-    if (@subparts > 1)
+    if (@subparts)
     {
-      $value = join '', $subparts[1 .. @subparts - 1];
+      $value = Common::Util::string_trim (join ('', @subparts));
     }
-    if ($rest =~ /^(.+\W)(\w+)$/)
+    if ($rest =~ /^(.+?)(\w+)(?:{([^}]+)})?$/)
     {
-      $type = $1;
-      $name = $2;
+      my $type = $1;
+      my $name = $2;
+      my $param = $3;
+      my $nullable = 0;
+      my $out = 0;
 
+      given ($param)
+      {
+        when ('?')
+        {
+          $nullable = 1;
+        }
+        when (['OUT', 'RET'])
+        {
+          $out = 1;
+        }
+      }
       $type = _type_fixup $type;
+
+      push (@params,
+            {
+              'type' => $type,
+              'name' => $name,
+              'value' => $value,
+              'nullable' => $nullable,
+              'out' => $out
+            });
     }
     else
     {
       return [];
     }
-
-    push @params, {'type' => $type, 'name' => $name, 'value' => $value};
   }
   return \ params;
 }
diff --git a/tools/pm/Common/WrapParser.pm b/tools/pm/Common/WrapParser.pm
index e24fc53..78dce33 100644
--- a/tools/pm/Common/WrapParser.pm
+++ b/tools/pm/Common/WrapParser.pm
@@ -801,6 +801,9 @@ sub _on_wrap_method ($)
                                   $cxx_function->get_name,
                                   $cxx_function->get_param_types,
                                   $cxx_function->get_param_names,
+                                  # $cxx_function->get_param_values,
+                                  $cxx_function->get_param_nullables,
+                                  # $cxx_function->get_param_outs,
                                   $cxx_function->get_const,
                                   $constversion,
                                   $deprecated,
diff --git a/tools/pm/TODO b/tools/pm/TODO
index 0aa53b5..119b2a3 100644
--- a/tools/pm/TODO
+++ b/tools/pm/TODO
@@ -191,6 +191,10 @@
 
 - Support optional parameter in _WRAP_CTOR, _WRAP_METHOD.
   These are denoted by '{?}' appended to parameter name.
+  IN PROGRESS.
+
+- Support out parameters in _WRAP_METHOD.
+  IN PROGRESS.
 
 - Support default values.
   These should be added to declarations.



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