# $strCommentBlock lookup_documentation($strFunctionName, $deprecation_docs, $newin, $objCppfunc)
# The final objCppfunc parameter is optional. If passed, it is used to
# decide if the final C parameter should be omitted if the C++ method
-# has a slot parameter.
+# has a slot parameter. It is also used for converting C parameter names to
+# C++ parameter names in the documentation, if they differ.
sub lookup_documentation($$$;$)
{
my ($functionName, $deprecation_docs, $newin, $objCppfunc) = @_;
$text .= "\n\@deprecated $deprecation_docs\n";
}
- DocsParser::append_parameter_docs($objFunction, \$text, $objCppfunc);
+ my %param_name_mappings = DocsParser::append_parameter_docs($objFunction, \$text, $objCppfunc);
DocsParser::append_return_docs($objFunction, \$text);
+ # Convert C parameter names to C++ parameter names where they differ.
+ foreach my $key (keys %param_name_mappings)
+ {
+ $text =~ s/\@(param|a) $key\b/\@$1 $param_name_mappings{$key}/g;
+ }
+
# Remove leading and trailing white space.
$text = string_trim($text);
# The final objCppfunc is optional. If passed, it is used to determine
# if the final C parameter should be omitted if the C++ method has a
-# slot parameter.
+# slot parameter. It is also used for converting C parameter names to
+# C++ parameter names in the documentation, if they differ.
sub append_parameter_docs($$;$)
{
my ($obj_function, $text, $objCppfunc) = @_;
- my @param_names = @{$$obj_function{param_names}};
+ my @docs_param_names = @{$$obj_function{param_names}};
my $param_descriptions = \$$obj_function{param_descriptions};
-
- # Strip first parameter if this is a method.
my $defs_method = GtkDefs::lookup_method_dont_mark($$obj_function{name});
- # the second alternative is for use with method-mappings meaning:
- # this function is mapped into this Gtk::class
- shift(@param_names) if(($defs_method && $$defs_method{class} ne "") ||
- ($$obj_function{mapped_class} ne ""));
+ my @c_param_names = $defs_method ? @{$$defs_method{param_names}} : @docs_param_names;
+
+ # The information in
+ # $obj_function comes from the docs.xml file,
+ # $objCppfunc comes from _WRAP_METHOD() or _WRAP_SIGNAL() in the .hg file,
+ # $defs_method comes from the methods.defs file.
+
+ # Ideally @docs_param_names and @c_param_names are identical.
+ # In the real world the parameters in the C documentation are sometimes not
+ # listed in the same order as the arguments in the C function declaration.
+ # We try to handle that case to some extent. If no argument name is misspelt
+ # in either the docs or the C function declaration, it usually succeeds for
+ # methods, but not for signals. For signals there is no C function declaration
+ # to compare with. If the docs of some method or signal get badly distorted
+ # due to imperfections in the C docs, and it's difficult to get the C docs
+ # corrected, correct docs can be added to the docs_override.xml file.
+
+ # Skip first param if this is a signal.
+ if ($$obj_function{name} =~ /\w+::/)
+ {
+ shift(@docs_param_names);
+ shift(@c_param_names);
+ }
+ # Skip first parameter if this is a non-static method.
+ elsif (defined($objCppfunc))
+ {
+ if (!$$objCppfunc{static})
+ {
+ shift(@docs_param_names);
+ shift(@c_param_names);
+ }
+ }
+ # The second alternative is for use with method-mappings meaning:
+ # this function is mapped into this Gtk::class.
+ elsif (($defs_method && $$defs_method{class} ne "") ||
+ $$obj_function{mapped_class} ne "")
+ {
+ shift(@docs_param_names);
+ shift(@c_param_names);
+ }
- # Also skip first param if this is a signal.
- shift(@param_names) if ($$obj_function{name} =~ /\w+::/);
# Skip the last param if there is a slot because it would be a
# gpointer user_data parameter.
- pop(@param_names) if (defined($objCppfunc) && $$objCppfunc{slot_name});
+ if (defined($objCppfunc) && $$objCppfunc{slot_name})
+ {
+ pop(@docs_param_names);
+ pop(@c_param_names);
+ }
- foreach my $param (@param_names)
+ # Skip the last param if it's an error output param.
+ if (scalar @docs_param_names && $docs_param_names[-1] eq "error")
{
- if ($param ne "error" ) #We wrap GErrors as exceptions, so ignore these.
+ pop(@docs_param_names);
+ pop(@c_param_names);
+ }
+
+ my $cpp_param_names;
+ my $param_mappings;
+ my $out_param_index = 1000; # No method has that many arguments, hopefully.
+ if (defined($objCppfunc))
+ {
+ $cpp_param_names = $$objCppfunc{param_names};
+ $param_mappings = $$objCppfunc{param_mappings}; # C name -> C++ index
+ if (exists $$param_mappings{OUT})
{
- my $desc = $$param_descriptions->{$param};
+ $out_param_index = $$param_mappings{OUT};
+ }
+ }
+ my %param_name_mappings; # C name -> C++ name
- # Deal with callback parameters converting the docs to a slot
- # compatible format.
- if ($param eq "callback")
+ for (my $i = 0; $i < @docs_param_names; ++$i)
+ {
+ my $param = $docs_param_names[$i];
+ my $desc = $$param_descriptions->{$param};
+
+ if (defined($objCppfunc))
+ {
+ # If the C++ name is not equal to the C name, mark that the name
+ # shall be changed in the documentation.
+ my $cpp_name = $param;
+ if (exists $$param_mappings{$param})
{
- $param = "slot";
- $$text =~ s/\@a callback/\@a slot/g;
+ # Rename and/or reorder declaration ({c_name} or {.}) in _WRAP_*().
+ $cpp_name = $$cpp_param_names[$$param_mappings{$param}];
}
-
- $param =~ s/([a-zA-Z0-9]*(_[a-zA-Z0-9]+)*)_?/$1/g;
- DocsParser::convert_docs_to_cpp($obj_function, \$desc);
- if(length($desc) > 0)
+ elsif ($c_param_names[$i] eq $param)
+ {
+ # Location in docs coincides with location in C declaration.
+ my $cpp_index = $i;
+ $cpp_index++ if ($i >= $out_param_index);
+ $cpp_name = $$cpp_param_names[$cpp_index];
+ }
+ else
+ {
+ # Search for the param in the C declaration.
+ for (my $j = 0; $j < @c_param_names; ++$j)
+ {
+ if ($c_param_names[$j] eq $param)
+ {
+ my $cpp_index = $j;
+ $cpp_index++ if ($j >= $out_param_index);
+ $cpp_name = $$cpp_param_names[$cpp_index];
+ last;
+ }
+ }
+ }
+ if ($cpp_name ne $param)
{
- $desc .= '.' unless($desc =~ /(?:^|\.)$/);
- $$text .= "\n\@param ${param} \u${desc}";
+ $param_name_mappings{$param} = $cpp_name;
}
}
+ elsif ($param eq "callback")
+ {
+ # Deal with callback parameters converting the docs to a slot
+ # compatible format.
+ $param_name_mappings{$param} = "slot";
+ }
+
+ $param =~ s/([a-zA-Z0-9]*(_[a-zA-Z0-9]+)*)_?/$1/g;
+ DocsParser::convert_docs_to_cpp($obj_function, \$desc);
+ if(length($desc) > 0)
+ {
+ $desc .= '.' unless($desc =~ /(?:^|\.)$/);
+ $$text .= "\n\@param ${param} \u${desc}";
+ }
}
+ return %param_name_mappings;
}