[glibmm] gmmproc: _WRAP_[CREATE|CTOR|METHOD]: Support parameter reordering.



commit 29da38e4fa01fa4460ca5359e0346f25c7781a5a
Author: José Alburquerque <jaalburqu svn gnome org>
Date:   Mon Jun 6 13:42:54 2011 -0400

    gmmproc: _WRAP_[CREATE|CTOR|METHOD]: Support parameter reordering.
    
    	* tools/pm/Function.pm (param_mappings): Add a new hash member mapping
    	C parameter names to C++ parameter indices.  The map is specified by
    	appending a {name[?]} to the desired C++ parameter name in the C++
    	method declaration.  A '-' in place of a C parameter name means to use
    	the C++ parameter name.
    	(parse_param): Modified to detect parameter mappings and set the
    	appropriate mapping in the above new member.  No mappings occur if
    	none are specified.
    	* tools/pm/Output.pm (convert_args_cpp_to_c):
    	(get_ctor_properties): Modified to use the new C param names to C++
    	param indices mappings member above to allow reordering of parameters
    	in the C++ method declaration.

 ChangeLog            |   17 ++++++
 tools/pm/Function.pm |   76 ++++++++++++++++++--------
 tools/pm/Output.pm   |  144 ++++++++++++++++++++++----------------------------
 3 files changed, 133 insertions(+), 104 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 9a2d62f..0b79821 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2011-06-06  José Alburquerque  <jaalburqu svn gnome org>
+
+	gmmproc: _WRAP_[CREATE|CTOR|METHOD]: Support parameter reordering.
+
+	* tools/pm/Function.pm (param_mappings): Add a new hash member mapping
+	C parameter names to C++ parameter indices.  The map is specified by
+	appending a {name[?]} to the desired C++ parameter name in the C++
+	method declaration.  A '-' in place of a C parameter name means to use
+	the C++ parameter name.
+	(parse_param): Modified to detect parameter mappings and set the
+	appropriate mapping in the above new member.  No mappings occur if
+	none are specified.
+	* tools/pm/Output.pm (convert_args_cpp_to_c):
+	(get_ctor_properties): Modified to use the new C param names to C++
+	param indices mappings member above to allow reordering of parameters
+	in the C++ method declaration.
+
 2011-06-05  José Alburquerque  <jaalburqu svn gnome org>
 
 	gmmproc: Do not use NULL for optional parameters or properties.
diff --git a/tools/pm/Function.pm b/tools/pm/Function.pm
index 841afa3..c80e993 100644
--- a/tools/pm/Function.pm
+++ b/tools/pm/Function.pm
@@ -36,6 +36,7 @@ our @EXPORT_OK;
 #       string array param_name;
 #       string array param_default_value;
 #       bool array param_optional;
+#       hash param_mappings; (maps C param names (if specified) to the C++ index)
 #       string array possible_args_list; (a list of space separated indexes)
 #       string in_module; e.g. Gtk
 #       string signal_when. e.g. first, last, or both.
@@ -75,6 +76,7 @@ sub new($$)
   $$self{param_names} = [];
   $$self{param_default_values} = [];
   $$self{param_optional} = [];
+  $$self{param_mappings} = {};
   $$self{possible_args_list} = [];
   $$self{in_module} = "";
   $$self{class} = "";
@@ -104,7 +106,7 @@ sub new($$)
   {
     $objWrapParser->error("fail to parse $line\n");
   }
-  
+
   # Store the list of possible argument combinations based on if arguments
   # are optional.
   my $possible_args_list = $$self{possible_args_list};
@@ -135,6 +137,7 @@ sub new_ctor($$)
   $$self{param_names} = [];
   $$self{param_default_values} = [];
   $$self{param_optional} = [];
+  $$self{param_mappings} = {};
   $$self{possible_args_list} = [];
   $$self{in_module} = "";
   $$self{class} = "";
@@ -153,7 +156,7 @@ sub new_ctor($$)
   {
     $objWrapParser->error("fail to parse $line\n");
   }
