This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
devel/mkapidoc.pl: Rewrite entirely in perl
authorKarl Williamson <khw@cpan.org>
Mon, 19 Aug 2019 22:42:45 +0000 (16:42 -0600)
committerNicolas R <atoomic@cpan.org>
Fri, 27 Sep 2019 22:51:28 +0000 (16:51 -0600)
The old version, partially in sh, grabbed every file in the directory
structure, looking for apidoc lines.  Unfortunately that included
things, in .git, for example, and those could be out-of-date entries,
with the result that there could be multiple entries with different
prototypes for the same macro.

This commit changes to read only MANIFEST files, and a few generated
files.

(cherry picked from commit d8bc0a3f40e83e52934696240c2d89398465a56c)
Signed-off-by: Nicolas R <atoomic@cpan.org>
MANIFEST
Porting/exec-bit.txt
dist/Devel-PPPort/devel/mkapidoc.pl [new file with mode: 0644]
dist/Devel-PPPort/devel/mkapidoc.sh [deleted file]
dist/Devel-PPPort/parts/apidoc.fnc

index d1bff40..c718c04 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -2960,7 +2960,6 @@ dist/Devel-PPPort/apicheck_c.PL           Devel::PPPort apicheck generator
 dist/Devel-PPPort/Changes                      Devel::PPPort Changes file
 dist/Devel-PPPort/devel/buildperl.pl   Devel::PPPort perl version builder
 dist/Devel-PPPort/devel/devtools.pl    Devel::PPPort development utilities
-dist/Devel-PPPort/devel/mkapidoc.sh    Devel::PPPort apidoc collector
 dist/Devel-PPPort/devel/mktodo         Devel::PPPort baseline/todo generator
 dist/Devel-PPPort/devel/mktodo.pl      Devel::PPPort baseline/todo generator
 dist/Devel-PPPort/devel/regenerate     Devel::PPPort API re-generator
index bb0daee..d5c727c 100644 (file)
@@ -14,7 +14,6 @@ cpan/autodie/t/chmod.t
 cpan/CPAN-Meta-YAML/t/tml
 cpan/Test-Harness/t/source_tests/source.sh
 cpan/Test-Harness/t/source_tests/source_args.sh
-dist/Devel-PPPort/devel/mkapidoc.sh
 dist/Devel-PPPort/devel/mktodo
 dist/Devel-PPPort/devel/regenerate
 dist/Devel-PPPort/devel/scanprov
