#!/usr/bin/env perl #*************************************************************************** # _ _ ____ _ # Project ___| | | | _ \| | # / __| | | | |_) | | # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # # Copyright (C) Daniel Stenberg, , 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 # ########################################################################### # use strict; use warnings; # the DISABLE options that can be set by configure my %disable; # the DISABLE options that can be set by CMakeLists.txt my %disable_cmake; # the DISABLE options that are used in C files my %file; # the DISABLE options that are documented my %docs; # we may get the dir root pointed out my $root=$ARGV[0] || "."; my $DOCS="CURL-DISABLE.md"; sub scanconf { my ($f)=@_; open S, "<$f"; while() { if(/(CURL_DISABLE_[A-Z0-9_]+)/g) { my ($sym)=($1); $disable{$sym} = 1; } } close S; } sub scan_configure { opendir(my $m, "$root/m4") || die "Can't opendir $root/m4: $!"; my @m4 = grep { /\.m4$/ } readdir($m); closedir $m; scanconf("$root/configure.ac"); # scan all m4 files too for my $e (@m4) { scanconf("$root/m4/$e"); } } sub scanconf_cmake { my ($f)=@_; open S, "<$f"; while() { if(/(CURL_DISABLE_[A-Z0-9_]+)/g) { my ($sym)=($1); if(not $sym =~ /^(CURL_DISABLE_INSTALL|CURL_DISABLE_TESTS|CURL_DISABLE_SRP)$/) { $disable_cmake{$sym} = 1; } } } close S; } sub scan_cmake { scanconf_cmake("$root/CMakeLists.txt"); } sub scan_file { my ($source)=@_; open F, "<$source"; while() { while(s/(CURL_DISABLE_[A-Z0-9_]+)//) { my ($sym)=($1); if(not $sym =~ /^(CURL_DISABLE_SHA512_256)/) { # Skip this symbol, to be implemented $file{$sym} = $source; } } } close F; } sub scan_dir { my ($dir)=@_; opendir(my $dh, $dir) || die "Can't opendir $dir: $!"; my @cfiles = grep { /\.[ch]\z/ && -f "$dir/$_" } readdir($dh); closedir $dh; for my $f (sort @cfiles) { scan_file("$dir/$f"); } } sub scan_sources { scan_dir("$root/src"); scan_dir("$root/lib"); scan_dir("$root/lib/vtls"); scan_dir("$root/lib/vauth"); } sub scan_docs { open F, "<$root/docs/$DOCS"; my $line = 0; while() { $line++; if(/^## `(CURL_DISABLE_[A-Z0-9_]+)`/g) { my ($sym)=($1); $docs{$sym} = $line; } } close F; } scan_configure(); scan_cmake(); scan_sources(); scan_docs(); my $error = 0; # Check the configure symbols for use in code for my $s (sort keys %disable) { if(!$file{$s}) { printf "Present in configure.ac, not used by code: %s\n", $s; $error++; } if(!$docs{$s}) { printf "Present in configure.ac, not documented in $DOCS: %s\n", $s; $error++; } } # Check the CMakeLists.txt symbols for use in code for my $s (sort keys %disable_cmake) { if(!$file{$s}) { printf "Present in CMakeLists.txt, not used by code: %s\n", $s; $error++; } if(!$docs{$s}) { printf "Present in CMakeLists.txt, not documented in $DOCS: %s\n", $s; $error++; } } # Check the code symbols for use in configure for my $s (sort keys %file) { if(!$disable{$s}) { printf "Not set by configure: %s (%s)\n", $s, $file{$s}; $error++; } if(!$disable_cmake{$s}) { printf "Not set by CMakeLists.txt: %s (%s)\n", $s, $file{$s}; $error++; } if(!$docs{$s}) { printf "Used in code, not documented in $DOCS: %s\n", $s; $error++; } } # Check the documented symbols for my $s (sort keys %docs) { if(!$disable{$s}) { printf "Documented but not in configure: %s\n", $s; $error++; } if(!$disable_cmake{$s}) { printf "Documented but not in CMakeLists.txt: %s\n", $s; $error++; } if(!$file{$s}) { printf "Documented, but not used by code: %s\n", $s; $error++; } } exit $error;