The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl -w
################################################################################
#
#  scanprov -- scan Perl headers for provided macros
#
################################################################################
#
#  $Revision: 11 $
#  $Author: mhx $
#  $Date: 2010/03/07 13:15:42 +0100 $
#
################################################################################
#
#  Version 3.x, Copyright (C) 2004-2010, 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 strict;
use Getopt::Long;

require 'parts/ppptools.pl';

our %opt = (
  mode    => 'check',
  install => '/tmp/perl/install/default',
  blead   => 'bleadperl',
);

GetOptions(\%opt, qw( install=s mode=s blead=s )) or die;

my $write = $opt{mode} eq 'write';

my %embed = map { ( $_->{name} => 1 ) }
            parse_embed(qw(parts/embed.fnc parts/apidoc.fnc parts/ppport.fnc ));

my @provided = grep { !exists $embed{$_} }
               map { /^(\w+)/ ? $1 : () }
               `$^X ppport.h --list-provided`;

my @perls = sort { $b->{version} <=> $a->{version} }
            map { { version => `$_ -e 'printf "%.6f", \$]'`, path => $_ } }
            ($opt{blead}, glob "$opt{install}/*/bin/perl5.*");

for (1 .. $#perls) {
  $perls[$_]{todo} = $perls[$_-1]{version};
}

shift @perls;

my %v;

for my $p (@perls) {
  print "checking perl $p->{version}...\n";
  my $archlib = `$p->{path} -MConfig -l -e 'print \$Config{archlib}'`;
  chomp $archlib;
  local @ARGV = glob "$archlib/CORE/*.h";
  my %sym;
  while (<>) { $sym{$_}++ for /(\w+)/g; }
  @provided = map { $sym{$_} or $v{$p->{todo}}{$_}++; $sym{$_} ? $_ : () } @provided;
}

my $out = 'parts/base';
my $todo = parse_todo($out);

for my $v (keys %v) {
  my @new = sort grep { !exists $todo->{$_} } keys %{$v{$v}};
  @new or next;
  my $file = $v;
  $file =~ s/\.//g;
  $file = "$out/$file";
  -e $file or die "non-existent: $file\n";
  print "-- $file --\n";
  $write and (open F, ">>$file" or die "$file: $!\n");
  for (@new) {
    print "adding $_\n";
    $write and printf F "%-30s # added by $0\n", $_;
  }
  $write and close F;
}