Home | History | Annotate | Download | only in tests
      1 #!/usr/bin/env perl
      2 #***************************************************************************
      3 #                                  _   _ ____  _
      4 #  Project                     ___| | | |  _ \| |
      5 #                             / __| | | | |_) | |
      6 #                            | (__| |_| |  _ <| |___
      7 #                             \___|\___/|_| \_\_____|
      8 #
      9 # Copyright (C) 2010-2011, Daniel Stenberg, <daniel (at] 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 
     28 use strict;
     29 use warnings;
     30 use vars qw($Cpreprocessor);
     31 
     32 #
     33 # configurehelp perl module is generated by configure script
     34 #
     35 my $rc = eval {
     36     require configurehelp;
     37     configurehelp->import(qw(
     38         $Cpreprocessor
     39     ));
     40     1;
     41 };
     42 # Set default values if configure has not generated a configurehelp.pm file.
     43 # This is the case with cmake.
     44 if (!$rc) {
     45     $Cpreprocessor = 'cpp';
     46 }
     47 
     48 # we may get the dir root pointed out
     49 my $root=$ARGV[0] || ".";
     50 
     51 # need an include directory when building out-of-tree
     52 my $i = ($ARGV[1]) ? "-I$ARGV[1] " : '';
     53 
     54 my $h = "$root/include/curl/curl.h";
     55 my $mh = "$root/include/curl/multi.h";
     56 
     57 my $verbose=0;
     58 my $summary=0;
     59 my $misses=0;
     60 
     61 my @syms;
     62 my %doc;
     63 my %rem;
     64 
     65 open H_IN, "-|", "$Cpreprocessor $i$h" || die "Cannot preprocess curl.h";
     66 while ( <H_IN> ) {
     67     if ( /enum\s+(\S+\s+)?{/ .. /}/ ) {
     68         s/^\s+//;
     69         next unless /^CURL/;
     70         chomp;
     71         s/[,\s].*//;
     72         push @syms, $_;
     73     }
     74 }
     75 close H_IN || die "Error preprocessing curl.h";
     76 
     77 sub scanheader {
     78     my ($f)=@_;
     79     open H, "<$f";
     80     while(<H>) {
     81         if (/^#define (CURL[A-Za-z0-9_]*)/) {
     82             push @syms, $1;
     83         }
     84     }
     85     close H;
     86 }
     87 
     88 scanheader($h);
     89 scanheader($mh);
     90 
     91 open S, "<$root/docs/libcurl/symbols-in-versions";
     92 while(<S>) {
     93     if(/(^CURL[^ \n]*) *(.*)/) {
     94         my ($sym, $rest)=($1, $2);
     95         if($doc{$sym}) {
     96             print "Detected duplicate symbol: $sym\n";
     97             $misses++;
     98             next;
     99         }
    100         $doc{$sym}=$sym;
    101         my @a=split(/ +/, $rest);
    102         if($a[2]) {
    103             # this symbol is documented to have been present the last time
    104             # in this release
    105             $rem{$sym}=$a[2];
    106         }
    107     }
    108 }
    109 close S;
    110 
    111 my $ignored=0;
    112 for my $e (sort @syms) {
    113     # OBSOLETE - names that are just placeholders for a position where we
    114     # previously had a name, that is now removed. The OBSOLETE names should
    115     # never be used for anything.
    116     #
    117     # CURL_EXTERN - is a define used for libcurl functions that are external,
    118     # public. No app or other code should ever use it.
    119     #
    120     # *_LAST and *_LASTENTRY are just prefix for the placeholders used for the
    121     # last entry in many enum series.
    122     #
    123 
    124     if($e =~ /(OBSOLETE|^CURL_EXTERN|_LAST\z|_LASTENTRY\z)/) {
    125         $ignored++;
    126         next;
    127     }
    128     if($doc{$e}) {
    129         if($verbose) {
    130             print $e."\n";
    131         }
    132         $doc{$e}="used";
    133         next;
    134     }
    135     else {
    136         print $e."\n";
    137         $misses++;
    138     }
    139 }
    140 
    141 #
    142 # now scan through all symbols that were present in the symbols-in-versions
    143 # but not in the headers
    144 #
    145 # If the symbols were marked 'removed' in symbols-in-versions we don't output
    146 # anything about it since that is perfectly fine.
    147 #
    148 
    149 my $anyremoved;
    150 
    151 for my $e (sort keys %doc) {
    152     if(($doc{$e} ne "used") && !$rem{$e}) {
    153 
    154         if(!$anyremoved++) {
    155             print "Missing symbols mentioned in symbols-in-versions\n";
    156             print "Add them to a header, or mark them as removed.\n";
    157         }
    158 
    159         print "$e\n";
    160         $misses++;
    161     }
    162 }
    163 
    164 if($summary) {
    165     print "Summary:\n";
    166     printf "%d symbols in headers (out of which %d are ignored)\n", scalar(@syms),
    167     $ignored;
    168     printf "%d symbols in headers are interesting\n",
    169     scalar(@syms)- $ignored;
    170     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);
    171     printf "%d symbols in symbols-in-versions should match the ones in headers\n", scalar(keys %doc) - scalar(keys %rem);
    172 }
    173 
    174 if($misses) {
    175     exit 2; # there are stuff to attend to!
    176 }
    177