use strict;
use warnings;
use vars qw($Cpreprocessor);
my $rc = eval {
require configurehelp;
configurehelp->import(qw(
$Cpreprocessor
));
1;
};
if (!$rc) {
$Cpreprocessor = 'cpp';
}
my $root=$ARGV[0] || ".";
my $i = ($ARGV[1]) ? "-I$ARGV[1] " : '';
my $h = "$root/include/curl/curl.h";
my $mh = "$root/include/curl/multi.h";
my $ua = "$root/include/curl/urlapi.h";
my $verbose=0;
my $summary=0;
my $misses=0;
my @syms;
my %doc;
my %rem;
open H_IN, "-|", "$Cpreprocessor $i$h" || die "Cannot preprocess curl.h";
while ( <H_IN> ) {
if ( /enum\s+(\S+\s+)?{/ .. /}/ ) {
s/^\s+//;
next unless /^CURL/;
chomp;
s/[,\s].*//;
push @syms, $_;
}
}
close H_IN || die "Error preprocessing curl.h";
sub scanheader {
my ($f)=@_;
open H, "<$f";
while(<H>) {
if (/^ push @syms, $1;
}
}
close H;
}
scanheader($h);
scanheader($mh);
scanheader($ua);
open S, "<$root/docs/libcurl/symbols-in-versions";
while(<S>) {
if(/(^CURL[^ \n]*) *(.*)/) {
my ($sym, $rest)=($1, $2);
if($doc{$sym}) {
print "Detected duplicate symbol: $sym\n";
$misses++;
next;
}
$doc{$sym}=$sym;
my @a=split(/ +/, $rest);
if($a[2]) {
$rem{$sym}=$a[2];
}
}
}
close S;
my $ignored=0;
for my $e (sort @syms) {
if($e =~ /(OBSOLETE|^CURL_EXTERN|_LAST\z|_LASTENTRY\z)/) {
$ignored++;
next;
}
if($doc{$e}) {
if($verbose) {
print $e."\n";
}
$doc{$e}="used";
next;
}
else {
print $e."\n";
$misses++;
}
}
my $anyremoved;
for my $e (sort keys %doc) {
if(($doc{$e} ne "used") && !$rem{$e}) {
if(!$anyremoved++) {
print "Missing symbols mentioned in symbols-in-versions\n";
print "Add them to a header, or mark them as removed.\n";
}
print "$e\n";
$misses++;
}
}
if($summary) {
print "Summary:\n";
printf "%d symbols in headers (out of which %d are ignored)\n", scalar(@syms),
$ignored;
printf "%d symbols in headers are interesting\n",
scalar(@syms)- $ignored;
printf "%d symbols are listed in symbols-in-versions\n (out of which %d are listed as removed)\n", scalar(keys %doc), scalar(keys %rem);
printf "%d symbols in symbols-in-versions should match the ones in headers\n", scalar(keys %doc) - scalar(keys %rem);
}
if($misses) {
exit 2; }