Diff for /embedaddon/rsync/packaging/var-checker between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/17 15:09:30 version 1.1.1.2, 2021/03/17 00:32:36
Line 1 Line 1
#!/usr/bin/perl#!/usr/bin/env -S python3 -B
 
 # This script checks the *.c files for extraneous "extern" variables,  # This script checks the *.c files for extraneous "extern" variables,
 # for vars that are defined but not used, and for inconsistent array  # for vars that are defined but not used, and for inconsistent array
 # sizes.  Run it from inside the main rsync directory.  # sizes.  Run it from inside the main rsync directory.
   
use strict;import re, argparse, glob
use warnings; 
   
my %add_syscall_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c tls.c trimslash.c );VARS_RE = re.compile(r'^(?!(?:extern|enum)\s)([a-zA-Z]\S*\s+.*);', re.M)
my %add_compat_c = map { $_ => 1 } qw( t_stub.c tls.c trimslash.c wildtest.c );EXTERNS_RE = re.compile(r'^extern\s+(.*);', re.M)
my %add_util_c = map { $_ => 1 } qw( t_stub.c t_unsafe.c ); 
my %sizes; 
   
open(IN, '<', 'syscall.c') or die $!;sizes = { }
undef $/; my $syscall_c = <IN>; $/ = "\n"; 
close IN; 
$syscall_c =~ s/^extern\s.*//mg; 
   
open(IN, '<', 'lib/compat.c') or die $!;def main():
undef $/; my $compat_c = <IN>; $/ = "\n";    add_syscall_c = set('t_stub.c t_unsafe.c tls.c trimslash.c'.split())
close IN;    add_util_c = set('t_stub.c t_unsafe.c'.split())
$compat_c =~ s/^extern\s.*//mg; 
   
open(IN, '<', 'util.c') or die $!;    syscall_c = slurp_file('syscall.c', True)
undef $/; my $util_c = <IN>; $/ = "\n";    util_c = slurp_file('util.c', True)
close IN; 
$util_c =~ s/^extern\s.*//mg; 
   
my @files = glob('*.c');    for fn in sorted(glob.glob('*.c')):
         txt = slurp_file(fn)
   
foreach my $fn (@files) {        var_list = parse_vars(fn, VARS_RE.findall(txt))
    open(IN, '<', $fn) or die $!;        extern_list = parse_vars(fn, EXTERNS_RE.findall(txt))
    undef $/; $_ = <IN>; $/ = "\n";        if not var_list and not extern_list:
    close IN;            continue
   
    my @vars = /^(?!(?:extern|enum)\s)([a-zA-Z]\S*\s+.*);/mg;        if fn in add_syscall_c:
    my @externs = /^extern\s+(.*);/mg;            txt += syscall_c
         if fn in add_util_c:
             txt += util_c
   
    $_ .= $syscall_c if $add_syscall_c{$fn};        txt = re.sub(r'INFO_GTE', 'info_levels ', txt)
    $_ .= $compat_c if $add_compat_c{$fn};        txt = re.sub(r'DEBUG_GTE', 'debug_levels ', txt)
    $_ .= $util_c if $add_util_c{$fn};        txt = re.sub(r'SIGACTION\(', 'sigact (', txt)
    s/INFO_GTE/info_levels/g; 
    s/DEBUG_GTE/debug_levels/g; 
   
    check_vars($fn, 'var', @vars);        find = '|'.join([ re.escape(x) for x in var_list + extern_list ])
    check_vars($fn, 'extern', @externs);        var_re = re.compile(r'(?<!\sstruct )\b(%s)(?!\w)' % find)
} 
   
exit;        found = { x: 0 for x in var_list + extern_list }
         for var in var_re.findall(txt):
             found[var] += 1
   
# The file's contents are in $_.        for var in sorted(var_list + extern_list):
sub check_vars            if found[var] == 1:
{                vtype = 'var' if var in var_list else 'extern'
    my $fn = shift;                print(fn, f'has extraneous {vtype}: "{var}"')
    my $type = shift; 
   
    foreach my $line (@_) {
        $line =~ s/\s*\{.*\}//;def slurp_file(fn, drop_externs=False):
        $line =~ s/\s*\(.*\)//;    with open(fn, 'r', encoding='utf-8') as fh:
        foreach my $item (split(/\s*,\s*/, $line)) {        txt = fh.read()
            $item =~ s/\s*=.*//;    if drop_externs:
            my $sz = $item =~ s/(\[.*?\])// ? $1 : '';        txt = EXTERNS_RE.sub('', txt)
            my($var) = $item =~ /([^*\s]+)$/;    return txt
            if (!defined $var) {
                print "Bogus match? ($item)\n";
                next;def parse_vars(fn, lines):
            }    ret = [ ]
            if ($sz) {    for line in lines:
                if (defined $sizes{$var}) {        line = re.sub(r'\s*\{.*\}', '', line)
                    if ($sizes{$var} ne $sz) {        line = re.sub(r'\s*\(.*\)', '', line)
                        print $fn, ' has inconsistent size for "', $var,        for item in re.split(r'\s*,\s*', line):
                            "\": $sizes{$var} vs $sz\n";            item = re.sub(r'\s*=.*', '', item)
                    }            m = re.search(r'(?P<var>\w+)(?P<sz>\[.*?\])?$', item)
                } else {            if not m:
                    $sizes{$var} = $sz;                print(f"Bogus match? ({item})")
                }                continue
            }            if m['sz']:
            my @matches = /(?<!\sstruct )\b(\Q$var\E)(?!\w)/g;                if m['var'] in sizes:
            push(@matches, /(\QSIGACTION(\E)/g) if $var eq 'sigact';                    if sizes[m['var']] != m['sz']:
            print $fn, " has extraneous $type: \"", $var, "\"\n" if @matches == 1;                        var = m['var']
        }                        print(fn, f'has inconsistent size for "{var}":', m['sz'], 'vs', sizes[var])
    }                else:
}                    sizes[m['var']] = m['sz']
             ret.append(m['var'])
     return ret
 
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Check the *.c files for extraneous extern vars.', add_help=False)
     parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
     args = parser.parse_args()
     main()
 
 # vim: sw=4 et ft=python

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>