2 ################################################################################
4 # scanprov -- scan Perl headers for provided macros
6 ################################################################################
8 # Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
9 # Version 2.x, Copyright (C) 2001, Paul Marquess.
10 # Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
12 # This program is free software; you can redistribute it and/or
13 # modify it under the same terms as Perl itself.
15 ################################################################################
20 require './parts/ppptools.pl';
21 require './parts/inc/inctools';
25 install => '/tmp/perl/install/default',
29 GetOptions(\%opt, qw( install=s mode=s blead=s )) or die;
31 my $write = $opt{mode} eq 'write';
33 my %embed = map { ( $_->{name} => 1 ) }
34 parse_embed(qw(parts/embed.fnc parts/apidoc.fnc parts/ppport.fnc ));
36 # @provided is set to the elements that are provided, but not functions in the
38 my @provided = grep { !exists $embed{$_} }
39 map { /^(\w+)/ ? $1 : () }
40 `$^X ppport.h --list-provided`;
42 my @perls = sort { $b->{version} <=> $a->{version} }
43 map { { version => `$_ -e 'printf "%.6f", \$]'`, path => $_ } }
44 ($opt{blead}, glob "$opt{install}/*/bin/perl5.*");
47 $perls[$_]{todo} = $perls[$_-1]{version};
55 # We look in descending order of perl versions. Each time through the loop
56 # @provided is narrowed.
58 print "checking perl $p->{version}...\n";
60 # Get the hdr files associated with this version
61 my $archlib = `$p->{path} -MConfig -l -e 'print \$Config{archlib}'`;
63 local @ARGV = glob "$archlib/CORE/*.h";
66 # %sym's keys are every single \w+ that occurs in all the headers,
67 # regardless of if they are in a comment, or what.
68 while (<>) { $sym{$_}++ for /(\w+)/g; }
70 # @provided is narrowed to include only those \w+ things that are mentioned
71 # in some hdr in this release. (If it isn't even mentioned, it won't exist in
72 # the release.) For those not mentioned, a key is added of the \w+ in %v.
73 # It is a subkey of this release's "todo" release, which is the next higher
74 # one. If we are at version n, we have already done version n+1 and the
75 # provided element was mentioned there, and now it no longer is. We take
76 # that to mean that to mean that the element became provided for in n+1.
77 # (khw notes that it could have just been in a comment for a bunch of
78 # releases above this, like
79 # /* Oh how I wish we had FOO */
80 # and at some point FOO got added. The method here is, hence, just a
82 @provided = map { $sym{$_} or $v{$p->{todo}}{$_}++;
87 # Read in the parts/base files. The hash ref has keys being all symbols found
88 # in all the files in base/, and the values being the perl versions each symbol
90 my $out = 'parts/base';
91 my $todo = parse_todo($out);
93 # Now add the results from above. At this point, The keys of %v are the 7
94 # digit BCD version numbers, and their subkeys are the symbols provided by
95 # D:P that are first mentioned in this version, like this:
97 # 'MY_CXT_CLONE' => 1,
99 # 'UTF8_MAXBYTES' => 1
102 for my $v (keys %v) {
104 # @new becomes the symbols for version $v not already in the file for $v
105 my @new = sort dictionary_order grep { !exists $todo->{$_} }
107 @new or next; # Nothing new, skip writing
111 $file = "$out/$file";
112 -e $file or die "non-existent: $file\n";
113 print "-- $file --\n";
114 $write and (open F, ">>$file" or die "$file: $!\n");
117 $write and printf F "%-30s # added by $0\n", $_;