summaryrefslogtreecommitdiff
path: root/tools/pm
diff options
context:
space:
mode:
Diffstat (limited to 'tools/pm')
-rw-r--r--tools/pm/DocsParser.pm257
-rw-r--r--tools/pm/Enum.pm2
-rw-r--r--tools/pm/Output.pm120
-rw-r--r--tools/pm/Property.pm10
-rw-r--r--tools/pm/WrapParser.pm153
5 files changed, 392 insertions, 150 deletions
diff --git a/tools/pm/DocsParser.pm b/tools/pm/DocsParser.pm
index c771fc3c..8dae9c14 100644
--- a/tools/pm/DocsParser.pm
+++ b/tools/pm/DocsParser.pm
@@ -25,7 +25,7 @@ use XML::Parser;
use strict;
use warnings;
-# use Util;
+use Util;
use Function;
use GtkDefs;
use Object;
@@ -112,18 +112,19 @@ sub parse_on_start($$%)
$tag = lc($tag);
- if($tag eq "function" or $tag eq "signal" or $tag eq "enum")
+ if($tag eq "function" or $tag eq "signal" or $tag eq "property" or $tag eq "enum")
{
if(defined $DocsParser::objCurrentFunction)
{
$objParser->xpcroak(
- "\nClose a function, signal or enum tag before you open another one.");
+ "\nClose a function, signal, property or enum tag before you open another one.");
}
my $functionName = $attr{name};
- # Change signal name from Class::a-signal-name to Class::a_signal_name.
- $functionName =~ s/-/_/g if($tag eq "signal");
+ # Change signal name from Class::a-signal-name to Class::a_signal_name
+ # and property name from Class:a-property-name to Class:a_property_name
+ $functionName =~ s/-/_/g if ($tag eq "signal" or $tag eq "property");
#Reuse existing Function, if it exists:
#(For instance, if this is the override parse)
@@ -195,7 +196,7 @@ sub parse_on_end($$)
$tag = lc($tag);
- if($tag eq "function" or $tag eq "signal" or $tag eq "enum")
+ if($tag eq "function" or $tag eq "signal" or $tag eq "property" or $tag eq "enum")
{
# Store the Function structure in the array:
my $functionName = $$DocsParser::objCurrentFunction{name};
@@ -233,14 +234,15 @@ sub parse_on_cdata($$)
}
}
-sub lookup_enum_documentation($$$)
+sub lookup_enum_documentation($$$$)
{
- my ($c_enum_name, $cpp_enum_name, $ref_flags) = @_;
+ my ($c_enum_name, $cpp_enum_name, $indent, $ref_flags) = @_;
my @subst_in = [];
my @subst_out = [];
+ my $newin = "";
- # Get the substitutions.
+ # Get the substitutions, and recognize some flags too.
foreach(@$ref_flags)
{
if(/^\s*s#([^#]+)#([^#]*)#\s*$/)
@@ -248,6 +250,10 @@ sub lookup_enum_documentation($$$)
push(@subst_in, $1);
push(@subst_out, $2);
}
+ elsif(/^\s*newin(.*)/) #If newin is at the start.
+ {
+ $newin = string_unquote(string_trim($1));
+ }
}
my $objFunction = $DocsParser::hasharrayFunctions{$c_enum_name};
@@ -285,19 +291,23 @@ sub lookup_enum_documentation($$$)
$param =~ s/([a-zA-Z0-9]*(_[a-zA-Z0-9]+)*)_?/$1/g;
if(length($desc) > 0)
{
- $desc =~ s/\n/ /g;
- $desc =~ s/ $//;
- $desc =~ s/^\s+//; # Chop off leading whitespace
+ # Chop off leading and trailing whitespace.
+ $desc =~ s/^\s+//;
+ $desc =~ s/\s+$//;
$desc .= '.' unless($desc =~ /(?:^|\.)$/);
- $docs .= "\@var $cpp_enum_name ${param}\n \u${desc}\n\n"; # \u = Convert next char to uppercase
+ $docs .= "\@var $cpp_enum_name ${param}\n\u${desc}\n\n"; # \u = Convert next char to uppercase
}
}
- # Append the enum description docs.
- $docs .= "\@enum $cpp_enum_name\n";
- $docs .= $$objFunction{description};
+ # Replace @newin in the enum description, but don't in the element descriptions.
+ my $description = "\@enum $cpp_enum_name\n";
+ $description .= $$objFunction{description};
+ DocsParser::convert_docs_to_cpp($objFunction, \$description);
+ DocsParser::replace_or_add_newin(\$description, $newin);
+ # Append the enum description docs.
DocsParser::convert_docs_to_cpp($objFunction, \$docs);
+ $docs .= "\n\n$description";
DocsParser::add_m4_quotes(\$docs);
# Escape the space after "i.e." or "e.g." in the brief description.
@@ -305,20 +315,21 @@ sub lookup_enum_documentation($$$)
remove_example_code($c_enum_name, \$docs);
- # Convert to Doxygen-style comment.
- $docs =~ s/\n/\n \* /g;
- $docs = "\/\*\* " . $docs;
+ # Add indentation and an asterisk on all lines except the first.
+ # $docs does not contain leading "/**" and trailing "*/".
+ $docs =~ s/\n/\n${indent}\* /g;
return $docs;
}
-# $strCommentBlock lookup_documentation($strFunctionName, $deprecation_docs, $objCppfunc)
+# $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.
-sub lookup_documentation($$;$)
+# 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, $objCppfunc) = @_;
+ my ($functionName, $deprecation_docs, $newin, $objCppfunc) = @_;
my $objFunction = $DocsParser::hasharrayFunctions{$functionName};
if(!$objFunction)
@@ -335,18 +346,30 @@ sub lookup_documentation($$;$)
}
DocsParser::convert_docs_to_cpp($objFunction, \$text);
+ DocsParser::replace_or_add_newin(\$text, $newin);
# A blank line, marking the end of a paragraph, is needed after @newin.
# Most @newins are at the end of a function description.
$text .= "\n";
- #Add note about deprecation if we have specified that in our _WRAP_METHOD() call:
+ # Add note about deprecation if we have specified that in our _WRAP_METHOD(),
+ # _WRAP_SIGNAL(), _WRAP_PROPERTY() or _WRAP_CHILD_PROPERTY() call:
if($deprecation_docs ne "")
{
$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);
+
DocsParser::add_m4_quotes(\$text);
# Escape the space after "i.e." or "e.g." in the brief description.
@@ -375,7 +398,8 @@ sub remove_example_code($$)
($$text =~ s"<programlisting>.*?</programlisting>"\n[C example ellipted]"sg);
$example_removals += ($$text =~ s"\|\[.*?]\|"\n[C example ellipted]"sg);
- print STDERR "gmmproc: $main::source: $obj_name: Example code discarded.\n"
+ # See "MS Visual Studio" comment in gmmproc.in.
+ print STDERR "gmmproc, $main::source, $obj_name: Example code discarded.\n"
if ($example_removals);
}
@@ -396,51 +420,143 @@ sub add_m4_quotes($)
# 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")
+ {
+ 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))
{
- if ($param ne "error" ) #We wrap GErrors as exceptions, so ignore these.
+ $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;
}
@@ -513,14 +629,20 @@ sub convert_tags_to_doxygen($)
s"<variablelist>\n?(.*?)</variablelist>\n?"&DocsParser::convert_variablelist($1)"esg;
# Use our Doxygen @newin alias.
- # If Since is not followed by a colon, substitute @newin only if it's
- # in a sentence of its own at the end of the string.
- s/\bSince:\s*(\d+)\.(\d+)\.(\d+)\b\.?/\@newin{$1,$2,$3}/g;
- s/\bSince:\s*(\d+)\.(\d+)\b\.?/\@newin{$1,$2}/g;
- s/(\.\s+)Since\s+(\d+)\.(\d+)\.(\d+)\.?$/$1\@newin{$2,$3,$4}/;
- s/(\.\s+)Since\s+(\d+)\.(\d+)\.?$/$1\@newin{$2,$3}/;
-
- s"\b->\b"->"g;
+ # Accept "Since" with or without a following colon.
+ # Require the Since clause to be
+ # - at the end of the string,
+ # - at the end of a line and followed by a blank line, or
+ # - followed by "Deprecated".
+ # If none of these requirements is met, "Since" may be embedded inside
+ # a function description, referring to only a part of the description.
+ # See e.g. g_date_time_format() and gdk_cursor_new_from_pixbuf().
+ # Doxygen assumes that @newin is followed by a paragraph that describes
+ # what is new, but we don't use it that way.
+ my $first_part = '\bSince[:\h]\h*(\d+)\.(\d+)'; # \h == [\t ] (horizontal whitespace)
+ my $last_part = '\.?(\s*$|\h*\n\h*\n|\s+Deprecated)';
+ s/$first_part\.(\d+)$last_part/\@newin{$1,$2,$3}$4/g;
+ s/$first_part$last_part/\@newin{$1,$2}$3/g;
# Doxygen is too dumb to handle &mdash;
s"&mdash;" \@htmlonly&mdash;\@endhtmlonly "g;
@@ -540,6 +662,21 @@ sub convert_tags_to_doxygen($)
}
}
+# void replace_or_add_newin(\$text, $newin)
+# If $newin is not empty, replace the version numbers in an existing @newin
+# Doxygen alias, or add one if there is none.
+sub replace_or_add_newin($$)
+{
+ my ($text, $newin) = @_;
+
+ return if ($newin eq "");
+
+ if (!($$text =~ s/\@newin\{[\d,]+\}/\@newin{$newin}/))
+ {
+ $$text .= "\n\n\@newin{$newin}";
+ }
+}
+
# Convert <simplelist> tags to a list of newline-separated elements.
sub convert_simplelist($)
{
@@ -691,7 +828,7 @@ sub lookup_object_of_method($$)
}
else
{
- print "DocsParser.pm:lookup_object_of_method(): Warning: GtkDefs::lookup_object() failed for object name=" . $object . ", function name=" . $name . "\n";
+ print "DocsParser.pm: lookup_object_of_method(): Warning: GtkDefs::lookup_object() failed for object name=" . $object . ", function name=" . $name . "\n";
print " This may be a missing define-object in a *.defs file.\n"
}
}
diff --git a/tools/pm/Enum.pm b/tools/pm/Enum.pm
index 8d0ce774..61840771 100644
--- a/tools/pm/Enum.pm
+++ b/tools/pm/Enum.pm
@@ -300,7 +300,7 @@ sub build_element_list($$$$)
push(@subst_in, $1);
push(@subst_out, $2);
}
- elsif($_ !~ /^\s*$/)
+ elsif($_ !~ /^\s*(?:newin.*)?$/) # newin or only white space
{
return undef;
}
diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm
index 05e0fa16..587d06ba 100644
--- a/tools/pm/Output.pm
+++ b/tools/pm/Output.pm
@@ -72,15 +72,16 @@ sub output_wrap_failed($$$)
{
my ($self, $cname, $error) = @_;
+ # See "MS Visual Studio" comment in gmmproc.in.
my $str = sprintf("//gtkmmproc error: %s : %s", $cname, $error);
- print STDERR "Output.pm: $main::source: $cname : $error\n";
+ print STDERR "Output.pm, $main::source, $cname : $error\n";
$self->append($str);
}
sub error
{
my $format=shift @_;
- printf STDERR "Output.pm: $main::source: $format",@_;
+ printf STDERR "Output.pm, $main::source: $format",@_;
}
sub ifdef($$)
@@ -204,6 +205,9 @@ sub output_wrap_vfunc_cc($$$$$$$$)
my $refreturn_ctype = "";
$refreturn_ctype = "refreturn_ctype" if($$objCFunc{rettype_needs_ref});
+ my $keep_return = "";
+ $keep_return = "keep_return" if($$objCppfunc{keep_return});
+
# Get the conversions.
my $conversions =
convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num);
@@ -211,7 +215,7 @@ sub output_wrap_vfunc_cc($$$$$$$$)
my $returnValue = $$objCppfunc{return_value};
my $exceptionHandler = $$objCppfunc{exception_handler};
- my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s,%s)dnl\n",
+ my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s,%s,%s)dnl\n",
$$objCppfunc{name},
$cname,
$$objCppfunc{rettype},
@@ -221,6 +225,7 @@ sub output_wrap_vfunc_cc($$$$$$$$)
$conversions,
${$objCFunc->get_param_names()}[0],
$refreturn_ctype,
+ $keep_return,
$ifdef,
$errthrow,
$$objCppfunc{slot_type},
@@ -578,11 +583,14 @@ sub output_wrap_create($$$)
}
}
-# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, $exceptionHandler)
-# custom_signalproxy_name is "" when no type conversion is required - a normal templates SignalProxy will be used instead.
-sub output_wrap_sig_decl($$$$$$$$$$$)
+# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name,
+# $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs,
+# $newin, $exceptionHandler, $detail_name, $bTwoSignalMethods)
+sub output_wrap_sig_decl($$$$$$$$$$$$$$)
{
- my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) = @_;
+ my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name,
+ $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs,
+ $newin, $exceptionHandler, $detail_name, $bTwoSignalMethods) = @_;
# _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>',
@@ -594,8 +602,8 @@ sub output_wrap_sig_decl($$$$$$$$$$$)
$underscored_signal_name =~ s/-/_/g;
# Get the existing signal documentation from the parsed docs.
- my $documentation =
- DocsParser::lookup_documentation("$$objCSignal{class}::$underscored_signal_name", $deprecation_docs);
+ my $documentation = DocsParser::lookup_documentation(
+ "$$objCSignal{class}::$underscored_signal_name", $deprecation_docs, $newin, $objCppfunc);
# Create a merged Doxygen comment block for the signal from the looked up
# docs (the block will also contain a prototype of the slot as an example).
@@ -609,6 +617,9 @@ sub output_wrap_sig_decl($$$$$$$$$$$)
{
# Strip leading whitespace
$doxycomment =~ s/^\s+//;
+ # Add a level of m4 quotes. Necessary if $commentblock contains __FT__ or __BT__.
+ # DocsParser::lookup_documentation() adds it in $documentation.
+ $commentblock = "`" . $commentblock . "'";
# We don't have something to add, so just use $commentblock with
# opening and closing tokens added.
@@ -629,7 +640,7 @@ sub output_wrap_sig_decl($$$$$$$$$$$)
my $conversions =
convert_args_c_to_cpp($objCSignal, $objCppfunc, $line_num);
- my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',%s,\`%s\',%s,%s)dnl\n",
+ my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',%s,\`%s\',%s,%s,%s,%s)dnl\n",
$signal_name,
$$objCSignal{rettype},
$objCSignal->args_types_and_names_without_object(),
@@ -641,7 +652,9 @@ sub output_wrap_sig_decl($$$$$$$$$$$)
$deprecated,
$doxycomment,
$ifdef,
- $exceptionHandler
+ $exceptionHandler,
+ $detail_name, # If a detailed name is supported (signal_name::detail_name)
+ $bTwoSignalMethods # If separate signal_xxx() methods for detailed and general name.
);
$self->append($str);
@@ -675,17 +688,10 @@ sub output_wrap_enum($$$$$$$)
# Get the enum documentation from the parsed docs.
my $enum_docs =
- DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", \@flags);
-
- # Remove initial Doxygen comment block start ('/**') from the enum docs
- # to merge the passed in Doxygen comment block.
- $enum_docs =~ s/\/\*\*\s+//g;
-
- # Make sure indentation of passed in comment is correct.
- $comment =~ s/\n\s*\*/\n */g;
+ DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", " ", \@flags);
# Merge the passed in comment to the existing enum documentation.
- $comment = $comment . "\n * " . $enum_docs;
+ $comment .= "\n * " . $enum_docs if $enum_docs ne "";
my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\')dnl\n",
$cpp_type,
@@ -706,7 +712,7 @@ sub output_wrap_enum_docs_only($$$$$$$)
# Get the existing enum description from the parsed docs.
my $enum_docs =
- DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", \@flags);
+ DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", " ", \@flags);
if($enum_docs eq "")
{
@@ -715,17 +721,10 @@ sub output_wrap_enum_docs_only($$$$$$$)
}
# Include the enum docs in the module's enum docs group.
- $enum_docs .= "\n * \@ingroup ${module_canonical}Enums\n";
+ $enum_docs .= "\n *\n * \@ingroup ${module_canonical}Enums";
- # Remove initial Doxygen comment block start ('/**') from the enum docs
- # to merge the passed in Doxygen comment block.
- $enum_docs =~ s/\/\*\*\s+//g;
-
# Merge the passed in comment to the existing enum documentation.
- $comment = "\/\*\* " . $comment . "\n * " . $enum_docs . "\n */\n";
-
- # Make sure indentation of passed in comment is correct.
- $comment =~ s/\n\s*\*/\n */g;
+ $comment = "/** " . $comment . "\n * " . $enum_docs . "\n */\n";
$self->append($comment);
}
@@ -761,10 +760,7 @@ sub output_wrap_gerror($$$$$$$)
# Get the enum documentation from the parsed docs.
my $enum_docs =
- DocsParser::lookup_enum_documentation("$c_enum", "Code", \@flags);
-
- # Make sure indentation of enum documentation is correct.
- $enum_docs =~ s/\n\s*\*/\n \*/g;
+ DocsParser::lookup_enum_documentation("$c_enum", "Code", " ", \@flags);
# Prevent Doxygen from auto-linking to a class called Error.
$enum_docs =~ s/([^%])(Error code)/$1%$2/g;
@@ -785,7 +781,8 @@ sub output_wrap_gerror($$$$$$$)
# void output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, $proxy_macro)
sub output_wrap_any_property($$$$$$$$$$)
{
- my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, $proxy_macro) = @_;
+ my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated,
+ $deprecation_docs, $newin, $objProperty, $proxy_macro) = @_;
my $objDefsParser = $$self{objDefsParser};
@@ -817,9 +814,44 @@ sub output_wrap_any_property($$$$$$$$$$)
my $name_underscored = $name;
$name_underscored =~ tr/-/_/;
- # Get the property documentation, if any, and add m4 quotes.
- my $documentation = $objProperty->get_docs($deprecation_docs);
- add_m4_quotes(\$documentation) if ($documentation ne "");
+ # Get the existing property documentation, if any, from the parsed docs.
+ my $documentation = DocsParser::lookup_documentation(
+ "$$objProperty{class}:$name_underscored", $deprecation_docs, $newin);
+
+ if ($documentation ne "")
+ {
+ # Remove leading "/**" and trailing "*/". They will be added by the m4 macro.
+ $documentation =~ s/^\s*\/\*\*\s*//;
+ $documentation =~ s/\s*\*\/\s*$//;
+ }
+
+ if ($documentation =~ /^`?[*\s]*
+ (?:
+ \@newin\{[\d,]+\}
+ |[Ss]ince[:\h]+\d+\.\d+
+ |\@deprecated\s
+ |[Dd]eprecated[:\s]
+ )/x)
+ {
+ # The documentation begins with a "@newin", "Since", "@deprecated" or
+ # "Deprecated" line. Get documentation also from the Property object,
+ # but don't add another @newin or @deprecated.
+ my $objdoc = $objProperty->get_docs("", "");
+ if ($objdoc ne "")
+ {
+ add_m4_quotes(\$objdoc);
+ $documentation = "$objdoc\n *\n * $documentation";
+ }
+ }
+ elsif ($documentation eq "")
+ {
+ # Try to get the (usually short) documentation from the Property object.
+ $documentation = $objProperty->get_docs($deprecation_docs, $newin);
+ if ($documentation ne "")
+ {
+ add_m4_quotes(\$documentation);
+ }
+ }
#Declaration:
if($deprecated ne "")
@@ -863,7 +895,8 @@ sub output_wrap_any_property($$$$$$$$$$)
# void output_wrap_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
sub output_wrap_property($$$$$$$$)
{
- my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+ my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated,
+ $deprecation_docs, $newin) = @_;
my $objProperty = GtkDefs::lookup_property($c_class, $name);
if($objProperty eq 0) #If the lookup failed:
@@ -872,7 +905,8 @@ sub output_wrap_property($$$$$$$$)
}
else
{
- $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, "_PROPERTY_PROXY");
+ $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class,
+ $deprecated, $deprecation_docs, $newin, $objProperty, "_PROPERTY_PROXY");
}
}
@@ -880,7 +914,8 @@ sub output_wrap_property($$$$$$$$)
# void output_wrap_child_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs)
sub output_wrap_child_property($$$$$$$$)
{
- my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_;
+ my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated,
+ $deprecation_docs, $newin) = @_;
my $objChildProperty = GtkDefs::lookup_child_property($c_class, $name);
if($objChildProperty eq 0) #If the lookup failed:
@@ -889,7 +924,8 @@ sub output_wrap_child_property($$$$$$$$)
}
else
{
- $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objChildProperty, "_CHILD_PROPERTY_PROXY");
+ $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class,
+ $deprecated, $deprecation_docs, $newin, $objChildProperty, "_CHILD_PROPERTY_PROXY");
}
}
diff --git a/tools/pm/Property.pm b/tools/pm/Property.pm
index f89140ea..8e2a131f 100644
--- a/tools/pm/Property.pm
+++ b/tools/pm/Property.pm
@@ -112,15 +112,21 @@ sub get_writable($)
sub get_docs($$)
{
- my ($self, $deprecation_docs) = @_;
+ my ($self, $deprecation_docs, $newin) = @_;
my $text = $$self{docs};
- #Add note about deprecation if we have specified that in our _WRAP_METHOD() call:
+ #Add note about deprecation if we have specified that in our _WRAP_PROPERTY()
+ #or_WRAP_CHILD_PROPERTY() call:
if($deprecation_docs ne "")
{
$text .= "\n * \@deprecated $deprecation_docs";
}
+ if ($newin ne "")
+ {
+ $text .= "\n *\n * \@newin{$newin}";
+ }
+
return $text;
}
diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm
index dc12eb47..b33ecb13 100644
--- a/tools/pm/WrapParser.pm
+++ b/tools/pm/WrapParser.pm
@@ -111,6 +111,8 @@ sub parse_and_build_output($)
if ($token eq "_DEFS") { $self->on_defs(); next;} #Read the defs file.
if ($token eq "_IGNORE") { $self->on_ignore(); next;} #Ignore a function.
if ($token eq "_IGNORE_SIGNAL") { $self->on_ignore_signal(); next;} #Ignore a signal.
+ if ($token eq "_IGNORE_PROPERTY") { $self->on_ignore_property(); next;} #Ignore a property.
+ if ($token eq "_IGNORE_CHILD_PROPERTY") { $self->on_ignore_child_property(); next;} #Ignore a child property.
if ($token eq "_WRAP_METHOD") { $self->on_wrap_method(); next;}
if ($token eq "_WRAP_METHOD_DOCS_ONLY") { $self->on_wrap_method_docs_only(); next;}
if ($token eq "_WRAP_CORBA_METHOD") { $self->on_wrap_corba_method(); next;} #Used in libbonobo*mm.
@@ -471,25 +473,42 @@ sub on_ignore($)
}
}
-sub on_ignore_signal($)
+# void on_ignore_signal_or_property(\&lookup_function, $type)
+sub on_ignore_signal_or_property($$$)
{
- my ($self) = @_;
- my $objOutputter = $$self{objOutputter};
+ my ($self, $lookup_function, $type) = @_;
my $str = $self->extract_bracketed_text();
- $str = string_trim($str);
- $str = string_unquote($str);
my @args = split(/\s+|,/,$str);
foreach (@args)
{
- next if ($_ eq "");
- my $objCsignal = GtkDefs::lookup_signal($$self{c_class}, $_); #Pretend that we've used it.
- if(!$objCsignal)
+ my $name = string_unquote($_);
+ next if ($name eq "");
+ my $objCentity = $lookup_function->($$self{c_class}, $name); #Pretend that we've used it.
+ if (!$objCentity)
{
- $objOutputter->output_wrap_failed($_, "ignored signal defs lookup failed");
+ $$self{objOutputter}->output_wrap_failed($name, "ignored $type defs lookup failed");
}
}
}
+sub on_ignore_signal($)
+{
+ my ($self) = @_;
+ $self->on_ignore_signal_or_property(\&GtkDefs::lookup_signal, "signal");
+}
+
+sub on_ignore_property($)
+{
+ my ($self) = @_;
+ $self->on_ignore_signal_or_property(\&GtkDefs::lookup_property, "property");
+}
+
+sub on_ignore_child_property($)
+{
+ my ($self) = @_;
+ $self->on_ignore_signal_or_property(\&GtkDefs::lookup_child_property, "child property");
+}
+
########################################
### we have certain macros we need to insert at end of statements
# void on_class($, $strClassCommand)
@@ -683,11 +702,12 @@ sub extract_bracketed_text($)
########################################
### breaks up a string by commas (smart)
-# @strings string_split_commas($string)
-sub string_split_commas($)
+# @strings string_split_commas($string [, $ignore_quotes])
+sub string_split_commas($;$)
{
- my ($in) = @_;
+ my ($in, $ignore_quotes) = @_;
+ $ignore_quotes = 2 unless defined $ignore_quotes;
my @out;
my $level = 0;
my $in_braces = 0;
@@ -701,10 +721,10 @@ sub string_split_commas($)
next if ($t eq "");
- # TODO: Delete the test for scalar(@out) >= 2 when we can stop accepting
+ # TODO: Delete the test for scalar(@out) >= $ignore_quotes when we can stop accepting
# .hg files with unpaired quotes, such as _WRAP_PROPERTY("text_column, int).
# See also TODO in extract_bracketed_text().
- $in_quotes = !$in_quotes if ($t eq '"' and scalar(@out) >= 2);
+ $in_quotes = !$in_quotes if ($t eq '"' and scalar(@out) >= $ignore_quotes);
if (!$in_quotes)
{
$in_braces++ if ($t eq "{");
@@ -931,6 +951,7 @@ sub on_wrap_method($)
$$objCfunc{constversion} = 0;
$$objCfunc{deprecated} = "";
my $deprecation_docs = "";
+ my $newin = "";
my $ifdef;
while($#args >= 2) # If the optional ref/err/deprecated arguments are there.
{
@@ -957,6 +978,10 @@ sub on_wrap_method($)
$deprecation_docs = string_unquote(string_trim($1));
}
}
+ elsif($argRef =~ /^newin(.*)/) #If newin is at the start.
+ {
+ $newin = string_unquote(string_trim($1));
+ }
elsif($argRef =~ /^ifdef(.*)/) #If ifdef is at the start.
{
$ifdef = $1;
@@ -989,7 +1014,7 @@ sub on_wrap_method($)
else
{
$commentblock = DocsParser::lookup_documentation($argCFunctionName,
- $deprecation_docs, $objCppfunc);
+ $deprecation_docs, $newin, $objCppfunc);
}
$objOutputter->output_wrap_meth($filename, $line_num, $objCppfunc, $objCfunc, $argCppMethodDecl, $commentblock, $ifdef);
@@ -1007,7 +1032,7 @@ sub on_wrap_method_docs_only($)
my $line_num = $$self{line_num};
my $str = $self->extract_bracketed_text();
- my @args = string_split_commas($str);
+ my @args = string_split_commas($str, 1);
my $entity_type = "method";
@@ -1038,8 +1063,8 @@ sub on_wrap_method_docs_only($)
}
}
- # Extra ref needed?
$$objCfunc{throw_any_errors} = 0;
+ my $newin = "";
while($#args >= 1) # If the optional ref/err arguments are there.
{
my $argRef = string_trim(pop @args);
@@ -1047,11 +1072,14 @@ sub on_wrap_method_docs_only($)
{
$$objCfunc{throw_any_errors} = 1;
}
+ elsif($argRef =~ /^newin(.*)/) #If newin is at the start.
+ {
+ $newin = string_unquote(string_trim($1));
+ }
}
my $commentblock = "";
- $commentblock = DocsParser::lookup_documentation($argCFunctionName, "");
-
+ $commentblock = DocsParser::lookup_documentation($argCFunctionName, "", $newin);
$objOutputter->output_wrap_meth_docs_only($filename, $line_num, $commentblock);
}
@@ -1205,10 +1233,13 @@ sub on_wrap_signal($$)
my $bNoDefaultHandler = 0;
my $bCustomCCallback = 0;
my $bRefreturn = 0;
- my $ifdef;
+ my $ifdef = "";
my $argDeprecated = "";
my $deprecation_docs = "";
+ my $newin = "";
my $exceptionHandler = "";
+ my $detail_name = "";
+ my $bTwoSignalMethods = 0;
while($#args >= 2) # If optional arguments are there.
{
@@ -1217,23 +1248,19 @@ sub on_wrap_signal($$)
{
$bCustomDefaultHandler = 1;
}
-
- if($argRef eq "no_default_handler")
+ elsif($argRef eq "no_default_handler")
{
$bNoDefaultHandler = 1;
}
-
- if($argRef eq "custom_c_callback")
+ elsif($argRef eq "custom_c_callback")
{
$bCustomCCallback = 1;
}
-
- if($argRef eq "refreturn")
+ elsif($argRef eq "refreturn")
{
$bRefreturn = 1;
}
-
- if($argRef =~ /^deprecated(.*)/) #If deprecated is at the start.
+ elsif($argRef =~ /^deprecated(.*)/) #If deprecated is at the start.
{
$argDeprecated = "deprecated";
@@ -1242,21 +1269,36 @@ sub on_wrap_signal($$)
$deprecation_docs = string_unquote(string_trim($1));
}
}
-
+ elsif($argRef =~ /^newin(.*)/) #If newin is at the start.
+ {
+ $newin = string_unquote(string_trim($1));
+ }
elsif($argRef =~ /^ifdef(.*)/) #If ifdef is at the start.
{
$ifdef = $1;
}
-
elsif($argRef =~ /^exception_handler\s+(.*)/) #If exception_handler at the start.
{
- $exceptionHandler = $1;
+ $exceptionHandler = $1;
+ }
+ elsif($argRef =~ /^detail_name\s+(.+)/) #If detail_name at the start.
+ {
+ $detail_name = $1;
+ }
+ elsif($argRef eq "two_signal_methods")
+ {
+ $bTwoSignalMethods = 1;
+ }
+ else
+ {
+ $self->error("_WRAP_SIGNAL: Invalid option '$argRef'.\n");
}
}
$self->output_wrap_signal($argCppDecl, $argCName, $$self{filename}, $$self{line_num},
$bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback,
- $bRefreturn, $ifdef, $commentblock, $argDeprecated, $deprecation_docs, $exceptionHandler);
+ $bRefreturn, $ifdef, $commentblock, $argDeprecated, $deprecation_docs,
+ $newin, $exceptionHandler, $detail_name, $bTwoSignalMethods);
}
# void on_wrap_vfunc()
@@ -1279,6 +1321,7 @@ sub on_wrap_vfunc($)
$argCName = string_unquote($argCName);
my $refreturn = 0;
+ my $keep_return = 0;
my $refreturn_ctype = 0;
my $returnValue = "";
my $exceptionHandler = "";
@@ -1299,6 +1342,12 @@ sub on_wrap_vfunc($)
{
$refreturn = 1;
}
+ # Must a copy of the return value be kept, because the caller does not
+ # get its own copy?
+ elsif($argRef eq "keep_return")
+ {
+ $keep_return = 1;
+ }
elsif($argRef eq "refreturn_ctype")
{
$refreturn_ctype = 1;
@@ -1354,7 +1403,7 @@ sub on_wrap_vfunc($)
}
$self->output_wrap_vfunc($argCppDecl, $argCName, $$self{filename}, $$self{line_num},
- $refreturn, $refreturn_ctype, $custom_vfunc,
+ $refreturn, $keep_return, $refreturn_ctype, $custom_vfunc,
$custom_vfunc_callback, $ifdef, $errthrow,
$slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler);
}
@@ -1452,6 +1501,7 @@ sub on_wrap_any_property($)
#TODO: Reduce duplication with on_wrap_method():
my $argDeprecated = "";
my $deprecation_docs = "";
+ my $newin = "";
while($#args >= 2) # If the optional arguments are there.
{
my $argRef = string_trim(pop @args);
@@ -1465,9 +1515,14 @@ sub on_wrap_any_property($)
$deprecation_docs = string_unquote(string_trim($1));
}
}
+ elsif($argRef =~ /^newin(.*)/) #If newin is at the start.
+ {
+ $newin = string_unquote(string_trim($1));
+ }
}
- return ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs);
+ return ($filename, $line_num, $argPropertyName, $argCppType,
+ $argDeprecated, $deprecation_docs, $newin);
}
sub on_wrap_property($)
@@ -1477,9 +1532,11 @@ sub on_wrap_property($)
return unless ($self->check_for_eof());
- my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = $self->on_wrap_any_property();
+ my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated,
+ $deprecation_docs, $newin) = $self->on_wrap_any_property();
- $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs);
+ $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName,
+ $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs, $newin);
}
sub on_wrap_child_property($)
@@ -1489,9 +1546,11 @@ sub on_wrap_child_property($)
return unless ($self->check_for_eof());
- my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = $self->on_wrap_any_property();
+ my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated,
+ $deprecation_docs, $newin) = $self->on_wrap_any_property();
- $objOutputter->output_wrap_child_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs);
+ $objOutputter->output_wrap_child_property($filename, $line_num, $argPropertyName,
+ $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs, $newin);
}
sub output_wrap_check($$$$$$)
@@ -1515,12 +1574,14 @@ sub output_wrap_check($$$$$$)
# void output_wrap($CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler,
# $bNoDefaultHandler, $bCustomCCallback, $bRefreturn, $ifdef,
-# $commentblock, $deprecated, $deprecation_docs, $exceptionHandler)
-sub output_wrap_signal($$$$$$$$$$$$)
+# $commentblock, $deprecated, $deprecation_docs, $newin, $exceptionHandler,
+# $detail_name, $bTwoSignalMethods)
+sub output_wrap_signal($$$$$$$$$$$$$$$$$)
{
my ($self, $CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler,
$bNoDefaultHandler, $bCustomCCallback, $bRefreturn, $ifdef,
- $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) = @_;
+ $commentblock, $deprecated, $deprecation_docs, $newin, $exceptionHandler,
+ $detail_name, $bTwoSignalMethods) = @_;
#Some checks:
return if ($self->output_wrap_check($CppDecl, $signal_name,
@@ -1554,7 +1615,8 @@ sub output_wrap_signal($$$$$$$$$$$$)
$objOutputter->output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppSignal,
$signal_name, $bCustomCCallback, $ifdef, $commentblock,
- $deprecated, $deprecation_docs, $exceptionHandler);
+ $deprecated, $deprecation_docs, $newin, $exceptionHandler,
+ $detail_name, $bTwoSignalMethods);
if($bNoDefaultHandler eq 0)
{
@@ -1570,12 +1632,12 @@ sub output_wrap_signal($$$$$$$$$$$$)
}
# void output_wrap_vfunc($CppDecl, $vfunc_name, $filename, $line_num,
-# $refreturn, $refreturn_ctype,
+# $refreturn, $keep_return, $refreturn_ctype,
# $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow,
# $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler)
-sub output_wrap_vfunc($$$$$$$$$$$$$$)
+sub output_wrap_vfunc($$$$$$$$$$$$$$$$$)
{
- my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype,
+ my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $keep_return, $refreturn_ctype,
$custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow,
$slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler) = @_;
@@ -1608,6 +1670,7 @@ sub output_wrap_vfunc($$$$$$$$$$$$$$)
# These macros are defined in vfunc.m4:
$$objCppVfunc{rettype_needs_ref} = $refreturn;
+ $$objCppVfunc{keep_return} = $keep_return;
$$objCppVfunc{return_value} = $returnValue;
$$objCppVfunc{exception_handler} = $exceptionHandler;
$$objCppVfunc{name} .= "_vfunc"; #All vfuncs should have the "_vfunc" suffix, and a separate easily-named invoker method.