diff --git a/dist/Devel-PPPort/devel/mkapidoc.pl b/dist/Devel-PPPort/devel/mkapidoc.pl
new file mode 100644 (file)
index 0000000..b3a5946
--- /dev/null
@@ -0,0 +1,132 @@
+################################################################################
+#
+#  mkapidoc.pl -- generate apidoc.fnc from scanning the Perl source
+#
+# Should be called from the base directory for Devel::PPPort.
+# If that happens to be in the /dist directory of a perl build structure, and
+# you're doing the standard thing, no parameters are required.  Otherwise
+# (again with the standard things, its single parameter is the base directory
+# of the perl source tree to be used.
+#
+################################################################################
+#
+#  Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
+#  Version 2.x, Copyright (C) 2001, Paul Marquess.
+#  Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the same terms as Perl itself.
+#
+################################################################################
+
+use warnings;
+use strict;
+
+my $PERLROOT = $ARGV[0];
+$PERLROOT = '../..' unless $PERLROOT;
+
+die "'$PERLROOT' is invalid, or you haven't successfully run 'make' in it"
+                                                unless -e "$PERLROOT/warnings.h";
+    
+my $config= "$PERLROOT/config_h.SH";
+my %seen;
+
+# Find the files in MANIFEST that are core, but not embed.fnc, nor .t's
+my @files;
+open(my $m, '<', "$PERLROOT/MANIFEST") || die "MANIFEST:$!";
+while (<$m>) {                      # In embed.fnc,
+    chomp;
+    next if m! ^ embed \. fnc \t !x;
+    next if m! ^ ( cpan | dist | t) / !x;
+    next if m! [^\t]* \.t \t !x;
+    push @files, $_;
+}
+
+# These files are also needed.  This might have to be added to in the future.
+push @files, qw(pod/perlguts.pod lib/perlxs.pod);
+
+# Find the apidoc entries in all these files
+my @entries;
+for (@files) {
+
+    s/ \t .* //x;
+    open my $f, '<', "$PERLROOT/$_" or die "Can't open $_: $!";
+
+    my $line;
+    while (defined ($line = <$f>)) {
+        chomp $line;
+        next unless $line =~ /^ =for \s+ apidoc \s+ 
+                             (  [^|]* \|        # flags
+                                [^|]* \|        # return type
+                              ( [^|]* )         # name
+                                (?: \| .* )?    # optional args
+                             ) /x;
+        my $meat = $1;
+        my $name = $2;
+
+        if (exists $seen{$name}) {
+            if ($seen{$name} ne $meat) {
+                print STDERR
+                    "Contradictory prototypes for $name,\n$seen{$name}\n$meat\n";
+            }
+            next;
+        }
+
+        $meat =~ s/[ \t]+$//;
+        $seen{$name} = $meat;
+
+        # Many of the entries omit the "d" flag to indicate they are
+        # documented, but we wouldn't have found this unless it was documented
+        # in the source
+        $meat =~ s/\|/d|/ unless $meat =~ /^[^|]*d/;
+
+        push @entries, "$meat\n";
+    }
+}
+
+# The entries in config_h.SH are also (documented) macros that are
+# accessible to XS code, and ppport.h backports some of them.  We
+# use only the unconditionally compiled parameterless ones (as
+# that"s all that"s backported so far, and we don"t have to know
+# the types of the parameters).
+open(my $c, "<", $config) or die "$config: $!";
+my $if_depth = 0;   # We don"t use the ones within #if statements
+                    # The #ifndef that guards the whole file is not
+                    # noticed by the code below
+while (<$c>) {
+    $if_depth ++ if / ^ \# [[:blank:]]* (ifdef | if\ defined ) /x;
+    $if_depth -- if $if_depth > 0 && / ^ \# [[:blank:]]* endif /x;
+    next unless $if_depth <= 0;
+
+    # We are only interested in #defines with no parameters
+    next unless /^ \# [[:blank:]]* define [[:blank:]]+
+                        ( [A-Za-z][A-Za-z0-9]* )
+                        [[:blank:]]
+                /x;
+    next if $seen{$1}; # Ignore duplicates
+    push @entries, "Amnd||$1\n";
+    $seen{$1}++;
+}
+close $c or die "Close failed: $!";
+
+open my $out, ">", "parts/apidoc.fnc"
+                        or die "Can't open 'parts/apidoc.fnc' for writing: $!";
+require "./parts/inc/inctools";
+print $out <<EOF;
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+:
+:  !!!! Do NOT edit this file directly! -- Edit devel/mkapidoc.sh instead. !!!!
+:
+:  This file was automatically generated from the API documentation scattered
+:  all over the Perl source code. To learn more about how all this works,
+:  please read the F<HACKERS> file that came with this distribution.
+:
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+
+:
+: This file lists all API functions/macros that are documented in the Perl
+: source code, but are not contained in F<embed.fnc>.
+:
+EOF
+print $out sort sort_api_lines @entries;
+close $out or die "Close failed: $!";
diff --git a/dist/Devel-PPPort/devel/mkapidoc.sh b/dist/Devel-PPPort/devel/mkapidoc.sh
deleted file mode 100755 (executable)
index 9830ec8..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/bin/bash
-################################################################################
-#
-#  mkapidoc.sh -- generate apidoc.fnc from scanning the Perl source
-#
-# Should be called from the base directory for Devel::PPPort.
-# If that happens to be in the /dist directory of a perl build structure, and
-# you're doing the standard thing, no parameters are required.  Otherwise
-# (again with the standard things, it can be called with one parameter:
-#       sh devel/mkapidoc.sh /path/to/the/embed.fnc/you/want
-#
-################################################################################
-#
-#  Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
-#  Version 2.x, Copyright (C) 2001, Paul Marquess.
-#  Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
-#
-#  This program is free software; you can redistribute it and/or
-#  modify it under the same terms as Perl itself.
-#
-################################################################################
-
-function isperlroot
-{
-  [ -f "$1/embed.fnc" ] && [ -f "$1/perl.h" ]
-}
-
-function usage
-{
-  echo "USAGE: $0 [perlroot] [output-file] [input embed.fnc] [input config_h.SH]"
-  exit 0
-}
-
-if [ -z "$1" ]; then
-  if isperlroot "../../.."; then
-    PERLROOT=../../..
-  fi
-else
-  PERLROOT=$1
-fi
-
-if [ -z "$2" ]; then
-  if [ -f "parts/apidoc.fnc" ]; then
-    OUTPUT="parts/apidoc.fnc"
-  else
-    usage
-  fi
-else
-  OUTPUT=$2
-fi
-
-if [ -z "$3" ]; then
-  EMBED="$PERLROOT/embed.fnc"
-else
-  EMBED=$3
-fi
-
-if [ -z "$4" ]; then
-  CONFIG="$PERLROOT/config_h.SH"
-else
-  CONFIG=$4
-fi
-
-if isperlroot $PERLROOT; then
-  cat >$OUTPUT <<EOF
-::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-:
-:  !!!! Do NOT edit this file directly! -- Edit devel/mkapidoc.sh instead. !!!!
-:
-:  This file was automatically generated from the API documentation scattered
-:  all over the Perl source code. To learn more about how all this works,
-:  please read the F<HACKERS> file that came with this distribution.
-:
-::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
-
-:
-: This file lists all API functions/macros that are documented in the Perl
-: source code, but are not contained in F<embed.fnc>.
-:
-EOF
-    grep -hr '^=for apidoc' $PERLROOT | sed -e 's/=for apidoc //'           \
-  | grep '|'                                                                \
-  | sort                                                                    \
-  | uniq                                                                    \
-  | sort -f -t'|' -k3                                                       \
-  | perl -e 'use warnings;
-             use strict;
-             my $c=pop;
-             my $f=pop;
-             my %h;
-
-             # Populate %h with the embed.fnc entry names
-             open(F,$f) || die "$f:$!";
-             while (<F>) {                      # In embed.fnc,
-                next unless /^[A-Za-z]+\t/;     # skip lines that arent defns
-                (  split /\s*\|\s*/ ) [2] =~ /(\w+)/;
-                $h{$1}++;   # Note in %h that $1 is in $EMBED
-            }
-            close F;
-
-            # STDIN consists of the =for apidoc lines.  Those in embed.fnc
-            # already give us their prototypes, so skip.  Otherwise massage the
-            # input somewhat and save them
-            my @entries;
-            while (<>) {
-                s/\|/d|/ unless /^[^|]*d/; # Many of the entries omit the "d"
-                                           # flag to indicate they are
-                                           # documented, but  we wouldnt have
-                                           # found this unless it was
-                                           # documented in the source
-                s/[ \t]+$//;
-                (  split /\s*\|\s*/  ) [2] =~ /(\w+)/;
-                push @entries, $_ unless $h{$1}
-            }
-
-            # The entries in config_h.SH are also (documented) macros that are
-            # accessible to XS code, and ppport.h backports some of them.  We
-            # use only the unconditionally compiled parameterless ones (as
-            # that"s all that"s backported so far, and we don"t have to know
-            # the types of the parameters.
-            open(C, "<", $c) or die "$c: $!";
-            my $if_depth = 0;   # We don"t use the ones within #if statements
-                                # The #ifndef that guards the whole file is not
-                                # noticed by the code below
-            while (<C>) {
-                $if_depth ++ if / ^ \# [[:blank:]]* (ifdef | if\ defined ) /x;
-                $if_depth -- if $if_depth > 0 && / ^ \# [[:blank:]]* endif /x;
-                next unless $if_depth <= 0;
-
-                # We are only interested in #defines with no parameters
-                next unless /^ \# [[:blank:]]* define [[:blank:]]+
-                                 ( [A-Za-z][A-Za-z0-9]* )
-                                 [[:blank:]]
-                            /x;
-                next if $h{$1}; # Ignore duplicates
-                push @entries, "Amnd||$1\n";
-                $h{$1}++;
-            }
-            close C;
-
-            require "./parts/inc/inctools";
-            print sort sort_api_lines @entries;
-           '  $EMBED $CONFIG >> $OUTPUT
-else
-  echo "$0: First parameter must be a directory containing embed.fnc and perl.h"
-  usage
-fi
index 048ddf4..3547c49 100644 (file)
@@ -127,7 +127,6 @@ Amd|AV*|GvAV|GV* gv
 Amd|CV*|GvCV|GV* gv
 Amd|HV*|GvHV|GV* gv
 AmnUd||G_VOID