-  
+
   # Store the list of possible argument combinations based on if arguments
   # are optional.
   my $possible_args_list = $$self{possible_args_list};
@@ -184,11 +187,16 @@ sub parse_param($$)
   my $id = 0;
   my $has_value = 0;
   my $is_optional = 0;
+  my $curr_param = 0;
 
   my $param_types = $$self{param_types};
   my $param_names = $$self{param_names};
   my $param_default_values = $$self{param_default_values};
   my $param_optional = $$self{param_optional};
+  my $param_mappings = $$self{param_mappings};
+
+  # Mappings from a C name to this C++ param defaults to empty (no mapping).
+  my $mapping = "";
 
   # clean up space and handle empty case
   $line = string_trim($line);
@@ -201,7 +209,7 @@ sub parse_param($$)
   foreach (split(/(const )|([,=&*()])|(<[^,]*>)|(\s+)/, $line)) #special characters OR <something> OR whitespace.
   {
     next if ( !defined($_) or $_ eq "" );
-      
+
     if ( $_ eq "(" ) #Detect the opening bracket.
     {
        push(@str, $_);
@@ -243,16 +251,26 @@ sub parse_param($$)
       }
 
       $type = string_trim($type);
-      
-	  # Determine if the param is optional (if name ends with {?}).
-      $is_optional = 1 if ($name =~ /\{\?\}$/);
-      $name =~ s/\{\?\}$//;
-      
+
+      # Determine if the param is optional or if a C param name should be
+      # mapped to the current C++ index (if name ends with {c_name?}). (A
+      # '-' for the name means use the C++ as the C name).
+      if ($name =~ /\{\s*(\w*|-)\s*(\??)\s*\}$/)
+      {
+        $is_optional = 1 if($2);
+        $mapping = $1 if($1);
+        $name =~ s/\{\s*(\w|-)*\??\s*\}$//;
+        $mapping = $name if($mapping eq "-");
+      }
+
       push(@$param_types, $type);
       push(@$param_names, $name);
       push(@$param_default_values, $value);
       push(@$param_optional, $is_optional);
-      
+
+      # Map from the c_name to the C++ index (no map if no name given).
+      $$param_mappings{$mapping} = $curr_param if($mapping);
+
       #Clear variables, ready for the next parameter.
       @str = ();
       $type= "";
@@ -260,6 +278,10 @@ sub parse_param($$)
       $has_value = 0;
       $name = "";
       $is_optional = 0;
+      $curr_param++;
+
+      # Mappings from a C name to this C++ param defaults to empty (no mapping).
+      my $mapping = "";
 
       $id = 0;
 
@@ -302,14 +324,24 @@ sub parse_param($$)
 
   $type = string_trim($type);
 
-  # Determine if the param is optional (if name ends with {?}).
-  $is_optional = 1 if ($name =~ /\{\?\}$/);
-  $name =~ s/\{\?\}$//;
-  
+  # Determine if the param is optional or if a C param name should be
+  # mapped to the current C++ index (if name ends with {c_name?}). (A
+  # '-' for the name means use the C++ as the C name).
+  if ($name =~ /\{\s*(\w*|-)\s*(\??)\s*\}$/)
+  {
+    $is_optional = 1 if($2);
+    $mapping = $1 if($1);
+    $name =~ s/\{\s*(\w*|-)\??\s*\}$//;
+    $mapping = $name if($mapping eq "-");
+  }
+
   push(@$param_types, $type);
   push(@$param_names, $name);
   push(@$param_default_values, $value);
   push(@$param_optional, $is_optional);
+
+  # Map from the c_name to the C++ index (no map if no name given).
+  $$param_mappings{$mapping} = $curr_param if($mapping);
 }
 
 # add_parameter_autoname($, $type, $name)
@@ -341,10 +373,6 @@ sub add_parameter($$$)
   my $param_types = $$self{param_types};
   push(@$param_types, $type);
 
