• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env perl
2#***************************************************************************
3#                                  _   _ ____  _
4#  Project                     ___| | | |  _ \| |
5#                             / __| | | | |_) | |
6#                            | (__| |_| |  _ <| |___
7#                             \___|\___/|_| \_\_____|
8#
9# Copyright (C) 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 -DCURL_DISABLE_DEPRECATION $i$file" ||
78        die "Cannot preprocess $file";
79    while ( <H_IN> ) {
80        my ($line, $linenum) = ($_, $.);
81        if( /^#(line|) (\d+) \"(.*)\"/) {
82            # if the included file isn't in our incdir, then we skip this section
83            # until next #line
84            #
85            if($3 !~ /^$incdir/) {
86                $skipit = 1;
87                next;
88            }
89            # parse this!
90            $skipit = 0;
91            next;
92        }
93        if($skipit) {
94            next;
95        }
96        if (/^#/) {
97            next;
98        }
99        if ( /enum\s+(\S+\s+)?{/ .. /}/ ) {
100            s/^\s+//;
101            chomp;
102            s/[,\s].*//;
103            if(($_ !~ /\}(;|)/) &&
104               ($_ ne "typedef") &&
105               ($_ ne "enum") &&
106               ($_ ne "=") &&
107               ($_ !~ /^[ \t]*$/)) {
108                if($verbose) {
109                    print "Source: $Cpreprocessor $i$file\n";
110                    print "Symbol: $_\n";
111                    print "Line #$linenum: $line\n\n";
112                }
113                push @syms, $_;
114            }
115        }
116    }
117    close H_IN || die "Error preprocessing $file";
118}
119
120sub scanheader {
121    my ($f)=@_;
122    scanenums($f);
123    open H, "<$f";
124    while(<H>) {
125        my ($line, $linenum) = ($_, $.);
126        if (/^#define +([^ \n]*)/) {
127            if($verbose) {
128                print "Source: $f\n";
129                print "Symbol: $1\n";
130                print "Line #$linenum: $line\n\n";
131            }
132            push @syms, $1;
133        }
134    }
135    close H;
136}
137
138
139opendir(my $dh, $incdir) || die "Can't opendir $incdir: $!";
140my @hfiles = grep { /\.h$/ } readdir($dh);
141closedir $dh;
142
143for(@hfiles) {
144    scanheader("$incdir/$_");
145}
146
147my $errors = 0;
148for my $s (@syms) {
149    if($s !~ /^(lib|)curl/i) {
150        print "Bad symbols in public header files:\n" if(!$errors);
151        $errors++;
152        print "  $s\n";
153    }
154}
155if($errors) {
156    exit 1;
157}
158printf "%d fine symbols found\n", scalar(@syms);
159