-Amd|HV*|gv_stashpvs|"literal string" name|I32 create
 Amd|HV*|gv_stashpvs|"name"|I32 create
 Amnhd||GV_SUPER
 Amd|SV*|GvSV|GV* gv
@@ -145,13 +144,11 @@ Amd|char*|HvENAME|HV* stash
 Amd|STRLEN|HvENAMELEN|HV *stash
 Amd|unsigned char|HvENAMEUTF8|HV *stash
 Amd|SV**|hv_fetchs|HV* tb|"key"|I32 lval
-Amd|SV**|hv_fetchs|HV* tb|"literal string" key|I32 lval
 Amd|STRLEN|HvFILL|HV *const hv
 Amd|char*|HvNAME|HV* stash
 Amd|STRLEN|HvNAMELEN|HV *stash
 Amd|unsigned char|HvNAMEUTF8|HV *stash
 Amd|SV**|hv_stores|HV* tb|"key"|SV* val
-Amd|SV**|hv_stores|HV* tb|"literal string" key|SV* val
 Amnd||I16SIZE
 Amnd||I16TYPE
 Amnd||I32SIZE
@@ -338,14 +335,12 @@ Amhd|bool|isXDIGIT_utf8_safe|U8 * s|U8 * end
 Amhd|bool|isXDIGIT_uvchr|int ch
 Amnd|I32|items
 Amnhd||IVdf