-  # Make sure this parameter is interpreted as not optional.
-  my $param_optional = $$self{param_optional};
-  push(@$param_optional, 0);
-
   return $self;
 }
 
@@ -393,13 +421,13 @@ sub possible_args_list($$)
   my $param_names = $$self{param_names};
   my $param_types = $$self{param_types};
   my $param_optional = $$self{param_optional};
-  
+
   my @result = ();
-  
+
   # Default starting index is 0 (The first call will have an undefined start
   # index).
   my $i = $start_index || 0;
-  
+
   if($i > $#$param_types)
   {
   	# If index is past last arg, return an empty array inserting an empty
@@ -416,10 +444,10 @@ sub possible_args_list($$)
   	push(@result, "") if ($$param_optional[$i]);
   	return @result;
   }
-  
+
   # Get the possible indices for remaining params without this one.
   my @remaining = possible_args_list($self, $i + 1);
-  
+
   # Prepend this param's index to the remaining ones.
   foreach my $possibility (@remaining)
   {
@@ -432,7 +460,7 @@ sub possible_args_list($$)
   	  push(@result, "$i");
   	}
   }
-  
+
   # If this parameter is optional, append the remaining possibilities without
   # this param's type and name.
   if($$param_optional[$i])
@@ -442,7 +470,7 @@ sub possible_args_list($$)
   	  push(@result, $possibility);
     }
   }
-  
+
   return @result;
 }
 
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index 977d95a..0872de1 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -232,7 +232,7 @@ sub output_wrap_default_signal_handler_cc($$$$$$$$$)
   {
     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,
@@ -286,7 +286,6 @@ sub output_wrap_meth($$$$$$$)
 
   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 = "";
@@ -294,13 +293,13 @@ sub output_wrap_meth($$$$$$$)
     {
       $deprecated = "deprecated";
     }
-  
+
     #Declaration:
     if($deprecated ne "")
     {
       $self->append("\n_DEPRECATE_IFDEF_START");
     }
-  
+
     if($arg_list == 0)
     {
       # Doxygen documentation before the method declaration:
@@ -310,37 +309,37 @@ sub output_wrap_meth($$$$$$$)
     {
       $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}) {
@@ -406,7 +405,7 @@ sub output_wrap_ctor($$$$$)
     {
       $self->append("\n\n  /// A $$objCppfunc{name}() convenience overload.\n");
     }
-    
+
     #Ctor Declaration:
     #TODO: Add explicit.
     $self->append("  explicit " . $objCppfunc->get_declaration($arg_list) . "\n");
@@ -418,7 +417,7 @@ sub output_wrap_ctor($$$$$)
       $objCppfunc->args_types_and_names($arg_list),
       get_ctor_properties($objCppfunc, $objCDefsFunc, $line_num, $arg_list)
     );
-  
+
     $self->append($str);
   }
 }
@@ -440,14 +439,14 @@ sub output_wrap_create($$$)
     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)
   }
 }
@@ -775,7 +774,9 @@ sub convert_args_cpp_to_c($$$$$)
   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;
 
@@ -793,6 +794,8 @@ sub convert_args_cpp_to_c($$$$$)
     $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.
+    $$cpp_param_mappings{ $c_param_names[$num_c_args_expected]} =$num_cpp_args - 1;
   }
 
   if ( $num_cpp_args != $num_c_args_expected )
@@ -807,10 +810,9 @@ sub convert_args_cpp_to_c($$$$$)
   }
 
   # Get the desired argument list combination.
-  my $possible_args_list = $$objCppfunc{possible_args_list};
-  my @arg_indices = split(" ", @$possible_args_list[$index]);
+  my $possible_arg_list = $$objCppfunc{possible_args_list}[$index];
 
-  # Loop through the cpp parameters:
+  # Loop through the parameters:
   my $i;
   my $cpp_param_max = $num_cpp_args;
   # if( !($static) ) { $cpp_param_max++; }
