xref: /aosp_15_r20/external/curl/tests/test1119.pl (revision 6236dae45794135f37c4eb022389c904c8b0090d)
1*6236dae4SAndroid Build Coastguard Worker#!/usr/bin/env perl
2*6236dae4SAndroid Build Coastguard Worker#***************************************************************************
3*6236dae4SAndroid Build Coastguard Worker#                                  _   _ ____  _
4*6236dae4SAndroid Build Coastguard Worker#  Project                     ___| | | |  _ \| |
5*6236dae4SAndroid Build Coastguard Worker#                             / __| | | | |_) | |
6*6236dae4SAndroid Build Coastguard Worker#                            | (__| |_| |  _ <| |___
7*6236dae4SAndroid Build Coastguard Worker#                             \___|\___/|_| \_\_____|
8*6236dae4SAndroid Build Coastguard Worker#
9*6236dae4SAndroid Build Coastguard Worker# Copyright (C) Daniel Stenberg, <[email protected]>, et al.
10*6236dae4SAndroid Build Coastguard Worker#
11*6236dae4SAndroid Build Coastguard Worker# This software is licensed as described in the file COPYING, which
12*6236dae4SAndroid Build Coastguard Worker# you should have received as part of this distribution. The terms
13*6236dae4SAndroid Build Coastguard Worker# are also available at https://curl.se/docs/copyright.html.
14*6236dae4SAndroid Build Coastguard Worker#
15*6236dae4SAndroid Build Coastguard Worker# You may opt to use, copy, modify, merge, publish, distribute and/or sell
16*6236dae4SAndroid Build Coastguard Worker# copies of the Software, and permit persons to whom the Software is
17*6236dae4SAndroid Build Coastguard Worker# furnished to do so, under the terms of the COPYING file.
18*6236dae4SAndroid Build Coastguard Worker#
19*6236dae4SAndroid Build Coastguard Worker# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20*6236dae4SAndroid Build Coastguard Worker# KIND, either express or implied.
21*6236dae4SAndroid Build Coastguard Worker#
22*6236dae4SAndroid Build Coastguard Worker# SPDX-License-Identifier: curl
23*6236dae4SAndroid Build Coastguard Worker#
24*6236dae4SAndroid Build Coastguard Worker###########################################################################
25*6236dae4SAndroid Build Coastguard Worker#
26*6236dae4SAndroid Build Coastguard Worker# This script grew out of help from Przemyslaw Iskra and Balint Szilakszi
27*6236dae4SAndroid Build Coastguard Worker# a late evening in the #curl IRC channel.
28*6236dae4SAndroid Build Coastguard Worker#
29*6236dae4SAndroid Build Coastguard Worker
30*6236dae4SAndroid Build Coastguard Workeruse strict;
31*6236dae4SAndroid Build Coastguard Workeruse warnings;
32*6236dae4SAndroid Build Coastguard Workeruse vars qw($Cpreprocessor);
33*6236dae4SAndroid Build Coastguard Worker
34*6236dae4SAndroid Build Coastguard Worker#
35*6236dae4SAndroid Build Coastguard Worker# configurehelp perl module is generated by configure script
36*6236dae4SAndroid Build Coastguard Worker#
37*6236dae4SAndroid Build Coastguard Workermy $rc = eval {
38*6236dae4SAndroid Build Coastguard Worker    require configurehelp;
39*6236dae4SAndroid Build Coastguard Worker    configurehelp->import(qw(
40*6236dae4SAndroid Build Coastguard Worker        $Cpreprocessor
41*6236dae4SAndroid Build Coastguard Worker    ));
42*6236dae4SAndroid Build Coastguard Worker    1;
43*6236dae4SAndroid Build Coastguard Worker};
44*6236dae4SAndroid Build Coastguard Worker# Set default values if configure has not generated a configurehelp.pm file.
45*6236dae4SAndroid Build Coastguard Worker# This is the case with cmake.
46*6236dae4SAndroid Build Coastguard Workerif (!$rc) {
47*6236dae4SAndroid Build Coastguard Worker    $Cpreprocessor = 'cpp';
48*6236dae4SAndroid Build Coastguard Worker}
49*6236dae4SAndroid Build Coastguard Worker
50*6236dae4SAndroid Build Coastguard Worker# we may get the dir root pointed out
51*6236dae4SAndroid Build Coastguard Workermy $root=$ARGV[0] || ".";
52*6236dae4SAndroid Build Coastguard Worker
53*6236dae4SAndroid Build Coastguard Worker# need an include directory when building out-of-tree
54*6236dae4SAndroid Build Coastguard Workermy $i = ($ARGV[1]) ? "-I$ARGV[1] " : '';
55*6236dae4SAndroid Build Coastguard Worker
56*6236dae4SAndroid Build Coastguard Workermy $verbose=0;
57*6236dae4SAndroid Build Coastguard Workermy $summary=0;
58*6236dae4SAndroid Build Coastguard Workermy $misses=0;
59*6236dae4SAndroid Build Coastguard Worker
60*6236dae4SAndroid Build Coastguard Workermy @manrefs;
61*6236dae4SAndroid Build Coastguard Workermy @syms;
62*6236dae4SAndroid Build Coastguard Workermy %doc;
63*6236dae4SAndroid Build Coastguard Workermy %rem;
64*6236dae4SAndroid Build Coastguard Worker
65*6236dae4SAndroid Build Coastguard Worker# scanenum runs the preprocessor on curl.h so it will process all enums
66*6236dae4SAndroid Build Coastguard Worker# included by it, which *should* be all headers
67*6236dae4SAndroid Build Coastguard Workersub scanenum {
68*6236dae4SAndroid Build Coastguard Worker    my ($file) = @_;
69*6236dae4SAndroid Build Coastguard Worker    open my $h_in, "-|", "$Cpreprocessor $i$file" || die "Cannot preprocess $file";
70*6236dae4SAndroid Build Coastguard Worker    while ( <$h_in> ) {
71*6236dae4SAndroid Build Coastguard Worker        if ( /enum\s+(\S+\s+)?{/ .. /}/ ) {
72*6236dae4SAndroid Build Coastguard Worker            s/^\s+//;
73*6236dae4SAndroid Build Coastguard Worker            next unless /^CURL/;
74*6236dae4SAndroid Build Coastguard Worker            chomp;
75*6236dae4SAndroid Build Coastguard Worker            s/[,\s].*//;
76*6236dae4SAndroid Build Coastguard Worker            push @syms, $_;
77*6236dae4SAndroid Build Coastguard Worker        }
78*6236dae4SAndroid Build Coastguard Worker    }
79*6236dae4SAndroid Build Coastguard Worker    close $h_in || die "Error preprocessing $file";
80*6236dae4SAndroid Build Coastguard Worker}
81*6236dae4SAndroid Build Coastguard Worker
82*6236dae4SAndroid Build Coastguard Workersub scanheader {
83*6236dae4SAndroid Build Coastguard Worker    my ($f)=@_;
84*6236dae4SAndroid Build Coastguard Worker    open my $h, "<", "$f";
85*6236dae4SAndroid Build Coastguard Worker    while(<$h>) {
86*6236dae4SAndroid Build Coastguard Worker        if (/^#define ((LIB|)CURL[A-Za-z0-9_]*)/) {
87*6236dae4SAndroid Build Coastguard Worker            push @syms, $1;
88*6236dae4SAndroid Build Coastguard Worker        }
89*6236dae4SAndroid Build Coastguard Worker    }
90*6236dae4SAndroid Build Coastguard Worker    close $h;
91*6236dae4SAndroid Build Coastguard Worker}
92*6236dae4SAndroid Build Coastguard Worker
93*6236dae4SAndroid Build Coastguard Workersub scanallheaders {
94*6236dae4SAndroid Build Coastguard Worker    my $d = "$root/include/curl";
95*6236dae4SAndroid Build Coastguard Worker    opendir(my $dh, $d) ||
96*6236dae4SAndroid Build Coastguard Worker        die "Can't opendir: $!";
97*6236dae4SAndroid Build Coastguard Worker    my @headers = grep { /.h\z/ } readdir($dh);
98*6236dae4SAndroid Build Coastguard Worker    closedir $dh;
99*6236dae4SAndroid Build Coastguard Worker    foreach my $h (@headers) {
100*6236dae4SAndroid Build Coastguard Worker        scanenum("$d/$h");
101*6236dae4SAndroid Build Coastguard Worker        scanheader("$d/$h");
102*6236dae4SAndroid Build Coastguard Worker    }
103*6236dae4SAndroid Build Coastguard Worker}
104*6236dae4SAndroid Build Coastguard Worker
105*6236dae4SAndroid Build Coastguard Workersub checkmanpage {
106*6236dae4SAndroid Build Coastguard Worker    my ($m) = @_;
107*6236dae4SAndroid Build Coastguard Worker
108*6236dae4SAndroid Build Coastguard Worker    open(my $mh, "<", "$m");
109*6236dae4SAndroid Build Coastguard Worker    my $line = 1;
110*6236dae4SAndroid Build Coastguard Worker    while(<$mh>) {
111*6236dae4SAndroid Build Coastguard Worker        # strip off formatting
112*6236dae4SAndroid Build Coastguard Worker        $_ =~ s/(^|[^A-Z0-9])[*_]+/ /;
113*6236dae4SAndroid Build Coastguard Worker        # detect global-looking 'CURL[BLABLA]_*' symbols
114*6236dae4SAndroid Build Coastguard Worker        while(s/\W(CURL(AUTH|E|H|MOPT|OPT|SHOPT|UE|M|SSH|SSLBACKEND|HEADER|FORM|FTP|PIPE|MIMEOPT|GSSAPI|ALTSVC|PROTO|PROXY|UPART|USESSL|_READFUNC|_WRITEFUNC|_CSELECT|_FORMADD|_IPRESOLVE|_REDIR|_RTSPREQ|_TIMECOND|_VERSION)_[a-zA-Z0-9_]+)//) {
115*6236dae4SAndroid Build Coastguard Worker            my $s = $1;
116*6236dae4SAndroid Build Coastguard Worker            # skip two "special" ones
117*6236dae4SAndroid Build Coastguard Worker            if($s !~ /^(CURLE_OBSOLETE|CURLOPT_TEMPLATE)/) {
118*6236dae4SAndroid Build Coastguard Worker                push @manrefs, "$1:$m:$line";
119*6236dae4SAndroid Build Coastguard Worker            }
120*6236dae4SAndroid Build Coastguard Worker        }
121*6236dae4SAndroid Build Coastguard Worker        $line++;
122*6236dae4SAndroid Build Coastguard Worker    }
123*6236dae4SAndroid Build Coastguard Worker    close($mh);
124*6236dae4SAndroid Build Coastguard Worker}
125*6236dae4SAndroid Build Coastguard Worker
126*6236dae4SAndroid Build Coastguard Workersub scanman_md_dir {
127*6236dae4SAndroid Build Coastguard Worker    my ($d) = @_;
128*6236dae4SAndroid Build Coastguard Worker    opendir(my $dh, $d) ||
129*6236dae4SAndroid Build Coastguard Worker        die "Can't opendir: $!";
130*6236dae4SAndroid Build Coastguard Worker    my @mans = grep { /.md\z/ } readdir($dh);
131*6236dae4SAndroid Build Coastguard Worker    closedir $dh;
132*6236dae4SAndroid Build Coastguard Worker    for my $m (@mans) {
133*6236dae4SAndroid Build Coastguard Worker        checkmanpage("$d/$m");
134*6236dae4SAndroid Build Coastguard Worker    }
135*6236dae4SAndroid Build Coastguard Worker}
136*6236dae4SAndroid Build Coastguard Worker
137*6236dae4SAndroid Build Coastguard Worker
138*6236dae4SAndroid Build Coastguard Workerscanallheaders();
139*6236dae4SAndroid Build Coastguard Workerscanman_md_dir("$root/docs/libcurl");
140*6236dae4SAndroid Build Coastguard Workerscanman_md_dir("$root/docs/libcurl/opts");
141*6236dae4SAndroid Build Coastguard Worker
142*6236dae4SAndroid Build Coastguard Workeropen my $s, "<", "$root/docs/libcurl/symbols-in-versions";
143*6236dae4SAndroid Build Coastguard Workerwhile(<$s>) {
144*6236dae4SAndroid Build Coastguard Worker    if(/(^[^ \n]+) +(.*)/) {
145*6236dae4SAndroid Build Coastguard Worker        my ($sym, $rest)=($1, $2);
146*6236dae4SAndroid Build Coastguard Worker        if($doc{$sym}) {
147*6236dae4SAndroid Build Coastguard Worker            print "Detected duplicate symbol: $sym\n";
148*6236dae4SAndroid Build Coastguard Worker            $misses++;
149*6236dae4SAndroid Build Coastguard Worker            next;
150*6236dae4SAndroid Build Coastguard Worker        }
151*6236dae4SAndroid Build Coastguard Worker        $doc{$sym}=$sym;
152*6236dae4SAndroid Build Coastguard Worker        my @a=split(/ +/, $rest);
153*6236dae4SAndroid Build Coastguard Worker        if($a[2]) {
154*6236dae4SAndroid Build Coastguard Worker            # this symbol is documented to have been present the last time
155*6236dae4SAndroid Build Coastguard Worker            # in this release
156*6236dae4SAndroid Build Coastguard Worker            $rem{$sym}=$a[2];
157*6236dae4SAndroid Build Coastguard Worker        }
158*6236dae4SAndroid Build Coastguard Worker    }
159*6236dae4SAndroid Build Coastguard Worker}
160*6236dae4SAndroid Build Coastguard Workerclose $s;
161*6236dae4SAndroid Build Coastguard Worker
162*6236dae4SAndroid Build Coastguard Workermy $ignored=0;
163*6236dae4SAndroid Build Coastguard Workerfor my $e (sort @syms) {
164*6236dae4SAndroid Build Coastguard Worker    # OBSOLETE - names that are just placeholders for a position where we
165*6236dae4SAndroid Build Coastguard Worker    # previously had a name, that is now removed. The OBSOLETE names should
166*6236dae4SAndroid Build Coastguard Worker    # never be used for anything.
167*6236dae4SAndroid Build Coastguard Worker    #
168*6236dae4SAndroid Build Coastguard Worker    # CURL_EXTERN - is a define used for libcurl functions that are external,
169*6236dae4SAndroid Build Coastguard Worker    # public. No app or other code should ever use it.
170*6236dae4SAndroid Build Coastguard Worker    #
171*6236dae4SAndroid Build Coastguard Worker    # CURLINC_ - defines for header dual-include prevention, ignore those.
172*6236dae4SAndroid Build Coastguard Worker    #
173*6236dae4SAndroid Build Coastguard Worker    # CURL_TEMP_ - are defined and *undefined* again within the file
174*6236dae4SAndroid Build Coastguard Worker    #
175*6236dae4SAndroid Build Coastguard Worker    # *_LAST and *_LASTENTRY are just prefix for the placeholders used for the
176*6236dae4SAndroid Build Coastguard Worker    # last entry in many enum series.
177*6236dae4SAndroid Build Coastguard Worker    #
178*6236dae4SAndroid Build Coastguard Worker
179*6236dae4SAndroid Build Coastguard Worker    if($e =~ /(OBSOLETE|^CURL_EXTERN|^CURLINC_|_LAST\z|_LASTENTRY\z|^CURL_TEMP_)/) {
180*6236dae4SAndroid Build Coastguard Worker        $ignored++;
181*6236dae4SAndroid Build Coastguard Worker        next;
182*6236dae4SAndroid Build Coastguard Worker    }
183*6236dae4SAndroid Build Coastguard Worker    if($doc{$e}) {
184*6236dae4SAndroid Build Coastguard Worker        if($verbose) {
185*6236dae4SAndroid Build Coastguard Worker            print $e."\n";
186*6236dae4SAndroid Build Coastguard Worker        }
187*6236dae4SAndroid Build Coastguard Worker        $doc{$e}="used";
188*6236dae4SAndroid Build Coastguard Worker        next;
189*6236dae4SAndroid Build Coastguard Worker    }
190*6236dae4SAndroid Build Coastguard Worker    else {
191*6236dae4SAndroid Build Coastguard Worker        print $e."\n";
192*6236dae4SAndroid Build Coastguard Worker        $misses++;
193*6236dae4SAndroid Build Coastguard Worker    }
194*6236dae4SAndroid Build Coastguard Worker}
195*6236dae4SAndroid Build Coastguard Worker
196*6236dae4SAndroid Build Coastguard Worker#
197*6236dae4SAndroid Build Coastguard Worker# now scan through all symbols that were present in the symbols-in-versions
198*6236dae4SAndroid Build Coastguard Worker# but not in the headers
199*6236dae4SAndroid Build Coastguard Worker#
200*6236dae4SAndroid Build Coastguard Worker# If the symbols were marked 'removed' in symbols-in-versions we don't output
201*6236dae4SAndroid Build Coastguard Worker# anything about it since that is perfectly fine.
202*6236dae4SAndroid Build Coastguard Worker#
203*6236dae4SAndroid Build Coastguard Worker
204*6236dae4SAndroid Build Coastguard Workermy $anyremoved;
205*6236dae4SAndroid Build Coastguard Worker
206*6236dae4SAndroid Build Coastguard Workerfor my $e (sort keys %doc) {
207*6236dae4SAndroid Build Coastguard Worker    if(($doc{$e} ne "used") && !$rem{$e}) {
208*6236dae4SAndroid Build Coastguard Worker
209*6236dae4SAndroid Build Coastguard Worker        if(!$anyremoved++) {
210*6236dae4SAndroid Build Coastguard Worker            print "Missing symbols mentioned in symbols-in-versions\n";
211*6236dae4SAndroid Build Coastguard Worker            print "Add them to a header, or mark them as removed.\n";
212*6236dae4SAndroid Build Coastguard Worker        }
213*6236dae4SAndroid Build Coastguard Worker
214*6236dae4SAndroid Build Coastguard Worker        print "$e\n";
215*6236dae4SAndroid Build Coastguard Worker        $misses++;
216*6236dae4SAndroid Build Coastguard Worker    }
217*6236dae4SAndroid Build Coastguard Worker}
218*6236dae4SAndroid Build Coastguard Worker
219*6236dae4SAndroid Build Coastguard Workermy %warned;
220*6236dae4SAndroid Build Coastguard Workerfor my $r (@manrefs) {
221*6236dae4SAndroid Build Coastguard Worker    if($r =~ /^([^:]+):(.*)/) {
222*6236dae4SAndroid Build Coastguard Worker        my ($sym, $file)=($1, $2);
223*6236dae4SAndroid Build Coastguard Worker        if(!$doc{$sym} && !$warned{$sym, $file}) {
224*6236dae4SAndroid Build Coastguard Worker            print "$file: $sym is not a public symbol\n";
225*6236dae4SAndroid Build Coastguard Worker            $warned{$sym, $file} = 1;
226*6236dae4SAndroid Build Coastguard Worker        }
227*6236dae4SAndroid Build Coastguard Worker    }
228*6236dae4SAndroid Build Coastguard Worker}
229*6236dae4SAndroid Build Coastguard Worker
230*6236dae4SAndroid Build Coastguard Workerif($summary) {
231*6236dae4SAndroid Build Coastguard Worker    print "Summary:\n";
232*6236dae4SAndroid Build Coastguard Worker    printf "%d symbols in headers (out of which %d are ignored)\n", scalar(@syms),
233*6236dae4SAndroid Build Coastguard Worker    $ignored;
234*6236dae4SAndroid Build Coastguard Worker    printf "%d symbols in headers are interesting\n",
235*6236dae4SAndroid Build Coastguard Worker    scalar(@syms)- $ignored;
236*6236dae4SAndroid Build Coastguard Worker    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);
237*6236dae4SAndroid Build Coastguard Worker    printf "%d symbols in symbols-in-versions should match the ones in headers\n", scalar(keys %doc) - scalar(keys %rem);
238*6236dae4SAndroid Build Coastguard Worker}
239*6236dae4SAndroid Build Coastguard Worker
240*6236dae4SAndroid Build Coastguard Workerif($misses) {
241*6236dae4SAndroid Build Coastguard Worker    exit 0; # there are stuff to attend to!
242*6236dae4SAndroid Build Coastguard Worker}
243*6236dae4SAndroid Build Coastguard Workerelse {
244*6236dae4SAndroid Build Coastguard Worker    print "OK\n";
245*6236dae4SAndroid Build Coastguard Worker}
246