summaryrefslogtreecommitdiff
path: root/autodoc.pl
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2020-09-02 10:55:02 -0600
committerKarl Williamson <khw@cpan.org>2020-09-04 16:13:24 -0600
commit3cfa66c412a3c052d32b67831b0bd368ac7c3140 (patch)
tree854f3440fe92c84d6331282b6b1beb4613671f92 /autodoc.pl
parent8740992ec43ef20892cc616fe0a4de16a599085e (diff)
downloadperl-3cfa66c412a3c052d32b67831b0bd368ac7c3140.tar.gz
autodoc.pl: Add ability to link to other pods
This enhances perlapi and perlintern so that an API element that is documented in some other pod can automatically have a link to that pod generated and placed into perlapi/perlintern. This allows one stop browsing through the API, as the hither-to-unlisted elements now are listed there, with a link.
Diffstat (limited to 'autodoc.pl')
-rw-r--r--autodoc.pl99
1 files changed, 66 insertions, 33 deletions
diff --git a/autodoc.pl b/autodoc.pl
index 02e98176d2..1816297afc 100644
--- a/autodoc.pl
+++ b/autodoc.pl
@@ -77,12 +77,21 @@ sub autodoc ($$) { # parse a file and extract documentation info
my($fh,$file) = @_;
my($in, $doc, $line, $header_doc);
+ my $file_is_C = $file =~ / \. [ch] $ /x;
+
# Count lines easier
my $get_next_line = sub { $line++; return <$fh> };
FUNC:
while (defined($in = $get_next_line->())) {
- if ($in=~ /^=head1 (.*)/) {
+
+ if ($in=~ /^=for apidoc_section\s*(.*)/) {
+ $curheader = $1;
+ next FUNC;
+ }
+ elsif ($file_is_C && $in=~ /^=head1 (.*)/) {
+ # =head1 lines only have effect in C files
+
$curheader = $1;
# If the next non-space line begins with a word char, then it is
@@ -111,7 +120,7 @@ HDR_DOC:
redo FUNC;
}
- if ($doc =~ m:^\s*\*/$:) {
+ if ($file_is_C && $doc =~ m:^\s*\*/$:) {
warn "=cut missing? $file:$line:$doc";;
last HDR_DOC;
}
@@ -154,15 +163,32 @@ Expected:
=for apidoc flags|returntype|name
=for apidoc name
EOS
+
+ # If the entry is also in embed.fnc, it should be defined
+ # completely there, but not here
+ my $embed_docref = delete $funcflags{$name};
+ if ($embed_docref and %$embed_docref) {
+ warn "embed.fnc entry overrides redundant information in"
+ . " '$proto_in_file' in $file" if $flags || $ret || @args;
+ $flags = $embed_docref->{'flags'};
+ warn "embed.fnc entry '$name' missing 'd' flag"
+ unless $flags =~ /d/;
+ $ret = $embed_docref->{'retval'};
+ @args = @{$embed_docref->{args}};
+ } elsif ($flags !~ /m/) { # Not in embed.fnc, is missing if not a
+ # macro
+ $missing{$name} = $file;
+ }
+
die "flag $1 is not legal (for function $name (from $file))"
if $flags =~ / ( [^AabCDdEeFfhiMmNnTOoPpRrSsUuWXx] ) /x;
- next FUNC if $flags =~ /h/;
+
die "'u' flag must also have 'm' flag' for $name" if $flags =~ /u/ && $flags !~ /m/;
warn ("'$name' not \\w+ in '$proto_in_file' in $file")
if $flags !~ /N/ && $name !~ / ^ [_[:alpha:]] \w* $ /x;
- if (exists $seen{$name}) {
+ if (exists $seen{$name} && $flags !~ /h/) {
die ("'$name' in $file was already documented in $seen{$name}");
}
else {
@@ -170,36 +196,37 @@ EOS
}
my $docs = "";
-DOC:
- while (defined($doc = $get_next_line->())) {
-
- # Other pod commands are considered part of the current
- # function's docs, so can have lists, etc.
- last DOC if $doc =~ /^=(cut|for\s+apidoc|head)/;
- if ($doc =~ m:^\*/$:) {
- warn "=cut missing? $file:$line:$doc";;
- last DOC;
- }
- $docs .= $doc;
+ my $is_link_only = ($flags =~ /h/);
+ if ($is_link_only) { # Don't put meat of entry in perlapi
+ next FUNC if $file_is_C; # Don't put anything if C source
+
+ # Here, is an 'h' flag in pod. We add a reference to the pod
+ # (and nothing else) to perlapi/intern. (It would be better
+ # to add a reference to the correct =item,=header, but
+ # something that makes it harder is that it that might be a
+ # duplicate, like '=item *'; so that is a future enhancement
+ # XXX. Another complication is there might be more than one
+ # deserving candidates.)
+ undef $header_doc;
+ my $podname = $file =~ s!.*/!!r; # Rmv directory name(s)
+ $podname =~ s/\.pod//;
+ $docs .= "Described in L<$podname>.\n\n";
}
- $docs = "\n$docs" if $docs and $docs !~ /^\n/;
+ else {
+ DOC:
+ while (defined($doc = $get_next_line->())) {
- # If the entry is also in embed.fnc, it should be defined
- # completely there, but not here
- my $embed_docref = delete $funcflags{$name};
- if ($embed_docref and %$embed_docref) {
- warn "embed.fnc entry overrides redundant information in"
- . " '$proto_in_file' in $file" if $flags || $ret || @args;
- $flags = $embed_docref->{'flags'};
- warn "embed.fnc entry '$name' missing 'd' flag"
- unless $flags =~ /d/;
- next FUNC if $flags =~ /h/;
- $ret = $embed_docref->{'retval'};
- @args = @{$embed_docref->{args}};
- } elsif ($flags !~ /m/) { # Not in embed.fnc, is missing if not a
- # macro
- $missing{$name} = $file;
+ # Other pod commands are considered part of the current
+ # function's docs, so can have lists, etc.
+ last DOC if $doc =~ /^=(cut|for\s+apidoc|head)/;
+ if ($doc =~ m:^\*/$:) {
+ warn "=cut missing? $file:$line:$doc";;
+ last DOC;
+ }
+ $docs .= $doc;
+ }
}
+ $docs = "\n$docs" if $docs and $docs !~ /^\n/;
my $inline_where = $flags =~ /A/ ? 'api' : 'guts';
@@ -222,7 +249,7 @@ DOC:
$in = $doc;
redo FUNC;
}
- } else {
+ } elsif (! $is_link_only) {
warn "No doc for $file:$line:$in";
}
}
@@ -257,7 +284,13 @@ removed without notice.\n\n$docs" if $flags =~ /x/;
$docs .= ".\n\n"
}
- print $fh "=item $name\nX<$name>\n$docs";
+ print $fh "=item $name\n";
+
+ # If we're printing only a link to an element, this isn't the major entry,
+ # so no X<> here.
+ print $fh "X<$name>\n" unless $flags =~ /h/;
+
+ print $fh $docs;
if ($flags =~ /U/) { # no usage
warn("U and s flags are incompatible") if $flags =~ /s/;