-Amnd||IVdf
 Amnd||IVSIZE
 Amnd||IVTYPE
 Amnd|I32|ix
 Amd|U8|LATIN1_TO_NATIVE|U8 ch
 Amnsd||LEAVE
 Amsd||LEAVE_with_name|"name"
-Amxd|void|lex_stuff_pvs|"literal string" pv|U32 flags
 Amxd|void|lex_stuff_pvs|"pv"|U32 flags
 AmUd|bool|LIKELY|const bool expr
 Amd|OP*|LINKLIST|OP *o
@@ -357,10 +352,8 @@ Amnd||LSEEKSIZE
 mnUd||LVRET
 AmnUd||MARK
 Amd|bool|memEQ|char* s1|char* s2|STRLEN len
-Amd|bool|memEQs|char* s1|STRLEN l1|"literal string" s2
 Amd|bool|memEQs|char* s1|STRLEN l1|"s2"
 Amd|bool|memNE|char* s1|char* s2|STRLEN len
-Amd|bool|memNEs|char* s1|STRLEN l1|"literal string" s2
 Amd|bool|memNEs|char* s1|STRLEN l1|"s2"
 Amd|void|Move|void* src|void* dest|int nitems|type
 Amd|void *|MoveD|void* src|void* dest|int nitems|type
@@ -385,11 +378,8 @@ Amd|SV*|newRV_inc|SV* sv
 Amxd|SV*|newSVpadname|PADNAME *pn
 Amd|SV*|newSVpvn_utf8|const char* s|STRLEN len|U32 utf8
 Amad|SV*|newSVpvs|"literal string"
-Amad|SV*|newSVpvs|"literal string" s
-Amad|SV*|newSVpvs_flags|"literal string" s|U32 flags
 Amad|SV*|newSVpvs_flags|"literal string"|U32 flags
 Amad|SV*|newSVpvs_share|"literal string"
-Amad|SV*|newSVpvs_share|"literal string" s
 Amd|void|Newx|void* ptr|int nitems|type
 Amd|void|Newxc|void* ptr|int nitems|type|cast
 AmUd||newXSproto|char* name|XSUBADDR_t f|char* filename|const char *proto
@@ -400,11 +390,8 @@ ADmnUd||Nullcv
 ADmnUd||Nullhv
 AmnUd||Nullsv
 Amnhd||NVef
-Amnd||NVef
 Amnhd||NVff
