summaryrefslogtreecommitdiff
path: root/packaging/var-checker
blob: b63428b741b769f9b2939190118b5867e4b073ca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/perl -w
# This script checks the *.c files for extraneous "extern" variables,
# for vars that are defined but not used, and for inconsistent array
# sizes.  Run it from inside the main rsync directory.

use strict;

my %add_syscall_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c tls.c trimslash.c );
my %add_util_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c );
my %sizes;

open(IN, '<', 'syscall.c') or die $!;
undef $/; my $syscall_c = <IN>; $/ = "\n";
close IN;
$syscall_c =~ s/^extern\s.*//mg;

open(IN, '<', 'util.c') or die $!;
undef $/; my $util_c = <IN>; $/ = "\n";
close IN;
$util_c =~ s/^extern\s.*//mg;

my @files = glob('*.c');

foreach my $fn (@files) {
    open(IN, '<', $fn) or die $!;
    undef $/; $_ = <IN>; $/ = "\n";
    close IN;

    my @vars = /^(?!(?:extern|enum)\s)([a-zA-Z]\S*\s+.*);/mg;
    my @externs = /^extern\s+(.*);/mg;

    $_ .= $syscall_c if $add_syscall_c{$fn};
    $_ .= $util_c if $add_util_c{$fn};
    s/INFO_GTE/info_levels/g;
    s/DEBUG_GTE/debug_levels/g;

    check_vars($fn, 'var', @vars);
    check_vars($fn, 'extern', @externs);
}

exit;

# The file's contents are in $_.
sub check_vars
{
    my $fn = shift;
    my $type = shift;

    foreach my $line (@_) {
	$line =~ s/\s*\{.*\}//;
	$line =~ s/\s*\(.*\)//;
	foreach my $item (split(/\s*,\s*/, $line)) {
	    $item =~ s/\s*=.*//;
	    my $sz = $item =~ s/(\[.*?\])// ? $1 : '';
	    my($var) = $item =~ /([^*\s]+)$/;
	    if (!defined $var) {
		print "Bogus match? ($item)\n";
		next;
	    }
	    if ($sz) {
		if (defined $sizes{$var}) {
		    if ($sizes{$var} ne $sz) {
			print $fn, ' has inconsistent size for "', $var,
			    "\": $sizes{$var} vs $sz\n";
		    }
		} else {
		    $sizes{$var} = $sz;
		}
	    }
	    my @matches = /(?<!\sstruct )\b(\Q$var\E)(?!\w)/g;
	    push(@matches, /(\QSIGACTION(\E)/g) if $var eq 'sigact';
	    print $fn, " has extraneous $type: \"", $var, "\"\n" if @matches == 1;
	}
    }
}