[glibmm] gmmproc: _WRAP_METHOD: Add optional parameter functionality.
- From: José Alburquerque <jaalburqu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glibmm] gmmproc: _WRAP_METHOD: Add optional parameter functionality.
- Date: Tue, 31 May 2011 16:58:19 +0000 (UTC)
commit 1802c2814461aed5878005ce99640340f1d9d69d
Author: José Alburquerque <jaalburqu svn gnome org>
Date: Tue May 31 12:05:17 2011 -0400
gmmproc: _WRAP_METHOD: Add optional parameter functionality.
* tools/pm/Function.pm (param_optional): Add new member bool array to
represent which parameters are optional.
(possible_args_list): Add new member string array containing a list of
the possible argument combination based on existing optional
parameters.
(possible_args_list): Added recursive function to generate the list of
possible parameter combinations. The first in the list (the zeroth
element) always includes all the paramters.
(new): Modified to initialize the new members above.
(parse_param): Modified to see if parameters are optional by checking
if the name ends with '{?}'.
* tools/pm/FunctionBase.pm (args_names_only):
(args_types_and_names):
(args_types_and_names_with_default_values): Modified to accept an
optional index representing the desired argument list to use out of
the possible combinations.
(get_declaration): New subroutine returning any of the possible
declarations based on optional arguments.
(get_num_possible_args_list): New subroutine returning the number of
possible combination of arguments.
* tools/pm/Output.pm (output_wrap_meth): Modified to loop through the
possible arguments list and generate a _METHOD or _STATIC_METHOD for
all the possible combination of arguments.
(convert_args_cpp_to_c): Modified as above to accept an optional index
parameter representing the argument list for which to generate
_CONVERT macros. For optional arguments a NULL is placed in the C
function call.
ChangeLog | 32 ++++++
tools/pm/Function.pm | 96 ++++++++++++++++++-
tools/pm/FunctionBase.pm | 128 ++++++++++++++++++++++---
tools/pm/Output.pm | 239 ++++++++++++++++++++++++++++------------------
4 files changed, 386 insertions(+), 109 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 04345a1..c3b50d7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2011-05-31 José Alburquerque <jaalburqu svn gnome org>
+
+ gmmproc: _WRAP_METHOD: Add optional parameter functionality.
+
+ * tools/pm/Function.pm (param_optional): Add new member bool array to
+ represent which parameters are optional.
+ (possible_args_list): Add new member string array containing a list of
+ the possible argument combination based on existing optional
+ parameters.
+ (possible_args_list): Added recursive function to generate the list of
+ possible parameter combinations. The first in the list (the zeroth
+ element) always includes all the paramters.
+ (new): Modified to initialize the new members above.
+ (parse_param): Modified to see if parameters are optional by checking
+ if the name ends with '{?}'.
+ * tools/pm/FunctionBase.pm (args_names_only):
+ (args_types_and_names):
+ (args_types_and_names_with_default_values): Modified to accept an
+ optional index representing the desired argument list to use out of
+ the possible combinations.
+ (get_declaration): New subroutine returning any of the possible
+ declarations based on optional arguments.
+ (get_num_possible_args_list): New subroutine returning the number of
+ possible combination of arguments.
+ * tools/pm/Output.pm (output_wrap_meth): Modified to loop through the
+ possible arguments list and generate a _METHOD or _STATIC_METHOD for
+ all the possible combination of arguments.
+ (convert_args_cpp_to_c): Modified as above to accept an optional index
+ parameter representing the argument list for which to generate
+ _CONVERT macros. For optional arguments a NULL is placed in the C
+ function call.
+
2011-05-27 Kjell Ahlstedt <kjellahl src gnome org>
gmmproc: Protect documentation with m4 quotes.
diff --git a/tools/pm/Function.pm b/tools/pm/Function.pm
index d0537bb..0434852 100644
--- a/tools/pm/Function.pm
+++ b/tools/pm/Function.pm
@@ -35,12 +35,18 @@ our @EXPORT_OK;
# string array param_type;
# string array param_name;
# string array param_default_value;
+# bool array param_optional;
+# 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.
# string class e.g. GtkButton ( == of-object. Useful for signal because their names are not unique.
# string entity_type. e.g. method or signal
# }
+# Subroutine to get an array of string of indices representing the possible
+# combination of arguments based on whether some parameters are optional.
+sub possible_args_list($$);
+
sub new_empty()
{
my $self = {};
@@ -68,6 +74,8 @@ sub new($$)
$$self{param_types} = [];
$$self{param_names} = [];
$$self{param_default_values} = [];
+ $$self{param_optional} = [];
+ $$self{possible_args_list} = [];
$$self{in_module} = "";
$$self{class} = "";
$$self{entity_type} = "method";
@@ -96,6 +104,11 @@ 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};
+ push(@$possible_args_list, $self->possible_args_list());
return $self;
}
@@ -163,10 +176,12 @@ sub parse_param($$)
my $value = "";
my $id = 0;
my $has_value = 0;
+ my $is_optional = 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};
# clean up space and handle empty case
$line = string_trim($line);
@@ -221,10 +236,15 @@ sub parse_param($$)
}
$type = string_trim($type);
-
+
+ # Determine if the param is optional (if name ends with {?}).
+ $is_optional = 1 if ($name =~ /\{\?\}$/);
+ $name =~ s/\{\?\}$//;
+
push(@$param_types, $type);
push(@$param_names, $name);
push(@$param_default_values, $value);
+ push(@$param_optional, $is_optional);
#Clear variables, ready for the next parameter.
@str = ();
@@ -232,6 +252,7 @@ sub parse_param($$)
$value = "";
$has_value = 0;
$name = "";
+ $is_optional = 0;
$id = 0;
@@ -274,9 +295,14 @@ sub parse_param($$)
$type = string_trim($type);
+ # Determine if the param is optional (if name ends with {?}).
+ $is_optional = 1 if ($name =~ /\{\?\}$/);
+ $name =~ s/\{\?\}$//;
+
push(@$param_types, $type);
push(@$param_names, $name);
push(@$param_default_values, $value);
+ push(@$param_optional, $is_optional);
}
# add_parameter_autoname($, $type, $name)
@@ -306,9 +332,12 @@ sub add_parameter($$$)
push(@$param_names, $name);
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;
}
@@ -347,5 +376,68 @@ sub get_is_const($)
return $$self{const};
}
+# string array possible_args_list()
+# Returns an array of string of space separated indexes representing the
+# possible argument combinations based on whether parameters are optional.
+sub possible_args_list($$)
+{
+ my ($self, $start_index) = @_;
+
+ 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
+ # string if this function has no parameters.
+ push(@result, "") if ($i == 0);
+ return @result;
+ }
+ elsif($i == $#$param_types)
+ {
+ # If it's the last arg just add its index:
+ push(@result, "$i");
+ # And if it's optional also add an empty string to represent that it is
+ # not added.
+ 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)
+ {
+ if($possibility)
+ {
+ push(@result, "$i " . $possibility);
+ }
+ else
+ {
+ push(@result, "$i");
+ }
+ }
+
+ # If this parameter is optional, append the remaining possibilities without
+ # this param's type and name.
+ if($$param_optional[$i])
+ {
+ foreach my $possibility (@remaining)
+ {
+ push(@result, $possibility);
+ }
+ }
+
+ return @result;
+}
+
1; # indicate proper module load.
diff --git a/tools/pm/FunctionBase.pm b/tools/pm/FunctionBase.pm
index 00c1c05..83fc58f 100644
--- a/tools/pm/FunctionBase.pm
+++ b/tools/pm/FunctionBase.pm
@@ -43,24 +43,53 @@ sub args_types_only($)
return join(", ", @$param_types);
}
-# $string args_names_only($)
+# $string args_names_only(int index = 0)
+# Gets the args names. The optional index specifies which argument
+# list should be used out of the possible combination of arguments based on
+# whether any arguments are optional. index = 0 ==> all the names.
sub args_names_only($)
{
- my ($self) = @_;
+ my ($self, $index) = @_;
+
+ $index = 0 unless defined($index);
my $param_names = $$self{param_names};
+ my $possible_args_list = $$self{possible_args_list};
+ my @out;
+
+ my @arg_indices;
+
+ if(defined($possible_args_list))
+ {
+ @arg_indices = split(" ", @$possible_args_list[$index]);
+ }
+ else
+ {
+ @arg_indices = (0 $param_names - 1);
+ }
+
+ for (my $i = 0; $i < @arg_indices; $i++)
+ {
+ push(@out, $$param_names[$arg_indices[$i]]);
+ }
return join(", ", @$param_names);
}
-# $string args_types_and_names($)
+# $string args_types_and_names(int index = 0)
+# Gets the args types and names. The optional index specifies which argument
+# list should be used out of the possible combination of arguments based on
+# whether any arguments are optional. index = 0 ==> all the types and names.
sub args_types_and_names($)
{
- my ($self) = @_;
+ my ($self, $index) = @_;
+
+ $index = 0 unless defined($index);
my $i;
my $param_names = $$self{param_names};
my $param_types = $$self{param_types};
+ my $possible_args_list = $$self{possible_args_list};
my @out;
#debugging:
@@ -69,9 +98,21 @@ sub args_types_and_names($)
# return "NOARGS";
#}
- for ($i = 0; $i < $#$param_types + 1; $i++)
+ my @arg_indices;
+
+ if(defined($possible_args_list))
{
- my $str = sprintf("%s %s", $$param_types[$i], $$param_names[$i]);
+ @arg_indices = split(" ", @$possible_args_list[$index]);
+ }
+ else
+ {
+ @arg_indices = (0 $param_names - 1);
+ }
+
+ for ($i = 0; $i < @arg_indices; $i++)
+ {
+ my $str = sprintf("%s %s", $$param_types[$arg_indices[$i]],
+ $$param_names[$arg_indices[$i]]);
push(@out, $str);
}
@@ -184,26 +225,49 @@ sub dump($)
print "</function>\n\n";
}
+# $string args_types_and_names_with_default_values(int index = 0)
+# Gets the args types and names with default values. The optional index
+# specifies which argument list should be used out of the possible
+# combination of arguments based on whether any arguments are optional.
+# index = 0 ==> all the types and names.
sub args_types_and_names_with_default_values($)
{
- my ($self) = @_;
+ my ($self, $index) = @_;
+
+ $index = 0 unless defined $index;
my $i;
my $param_names = $$self{param_names};
my $param_types = $$self{param_types};
my $param_default_values = $$self{param_default_values};
+ my $possible_args_list = $$self{possible_args_list};
my @out;
- for ($i = 0; $i < $#$param_types + 1; $i++)
+ my @arg_indices;
+
+ if(defined($possible_args_list))
{
- my $str = sprintf("%s %s", $$param_types[$i], $$param_names[$i]);
+ @arg_indices = split(" ", @$possible_args_list[$index]);
+ }
+ else
+ {
+ @arg_indices = (0 $param_names - 1);
+ }
+
+ for ($i = 0; $i < @arg_indices; $i++)
+ {
+ my $str = sprintf("%s %s", $$param_types[$arg_indices[$i]],
+ $$param_names[$arg_indices[$i]]);
+
- if(defined($$param_default_values[$i]))
+ if(defined($$param_default_values[$arg_indices[$i]]))
{
- if($$param_default_values[$i] ne "")
+ my $default_value = $$param_default_values[$arg_indices[$i]];
+
+ if($default_value ne "")
{
- $str .= " = " . $$param_default_values[$i];
+ $str .= " = " . $default_value;
}
}
@@ -213,5 +277,45 @@ sub args_types_and_names_with_default_values($)
return join(", ", @out);
}
+# $string get_declaration(int index = 0)
+# Gets the function declaration (this includes the default values of the
+# args). The optional index specifies which argument list should be used out
+# of the possible combination of arguments based on whether any arguments are
+# optional. index = 0 ==> all the types and names.
+sub get_declaration($)
+{
+ my ($self, $index) = @_;
+
+ $index = 0 unless defined $index;
+ my $out = "";
+
+ $out = "static " if($$self{static});
+ $out = $out . $$self{rettype} . " " . $$self{name} . "(" .
+ $self->args_types_and_names_with_default_values($index) . ")";
+ $out = $out . " const" if $$self{const};
+ $out = $out . ";";
+
+ return $out;
+}
+
+# int get_num_possible_args_list();
+# Returns the number of possible argument list based on whether some args are
+# optional.
+sub get_num_possible_args_list()
+{
+ my ($self) = @_;
+
+ my $possible_args_list = $$self{possible_args_list};
+
+ if(defined($possible_args_list))
+ {
+ return @$possible_args_list;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
1; # indicate proper module load.
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index 1cbd896..9d17ac4 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -282,84 +282,99 @@ sub output_wrap_meth($$$$$$$)
my ($self, $filename, $line_num, $objCppfunc, $objCDefsFunc, $cppMethodDecl, $documentation, $ifdef) = @_;
my $objDefsParser = $$self{objDefsParser};
- # 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})
+ for(my $arg_list = 0; $arg_list < $objCppfunc->get_num_possible_args_list();
+ $arg_list++)
{
- $deprecated = "deprecated";
- }
-
- #Declaration:
- if($deprecated ne "")
- {
- $self->append("\n_DEPRECATE_IFDEF_START");
- }
-
- # Doxygen documentation before the method declaration:
- $self->output_wrap_meth_docs_only($filename, $line_num, $documentation);
-
- $self->ifdef($ifdef);
-
- $self->append(" ${cppMethodDecl};");
- $self->endif($ifdef);
-
+ # 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";
+ }
- 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)dnl\n",
- $$objCppfunc{name},
- $$objCDefsFunc{c_name},
- $$objCppfunc{rettype},
- $objCDefsFunc->get_return_type_for_methods(),
- $objCppfunc->args_types_and_names(),
- convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 1, $line_num, $errthrow), #1 means it's static, so it has 'object'.
- $refneeded,
- $errthrow,
- $deprecated,
- $ifdef);
- } else {
- $str = sprintf("_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(),
- convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, 0, $line_num, $errthrow),
- $$objCppfunc{const},
- $refneeded,
- $errthrow,
- $deprecated,
- $constversion,
- $objCppfunc->args_names_only(),
- $ifdef
- );
+ #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}() convinience 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)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);
+ } else {
+ $str = sprintf("_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, 0, $line_num,
+ $errthrow, $arg_list),
+ $$objCppfunc{const},
+ $refneeded,
+ $errthrow,
+ $deprecated,
+ $constversion,
+ $objCppfunc->args_names_only($arg_list),
+ $ifdef
+ );
+ }
+ $self->append($str);
}
- $self->append($str);
}
### Convert _WRAP to a method
@@ -724,15 +739,20 @@ sub remove_temp_files($)
# procedure for generating CONVERT macros
-# $string convert_args_cpp_to_c($objCppfunc, $objCDefsFunc, $static, $wrap_line_number,$automatic_error)
-sub convert_args_cpp_to_c($$$$;$)
+# $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) = @_;
+ 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 $c_param_types = $$objCDefsFunc{param_types};
my @result;
@@ -750,6 +770,7 @@ sub convert_args_cpp_to_c($$$$;$)
$num_cpp_args++;
$cpp_param_names = [ {$cpp_param_names},"gerror"];
$cpp_param_types = [ {$cpp_param_types},"GError*&"];
+ $cpp_param_optional = [ {$cpp_param_optional}, 0];
}
if ( $num_cpp_args != $num_c_args_expected )
@@ -763,30 +784,58 @@ sub convert_args_cpp_to_c($$$$;$)
return "";
}
+ # Get the desired argument list combination.
+ my $possible_args_list = $$objCppfunc{possible_args_list};
+ my @arg_indices = split(" ", @$possible_args_list[$index]);
# Loop through the cpp parameters:
- my $i;
- my $cpp_param_max = $num_cpp_args;
- # if( !($static) ) { $cpp_param_max++; }
-
- for ($i = 0; $i < $cpp_param_max; $i++)
- {
- #index of C parameter:
- my $iCParam = $i;
- if( !($static) ) { $iCParam++; }
-
- my $cppParamType = $$cpp_param_types[$i];
- $cppParamType =~ s/ &/&/g; #Remove space between type and &
- $cppParamType =~ s/ \*/*/g; #Remove space between type and *
+ my $i;
+ my $cpp_param_max = $num_cpp_args;
+ # if( !($static) ) { $cpp_param_max++; }
- my $cppParamName = $$cpp_param_names[$i];
- my $cParamType = $$c_param_types[$iCParam];
+ for ($i = 0; $i < $cpp_param_max; $i++)
+ {
+ #index of C parameter:
+ my $iCParam = $i;
+ if( !($static) ) { $iCParam++; }
+
+ my $cppParamType = $$cpp_param_types[$i];
+ $cppParamType =~ s/ &/&/g; #Remove space between type and &
+ $cppParamType =~ s/ \*/*/g; #Remove space between type and *
+
+ my $cppParamName = $$cpp_param_names[$i];
+ my $cParamType = $$c_param_types[$iCParam];
+
+ 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])
+ {
+ push(@result, "NULL");
+ 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, "NULL");
+ 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.
- {
+ if ($cppParamType ne $cParamType) #If a type conversion is needed.
+ {
- push(@result, sprintf("_CONVERT(%s,%s,%s,%s)",
+ 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]