1#!/usr/bin/env perl 2#*************************************************************************** 3# _ _ ____ _ 4# Project ___| | | | _ \| | 5# / __| | | | |_) | | 6# | (__| |_| | _ <| |___ 7# \___|\___/|_| \_\_____| 8# 9# Copyright (C) 2010-2011, Daniel Stenberg, <daniel@haxx.se>, et al. 10# 11# This software is licensed as described in the file COPYING, which 12# you should have received as part of this distribution. The terms 13# are also available at http://curl.haxx.se/docs/copyright.html. 14# 15# You may opt to use, copy, modify, merge, publish, distribute and/or sell 16# copies of the Software, and permit persons to whom the Software is 17# furnished to do so, under the terms of the COPYING file. 18# 19# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20# KIND, either express or implied. 21# 22########################################################################### 23# 24# This script grew out of help from Przemyslaw Iskra and Balint Szilakszi 25# a late evening in the #curl IRC channel on freenode. 26# 27 28use strict; 29use warnings; 30 31# we may get the dir root pointed out 32my $root=$ARGV[0] || "."; 33 34# need an include directory when building out-of-tree 35my $i = ($ARGV[1]) ? "-I$ARGV[1] " : ''; 36 37my $h = "$root/include/curl/curl.h"; 38my $mh = "$root/include/curl/multi.h"; 39 40my $verbose=0; 41my $summary=0; 42my $misses=0; 43 44my @syms; 45my %doc; 46my %rem; 47 48open H_IN, "-|", "cc -E $i$h" || die "Cannot preprocess curl.h"; 49while ( <H_IN> ) { 50 if ( /enum\s+(\S+\s+)?{/ .. /}/ ) { 51 s/^\s+//; 52 next unless /^CURL/; 53 chomp; 54 s/[,\s].*//; 55 push @syms, $_; 56 } 57} 58close H_IN || die "Error preprocessing curl.h"; 59 60sub scanheader { 61 my ($f)=@_; 62 open H, "<$f"; 63 while(<H>) { 64 if (/^#define (CURL[A-Za-z0-9_]*)/) { 65 push @syms, $1; 66 } 67 } 68 close H; 69} 70 71scanheader($h); 72scanheader($mh); 73 74open S, "<$root/docs/libcurl/symbols-in-versions"; 75while(<S>) { 76 if(/(^CURL[^ \n]*) *(.*)/) { 77 my ($sym, $rest)=($1, $2); 78 if($doc{$sym}) { 79 print "Detected duplicate symbol: $sym\n"; 80 $misses++; 81 next; 82 } 83 $doc{$sym}=$sym; 84 my @a=split(/ +/, $rest); 85 if($a[2]) { 86 # this symbol is documented to have been present the last time 87 # in this release 88 $rem{$sym}=$a[2]; 89 } 90 } 91} 92close S; 93 94my $ignored=0; 95for my $e (sort @syms) { 96 # OBSOLETE - names that are just placeholders for a position where we 97 # previously had a name, that is now removed. The OBSOLETE names should 98 # never be used for anything. 99 # 100 # CURL_EXTERN - is a define used for libcurl functions that are external, 101 # public. No app or other code should ever use it. 102 # 103 # *_LAST and *_LASTENTRY are just prefix for the placeholders used for the 104 # last entry in many enum series. 105 # 106 107 if($e =~ /(OBSOLETE|^CURL_EXTERN|_LAST\z|_LASTENTRY\z)/) { 108 $ignored++; 109 next; 110 } 111 if($doc{$e}) { 112 if($verbose) { 113 print $e."\n"; 114 } 115 $doc{$e}="used"; 116 next; 117 } 118 else { 119 print $e."\n"; 120 $misses++; 121 } 122} 123 124# 125# now scan through all symbols that were present in the symbols-in-versions 126# but not in the headers 127# 128# If the symbols were marked 'removed' in symbols-in-versions we don't output 129# anything about it since that is perfectly fine. 130# 131 132my $anyremoved; 133 134for my $e (sort keys %doc) { 135 if(($doc{$e} ne "used") && !$rem{$e}) { 136 137 if(!$anyremoved++) { 138 print "Missing symbols mentioned in symbols-in-versions\n"; 139 print "Add them to a header, or mark them as removed.\n"; 140 } 141 142 print "$e\n"; 143 $misses++; 144 } 145} 146 147if($summary) { 148 print "Summary:\n"; 149 printf "%d symbols in headers (out of which %d are ignored)\n", scalar(@syms), 150 $ignored; 151 printf "%d symbols in headers are interesting\n", 152 scalar(@syms)- $ignored; 153 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); 154 printf "%d symbols in symbols-in-versions should match the ones in headers\n", scalar(keys %doc) - scalar(keys %rem); 155} 156 157if($misses) { 158 exit 2; # there are stuff to attend to! 159} 160