-Amnd||NVff
 Amnhd||NVgf
-Amnd||NVgf
 Amnd||NVMANTBITS
 Amnd||NVSIZE
 Amnd||NVTYPE
@@ -592,10 +579,10 @@ Amnd|STRLEN|PL_na
 mnd|GV*|PL_ofsgv
 Amnd|Perl_ophook_t|PL_opfreehook
 AmnUd|yy_parser *|PL_parser
+AmnxUNd|SV *|PL_parser-E<gt>linestr
 AmnxUNd|char *|PL_parser-E<gt>bufend
 AmnxUNd|char *|PL_parser-E<gt>bufptr
 AmnxUNd|char *|PL_parser-E<gt>linestart
-AmnxUNd|SV *|PL_parser-E<gt>linestr
 Amnd|peep_t|PL_peepp
 Amnd|signed char|PL_perl_destruct_level
 Amnd|peep_t|PL_rpeepp
@@ -655,9 +642,7 @@ md|void|SAVECOMPPAD
 mnd|void|SAVE_ERRNO
 md|void|SAVEPADSV      |PADOFFSET po
 Amad|char*|savepvs|"literal string"
-Amad|char*|savepvs|"literal string" s
 Amad|char*|savesharedpvs|"literal string"
-Amad|char*|savesharedpvs|"literal string" s
 Amnsd||SAVETMPS
 md|void|SETERRNO|int errcode|int vmserrcode
 Amnd||SHORTSIZE
@@ -689,13 +674,9 @@ Amud|pair|STR_WITH_LEN|"literal string"
 Amd|void|sv_catpvn_nomg|SV* sv|const char* ptr|STRLEN len
 Amd|void|sv_catpv_nomg|SV* sv|const char* ptr
 Amd|void|sv_catpvs|SV* sv|"literal string"
-Amd|void|sv_catpvs|SV* sv|"literal string" s
 Amd|void|sv_catpvs_flags|SV* sv|"literal string"|I32 flags
-Amd|void|sv_catpvs_flags|SV* sv|"literal string" s|I32 flags
 Amd|void|sv_catpvs_mg|SV* sv|"literal string"
-Amd|void|sv_catpvs_mg|SV* sv|"literal string" s
 Amd|void|sv_catpvs_nomg|SV* sv|"literal string"
-Amd|void|sv_catpvs_nomg|SV* sv|"literal string" s
 Amd|void|sv_catsv_nomg|SV* dsv|SV* ssv
 Amnhd||SV_COW_DROP_PV
 Amd|STRLEN|SvCUR|SV* sv
@@ -796,11 +777,8 @@ Amd|void|SvSETMAGIC|SV* sv
 Amd|void|SvSetMagicSV|SV* dsv|SV* ssv
 Amd|void|SvSetMagicSV_nosteal|SV* dsv|SV* ssv
 Amd|void|sv_setpvs|SV* sv|"literal string"
-Amd|void|sv_setpvs|SV* sv|"literal string" s
 Amd|void|sv_setpvs_mg|SV* sv|"literal string"
-Amd|void|sv_setpvs_mg|SV* sv|"literal string" s
 Amd|SV *|sv_setref_pvs|SV *const rv|const char *const classname|"literal string"
-Amd|SV *|sv_setref_pvs|SV *const rv|const char *const classname|"literal string" s
 Amd|void|SvSetSV|SV* dsv|SV* ssv
 Amd|void|sv_setsv_nomg|SV* dsv|SV* ssv
 Amd|void|SvSetSV_nosteal|SV* dsv|SV* ssv
@@ -887,14 +865,11 @@ Amd|STRLEN|UTF8SKIP|char* s
 Amd|bool|UVCHR_IS_INVARIANT|UV cp
 Amd|STRLEN|UVCHR_SKIP|UV cp
 Amnhd||UVof
-Amnd||UVof
 Amnd||UVSIZE
 Amnd||UVTYPE
 Amnhd||UVuf
-Amnd||UVuf
 Amnd||UVXf
 Amnhd||UVxf
-Amnd||UVxf
 Amnhd||WARN_ALL
 Amnhd||WARN_AMBIGUOUS
 Amnhd||WARN_BAREWORD