This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
devel/scanprov: Use library fcn to find perl versions
[perl5.git] / dist / Devel-PPPort / devel / scanprov
CommitLineData
adfe19db
MHM
1#!/usr/bin/perl -w
2################################################################################
3#
4# scanprov -- scan Perl headers for provided macros
5#
6################################################################################
7#
b2049988 8# Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
adfe19db
MHM
9# Version 2.x, Copyright (C) 2001, Paul Marquess.
10# Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
11#
12# This program is free software; you can redistribute it and/or
13# modify it under the same terms as Perl itself.
14#
15################################################################################
16
17use strict;
49ef49fe
CBW
18use Getopt::Long;
19
3d7c117d 20require './parts/ppptools.pl';
55179e46 21require './parts/inc/inctools';
97b9d11f 22require './devel/devtools.pl';
adfe19db 23
49ef49fe
CBW
24our %opt = (
25 mode => 'check',
26 install => '/tmp/perl/install/default',
27 blead => 'bleadperl',
97b9d11f
KW
28 debug => 0,
29 'debug-start' => "",
49ef49fe
CBW
30);
31
97b9d11f 32GetOptions(\%opt, qw( install=s mode=s blead=s debug debug-start=s)) or die;
49ef49fe
CBW
33
34my $write = $opt{mode} eq 'write';
adfe19db
MHM
35
36my %embed = map { ( $_->{name} => 1 ) }
679ad62d 37 parse_embed(qw(parts/embed.fnc parts/apidoc.fnc parts/ppport.fnc ));
adfe19db 38
c48f5549
KW
39# @provided is set to the elements that are provided, but not functions in the
40# .fnc files
adfe19db
MHM
41my @provided = grep { !exists $embed{$_} }
42 map { /^(\w+)/ ? $1 : () }
43 `$^X ppport.h --list-provided`;
44
97b9d11f 45my $perls_ref = get_and_sort_perls(\%opt);
adfe19db 46
c48f5549 47# Get rid of blead
97b9d11f
KW
48shift @$perls_ref;
49
50die "Couldn't find any perls" unless @$perls_ref > 1;
adfe19db
MHM
51
52my %v;
53
c48f5549
KW
54# We look in descending order of perl versions. Each time through the loop
55# @provided is narrowed.
97b9d11f 56for my $p (@$perls_ref) {
a745474a 57 print "checking perl $p->{version}...\n";
c48f5549
KW
58
59 # Get the hdr files associated with this version
adfe19db
MHM
60 my $archlib = `$p->{path} -MConfig -l -e 'print \$Config{archlib}'`;
61 chomp $archlib;
62 local @ARGV = glob "$archlib/CORE/*.h";
63 my %sym;
c48f5549
KW
64
65 # %sym's keys are every single \w+ that occurs in all the headers,
66 # regardless of if they are in a comment, or what.
adfe19db 67 while (<>) { $sym{$_}++ for /(\w+)/g; }
c48f5549
KW
68
69 # @provided is narrowed to include only those \w+ things that are mentioned
70 # in some hdr in this release. (If it isn't even mentioned, it won't exist in
71 # the release.) For those not mentioned, a key is added of the \w+ in %v.
72 # It is a subkey of this release's "todo" release, which is the next higher
73 # one. If we are at version n, we have already done version n+1 and the
74 # provided element was mentioned there, and now it no longer is. We take
75 # that to mean that to mean that the element became provided for in n+1.
76 # (khw notes that it could have just been in a comment for a bunch of
77 # releases above this, like
78 # /* Oh how I wish we had FOO */
79 # and at some point FOO got added. The method here is, hence, just a
80 # heuristic.
81 @provided = map { $sym{$_} or $v{$p->{todo}}{$_}++;
82 $sym{$_} ? $_ : ()
83 } @provided;
adfe19db
MHM
84}
85
c48f5549
KW
86# Read in the parts/base files. The hash ref has keys being all symbols found
87# in all the files in base/, and the values being the perl versions each symbol
88# became defined in.
adfe19db 89my $out = 'parts/base';
c2be1425 90my $base_ref = parse_todo($out);
adfe19db 91
c48f5549
KW
92# Now add the results from above. At this point, The keys of %v are the 7
93# digit BCD version numbers, and their subkeys are the symbols provided by
94# D:P that are first mentioned in this version, like this:
95# '5009002' => {
96# 'MY_CXT_CLONE' => 1,
97# 'SV_NOSTEAL' => 1,
98# 'UTF8_MAXBYTES' => 1
99# },
100
adfe19db 101for my $v (keys %v) {
c48f5549
KW
102
103 # @new becomes the symbols for version $v not already in the file for $v
c2be1425 104 my @new = sort dictionary_order grep { !exists $base_ref->{$_} }
c48f5549
KW
105 keys %{$v{$v}};
106 @new or next; # Nothing new, skip writing
107
adfe19db
MHM
108 my $file = $v;
109 $file =~ s/\.//g;
110 $file = "$out/$file";
111 -e $file or die "non-existent: $file\n";
a745474a 112 print "-- $file --\n";
49ef49fe 113 $write and (open F, ">>$file" or die "$file: $!\n");
a745474a
MHM
114 for (@new) {
115 print "adding $_\n";
49ef49fe 116 $write and printf F "%-30s # added by $0\n", $_;
a745474a 117 }
49ef49fe 118 $write and close F;
adfe19db 119}