mirror of
https://github.com/curl/curl.git
synced 2024-12-15 06:40:09 +08:00
c386065878
It is hard to name the scripts sensibly. Lots of them are similarly named and the name did not tell which test that used them. The new approach is rather to name them based on the test number that runs them. Also helps us see which scripts are for individual tests rather than for general test infra. - badsymbols.pl -> test1167.pl - check-deprecated.pl -> test1222.pl - check-translatable-options.pl -> test1544.pl - disable-scan.pl -> test1165.pl - error-codes.pl -> test1175.pl - errorcodes.pl -> test1477.pl - extern-scan.pl -> test1135.pl - manpage-scan.pl -> test1139.pl - manpage-syntax.pl -> test1173.pl - markdown-uppercase.pl -> test1275.pl - mem-include-scan.pl -> test1132.pl - nroff-scan.pl -> test1140.pl - option-check.pl -> test1276.pl - options-scan.pl -> test971.pl - symbol-scan.pl -> test1119.pl - version-scan.pl -> test1177.pl Closes #12487
330 lines
9.3 KiB
Perl
Executable File
330 lines
9.3 KiB
Perl
Executable File
#!/usr/bin/env perl
|
|
#***************************************************************************
|
|
# _ _ ____ _
|
|
# Project ___| | | | _ \| |
|
|
# / __| | | | |_) | |
|
|
# | (__| |_| | _ <| |___
|
|
# \___|\___/|_| \_\_____|
|
|
#
|
|
# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
|
|
#
|
|
# This software is licensed as described in the file COPYING, which
|
|
# you should have received as part of this distribution. The terms
|
|
# are also available at https://curl.se/docs/copyright.html.
|
|
#
|
|
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
|
# copies of the Software, and permit persons to whom the Software is
|
|
# furnished to do so, under the terms of the COPYING file.
|
|
#
|
|
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
# KIND, either express or implied.
|
|
#
|
|
# SPDX-License-Identifier: curl
|
|
#
|
|
#
|
|
###########################################################################
|
|
#
|
|
# Check that the deprecated statuses of functions and enum values in header
|
|
# files, man pages and symbols-in-versions are in sync.
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use File::Basename;
|
|
|
|
my $root=$ARGV[0] || ".";
|
|
my $incdir = "$root/include/curl";
|
|
my $docdir = "$root/docs";
|
|
my $libdocdir = "$docdir/libcurl";
|
|
my $errcode = 0;
|
|
|
|
# Symbol-indexed hashes.
|
|
# Values are:
|
|
# X Not deprecated
|
|
# ? Deprecated in unknown version
|
|
# x.yy.z Deprecated in version x.yy.z
|
|
my %syminver; # Symbols-in-versions deprecations.
|
|
my %hdr; # Public header files deprecations.
|
|
my %funcman; # Function man pages deprecations.
|
|
my %optman; # Option man pages deprecations.
|
|
|
|
|
|
# Scan header file for public function and enum values. Flag them with
|
|
# the version they are deprecated in, if some.
|
|
sub scan_header {
|
|
my ($f)=@_;
|
|
my $line = "";
|
|
my $incomment = 0;
|
|
my $inenum = 0;
|
|
|
|
open(my $h, "<", "$f");
|
|
while(<$h>) {
|
|
s/^\s*(.*?)\s*$/$1/; # Trim.
|
|
# Remove multi-line comment trail.
|
|
if($incomment) {
|
|
if($_ !~ /.*?\*\/\s*(.*)$/) {
|
|
next;
|
|
}
|
|
$_ = $1;
|
|
$incomment = 0;
|
|
}
|
|
if($line ne "") {
|
|
# Unfold line.
|
|
$_ = "$line $1";
|
|
$line = "";
|
|
}
|
|
# Remove comments.
|
|
while($_ =~ /^(.*?)\/\*.*?\*\/(.*)$/) {
|
|
$_ = "$1 $2";
|
|
}
|
|
if($_ =~ /^(.*)\/\*/) {
|
|
$_ = "$1 ";
|
|
$incomment = 1;
|
|
}
|
|
s/^\s*(.*?)\s*$/$1/; # Trim again.
|
|
# Ignore preprocessor directives and blank lines.
|
|
if($_ =~ /^(?:#|$)/) {
|
|
next;
|
|
}
|
|
# Handle lines that may be continued as if they were folded.
|
|
if($_ !~ /[;,{}]$/) {
|
|
# Folded line.
|
|
$line = $_;
|
|
next;
|
|
}
|
|
if($_ =~ /CURLOPTDEPRECATED\(/) {
|
|
# Handle deprecated CURLOPT_* option.
|
|
if($_ !~ /CURLOPTDEPRECATED\(\s*(\S+)\s*,(?:.*?,){2}\s*(.*?)\s*,.*"\)/) {
|
|
# Folded line.
|
|
$line = $_;
|
|
next;
|
|
}
|
|
$hdr{$1} = $2;
|
|
}
|
|
elsif($_ =~ /CURLOPT\(/) {
|
|
# Handle non-deprecated CURLOPT_* option.
|
|
if($_ !~ /CURLOPT\(\s*(\S+)\s*(?:,.*?){2}\)/) {
|
|
# Folded line.
|
|
$line = $_;
|
|
next;
|
|
}
|
|
$hdr{$1} = "X";
|
|
}
|
|
else {
|
|
my $version = "X";
|
|
|
|
# Get other kind of deprecation from this line.
|
|
if($_ =~ /CURL_DEPRECATED\(/) {
|
|
if($_ !~ /^(.*)CURL_DEPRECATED\(\s*(\S+?)\s*,.*?"\)(.*)$/) {
|
|
# Folded line.
|
|
$line = $_;
|
|
next;
|
|
}
|
|
$version = $2;
|
|
$_ = "$1 $3";
|
|
}
|
|
if($_ =~ /^CURL_EXTERN\s+.*\s+(\S+?)\s*\(/) {
|
|
# Flag public function.
|
|
$hdr{$1} = $version;
|
|
}
|
|
elsif($inenum && $_ =~ /(\w+)\s*[,=}]/) {
|
|
# Flag enum value.
|
|
$hdr{$1} = $version;
|
|
}
|
|
}
|
|
# Remember if we are in an enum definition.
|
|
$inenum |= ($_ =~ /\benum\b/);
|
|
if($_ =~ /}/) {
|
|
$inenum = 0;
|
|
}
|
|
}
|
|
close $h;
|
|
}
|
|
|
|
# Scan function man page for options.
|
|
# Each option has to be declared as ".IP <option>" where <option> starts with
|
|
# the prefix. Flag each option with its deprecation version, if some.
|
|
sub scan_man_for_opts {
|
|
my ($f, $prefix)=@_;
|
|
my $opt = "";
|
|
my $line = "";
|
|
|
|
open(my $m, "<", "$f");
|
|
while(<$m>) {
|
|
if($_ =~ /^\./) {
|
|
# roff directive found: end current option paragraph.
|
|
my $o = $opt;
|
|
$opt = "";
|
|
if($_ =~ /^\.IP\s+((?:$prefix)_\w+)/) {
|
|
# A new option has been found.
|
|
$opt = $1;
|
|
}
|
|
$_ = $line; # Get full paragraph.
|
|
$line = "";
|
|
s/\\f.//g; # Remove font formatting.
|
|
s/\s+/ /g; # One line with single space only.
|
|
if($o) {
|
|
$funcman{$o} = "X";
|
|
# Check if paragraph is mentioning deprecation.
|
|
while($_ =~ /(?:deprecated|obsoleted?)\b\s*(?:in\b|since\b)?\s*(?:version\b|curl\b|libcurl\b)?\s*(\d[0-9.]*\d)?\b\s*(.*)$/i) {
|
|
$funcman{$o} = $1 || "?";
|
|
$_ = $2;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
# Text line: accumulate.
|
|
$line .= $_;
|
|
}
|
|
}
|
|
close $m;
|
|
}
|
|
|
|
# Scan man page for deprecation in DESCRIPTION and/or AVAILABILITY sections.
|
|
sub scan_man_page {
|
|
my ($path, $sym, $table)=@_;
|
|
my $version = "X";
|
|
|
|
if(open(my $fh, "<", "$path")) {
|
|
my $section = "";
|
|
my $line = "";
|
|
|
|
while(<$fh>) {
|
|
if($_ =~ /\.so\s+man3\/(.*\.3\b)/) {
|
|
# Handle man page inclusion.
|
|
scan_man_page(dirname($path) . "/$1", $sym, $table);
|
|
$version = exists($$table{$sym})? $$table{$sym}: $version;
|
|
}
|
|
elsif($_ =~ /^\./) {
|
|
# Line is a roff directive.
|
|
if($_ =~ /^\.SH\b\s*(\w*)/) {
|
|
# Section starts. End previous one.
|
|
my $sh = $section;
|
|
|
|
$section = $1;
|
|
$_ = $line; # Previous section text.
|
|
$line = "";
|
|
s/\\f.//g;
|
|
s/\s+/ /g;
|
|
s/\\f.//g; # Remove font formatting.
|
|
s/\s+/ /g; # One line with single space only.
|
|
if($sh =~ /DESCRIPTION|AVAILABILITY/) {
|
|
while($_ =~ /(?:deprecated|obsoleted?)\b\s*(?:in\b|since\b)?\s*(?:version\b|curl\b|libcurl\b)?\s*(\d[0-9.]*\d)?\b\s*(.*)$/i) {
|
|
# Flag deprecation status.
|
|
if($version ne "X" && $version ne "?") {
|
|
if($1 && $1 ne $version) {
|
|
print "error: $sym man page lists unmatching deprecation versions $version and $1\n";
|
|
$errcode++;
|
|
}
|
|
}
|
|
else {
|
|
$version = $1 || "?";
|
|
}
|
|
$_ = $2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
# Text line: accumulate.
|
|
$line .= $_;
|
|
}
|
|
}
|
|
close $fh;
|
|
$$table{$sym} = $version;
|
|
}
|
|
}
|
|
|
|
|
|
# Read symbols-in-versions.
|
|
open(my $fh, "<", "$libdocdir/symbols-in-versions") ||
|
|
die "$libdocdir/symbols-in-versions";
|
|
while(<$fh>) {
|
|
if($_ =~ /^((?:CURL|LIBCURL)\S+)\s+\S+\s*(\S*)\s*(\S*)$/) {
|
|
if($3 eq "") {
|
|
$syminver{$1} = "X";
|
|
if($2 ne "" && $2 ne ".") {
|
|
$syminver{$1} = $2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
close($fh);
|
|
|
|
# Get header file names,
|
|
opendir(my $dh, $incdir) || die "Can't opendir $incdir";
|
|
my @hfiles = grep { /\.h$/ } readdir($dh);
|
|
closedir $dh;
|
|
|
|
# Get functions and enum symbols from header files.
|
|
for(@hfiles) {
|
|
scan_header("$incdir/$_");
|
|
}
|
|
|
|
# Get function statuses from man pages.
|
|
foreach my $sym (keys %hdr) {
|
|
if($sym =~/^(?:curl|curlx)_\w/) {
|
|
scan_man_page("$libdocdir/$sym.3", $sym, \%funcman);
|
|
}
|
|
}
|
|
|
|
# Get options from function man pages.
|
|
scan_man_for_opts("$libdocdir/curl_easy_setopt.3", "CURLOPT");
|
|
scan_man_for_opts("$libdocdir/curl_easy_getinfo.3", "CURLINFO");
|
|
|
|
# Get deprecation status from option man pages.
|
|
foreach my $sym (keys %syminver) {
|
|
if($sym =~ /^(?:CURLOPT|CURLINFO)_\w+$/) {
|
|
scan_man_page("$libdocdir/opts/$sym.3", $sym, \%optman);
|
|
}
|
|
}
|
|
|
|
# Print results.
|
|
my %keys = (%syminver, %funcman, %optman, %hdr);
|
|
my $leader = <<HEADER
|
|
Legend:
|
|
<empty> Not listed
|
|
X Not deprecated
|
|
? Deprecated in unknown version
|
|
x.yy.z Deprecated in version x.yy.z
|
|
|
|
Symbol symbols-in func man opt man .h
|
|
-versions
|
|
HEADER
|
|
;
|
|
foreach my $sym (sort {$a cmp $b} keys %keys) {
|
|
if($sym =~ /^(?:CURLOPT|CURLINFO|curl|curlx)_\w/) {
|
|
my $s = exists($syminver{$sym})? $syminver{$sym}: " ";
|
|
my $f = exists($funcman{$sym})? $funcman{$sym}: " ";
|
|
my $o = exists($optman{$sym})? $optman{$sym}: " ";
|
|
my $h = exists($hdr{$sym})? $hdr{$sym}: " ";
|
|
my $r = " ";
|
|
|
|
# There are deprecated symbols in symbols-in-versions that are aliases
|
|
# and thus not listed anywhere else. Ignore them.
|
|
"$f$o$h" =~ /[X ]{3}/ && next;
|
|
|
|
# Check for inconsistencies between deprecations from the different sources.
|
|
foreach my $k ($s, $f, $o, $h) {
|
|
$r = $r eq " "? $k: $r;
|
|
if($k ne " " && $r ne $k) {
|
|
if($r eq "?") {
|
|
$r = $k ne "X"? $k: "!";
|
|
}
|
|
elsif($r eq "X" || $k ne "?") {
|
|
$r = "!";
|
|
}
|
|
}
|
|
}
|
|
|
|
if($r eq "!") {
|
|
print $leader;
|
|
$leader = "";
|
|
printf("%-38s %-11s %-9s %-9s %s\n", $sym, $s, $f, $o, $h);
|
|
$errcode++;
|
|
}
|
|
}
|
|
}
|
|
|
|
exit $errcode;
|