blob: 392b190f8f7d54a7da0b3a7f9ae9413999fd389c [file] [log] [blame]
xf.li6c8fc1e2023-08-12 00:11:09 -07001#!/usr/bin/env perl
2#***************************************************************************
3# _ _ ____ _
4# Project ___| | | | _ \| |
5# / __| | | | |_) | |
6# | (__| |_| | _ <| |___
7# \___|\___/|_| \_\_____|
8#
9# Copyright (C) 2010-2022, 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 https://curl.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# SPDX-License-Identifier: curl
23#
24###########################################################################
25#
26# This script grew out of help from Przemyslaw Iskra and Balint Szilakszi
27# a late evening in the #curl IRC channel.
28#
29
30use strict;
31use warnings;
32use vars qw($Cpreprocessor);
33
34#
35# configurehelp perl module is generated by configure script
36#
37my $rc = eval {
38 require configurehelp;
39 configurehelp->import(qw(
40 $Cpreprocessor
41 ));
42 1;
43};
44# Set default values if configure has not generated a configurehelp.pm file.
45# This is the case with cmake.
46if (!$rc) {
47 $Cpreprocessor = 'cpp';
48}
49
50my $verbose=0;
51
52# verbose mode when -v is the first argument
53if($ARGV[0] eq "-v") {
54 $verbose=1;
55 shift;
56}
57
58# we may get the dir root pointed out
59my $root=$ARGV[0] || ".";
60
61# need an include directory when building out-of-tree
62my $i = ($ARGV[1]) ? "-I$ARGV[1] " : '';
63
64my $incdir = "$root/include/curl";
65
66my $summary=0;
67my $misses=0;
68
69my @syms;
70my %doc;
71my %rem;
72
73sub scanenums {
74 my ($file)=@_;
75 my $skipit = 0;
76
77 open H_IN, "-|", "$Cpreprocessor $i$file" || die "Cannot preprocess $file";
78 while ( <H_IN> ) {
79 my ($line, $linenum) = ($_, $.);
80 if( /^#(line|) (\d+) \"(.*)\"/) {
81 # if the included file isn't in our incdir, then we skip this section
82 # until next #line
83 #
84 if($3 !~ /^$incdir/) {
85 $skipit = 1;
86 next;
87 }
88 # parse this!
89 $skipit = 0;
90 next;
91 }
92 if($skipit) {
93 next;
94 }
95 if (/^#/) {
96 next;
97 }
98 if ( /enum\s+(\S+\s+)?{/ .. /}/ ) {
99 s/^\s+//;
100 chomp;
101 s/[,\s].*//;
102 if(($_ !~ /\}(;|)/) &&
103 ($_ ne "typedef") &&
104 ($_ ne "enum") &&
105 ($_ !~ /^[ \t]*$/)) {
106 if($verbose) {
107 print "Source: $Cpreprocessor $i$file\n";
108 print "Symbol: $_\n";
109 print "Line #$linenum: $line\n\n";
110 }
111 push @syms, $_;
112 }
113 }
114 }
115 close H_IN || die "Error preprocessing $file";
116}
117
118sub scanheader {
119 my ($f)=@_;
120 scanenums($f);
121 open H, "<$f";
122 while(<H>) {
123 my ($line, $linenum) = ($_, $.);
124 if (/^#define +([^ \n]*)/) {
125 if($verbose) {
126 print "Source: $f\n";
127 print "Symbol: $1\n";
128 print "Line #$linenum: $line\n\n";
129 }
130 push @syms, $1;
131 }
132 }
133 close H;
134}
135
136
137opendir(my $dh, $incdir) || die "Can't opendir $incdir: $!";
138my @hfiles = grep { /\.h$/ } readdir($dh);
139closedir $dh;
140
141for(@hfiles) {
142 scanheader("$incdir/$_");
143}
144
145my $errors = 0;
146for my $s (@syms) {
147 if($s !~ /^(lib|)curl/i) {
148 print "Bad symbols in public header files:\n" if(!$errors);
149 $errors++;
150 print " $s\n";
151 }
152}
153if($errors) {
154 exit 1;
155}
156printf "%d fine symbols found\n", scalar(@syms);