@@ -820,38 +822,29 @@ sub convert_args_cpp_to_c($$$$$)
     #index of C parameter:
     my $iCParam = $i;
     if( !($static) ) { $iCParam++; }
-   
-    my $cppParamType = $$cpp_param_types[$i];
+
+    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[$i];
+    my $cppParamName = $$cpp_param_names[$cpp_param_index];
     my $cParamType = $$c_param_types[$iCParam];
-    
-    if(! arg_indices)
+
+    if(!($possible_arg_list =~ /\b$cpp_param_index\b/))
     {
-      # If there are no more arg indices that should be included, pass
+      # 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[$i])
+      if ($$cpp_param_optional[$cpp_param_index])
       {
         push(@result, "0");
         next;
       }
     }
-    elsif($arg_indices[0] > $i)
-    {
-      # If this argument is not in the desired argument list (The argument
-      # indices are stored in ascending order) then pass NULL to C func.
-      push(@result, "0");
-      next;
-    }
-    else
-    {
-      # The current argument index from the desired list is <= the current
-      # index so go to the next index.
-      shift(@arg_indices);
-    }
 
     if ($cppParamType ne $cParamType) #If a type conversion is needed.
     {
@@ -943,14 +936,16 @@ sub convert_args_c_to_cpp($$$)
 # $string get_ctor_properties($objCppfunc, $objCDefsFunc, $wrap_line_number, $index = 0)
 sub get_ctor_properties($$$$$)
 {
- my ($objCppfunc, $objCDefsFunc, $wrap_line_number, $index) = @_;
+  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;
 
@@ -967,53 +962,42 @@ sub get_ctor_properties($$$$$)
 
 
   # Get the desired argument list combination.
-  my $possible_args_list = $$objCppfunc{possible_args_list};
-  my @arg_indices = split(" ", @$possible_args_list[$index]);
+  my $possible_arg_list = $$objCppfunc{possible_args_list}[$index];
 
-  # Loop through the cpp parameters:
- my $i = 0;
+  # Loop through the parameters:
+  my $i = 0;
 
- for ($i = 0; $i < $num_args; $i++)
- {
-   my $cppParamType = $$cpp_param_types[$i];
-   $cppParamType =~ s/ &/&/g; #Remove space between type and &
-   $cppParamType =~ s/ \*/*/g; #Remove space between type and *
+  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 $cppParamName = $$cpp_param_names[$i];
-   my $cParamType = $$c_param_types[$i];
+    my $cppParamType = $$cpp_param_types[$cpp_param_index];
+    $cppParamType =~ s/ &/&/g; #Remove space between type and &
+    $cppParamType =~ s/ \*/*/g; #Remove space between type and *
 
-   # Property name:
-   push(@result, "\"" . $cppParamName . "\"");
+    my $cppParamName = $$cpp_param_names[$cpp_param_index];
+    my $cParamType = $$c_param_types[$i];
 
-  if(! arg_indices)
-  {
-    # If there are no more arg indices that should be included, pass
-    # NULL to the C func unless the param is not optional (applies to a
-    # possibly added GError parameter).
-    if ($$cpp_param_optional[$i])
+    # Property name:
+    push(@result, "\"" . $cppParamName . "\"");
+
+    if(!($possible_arg_list =~ /\b$cpp_param_index\b/))
     {
-      push(@result, "0");
-      next;
+      # 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;
+      }
     }
-  }
-  elsif($arg_indices[0] > $i)
-  {
-    # If this argument is not in the desired argument list (The argument
-    # indices are stored in ascending order) then pass NULL to C func.
-    push(@result, "0");
-    next;
-  }
-  else
-  {
-    # The current argument index from the desired list is <= the current
-    # index so go to the next index.
-    shift(@arg_indices);
-  }
 
    # C property value:
-   if ($cppParamType ne $cParamType) #If a type conversion is needed.
-   {
-     push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
+    if ($cppParamType ne $cParamType) #If a type conversion is needed.
+    {
+      push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
                   $cppParamType,
                   $cParamType,
                   $cppParamName,



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