File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / rsync / packaging / var-checker
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 00:32:36 2021 UTC (3 years, 3 months ago) by misho
Branches: rsync, MAIN
CVS tags: v3_2_3, HEAD
rsync 3.2.3

    1: #!/usr/bin/env -S python3 -B
    2: 
    3: # This script checks the *.c files for extraneous "extern" variables,
    4: # for vars that are defined but not used, and for inconsistent array
    5: # sizes.  Run it from inside the main rsync directory.
    6: 
    7: import re, argparse, glob
    8: 
    9: VARS_RE = re.compile(r'^(?!(?:extern|enum)\s)([a-zA-Z]\S*\s+.*);', re.M)
   10: EXTERNS_RE = re.compile(r'^extern\s+(.*);', re.M)
   11: 
   12: sizes = { }
   13: 
   14: def main():
   15:     add_syscall_c = set('t_stub.c t_unsafe.c tls.c trimslash.c'.split())
   16:     add_util_c = set('t_stub.c t_unsafe.c'.split())
   17: 
   18:     syscall_c = slurp_file('syscall.c', True)
   19:     util_c = slurp_file('util.c', True)
   20: 
   21:     for fn in sorted(glob.glob('*.c')):
   22:         txt = slurp_file(fn)
   23: 
   24:         var_list = parse_vars(fn, VARS_RE.findall(txt))
   25:         extern_list = parse_vars(fn, EXTERNS_RE.findall(txt))
   26:         if not var_list and not extern_list:
   27:             continue
   28: 
   29:         if fn in add_syscall_c:
   30:             txt += syscall_c
   31:         if fn in add_util_c:
   32:             txt += util_c
   33: 
   34:         txt = re.sub(r'INFO_GTE', 'info_levels ', txt)
   35:         txt = re.sub(r'DEBUG_GTE', 'debug_levels ', txt)
   36:         txt = re.sub(r'SIGACTION\(', 'sigact (', txt)
   37: 
   38:         find = '|'.join([ re.escape(x) for x in var_list + extern_list ])
   39:         var_re = re.compile(r'(?<!\sstruct )\b(%s)(?!\w)' % find)
   40: 
   41:         found = { x: 0 for x in var_list + extern_list }
   42:         for var in var_re.findall(txt):
   43:             found[var] += 1
   44: 
   45:         for var in sorted(var_list + extern_list):
   46:             if found[var] == 1:
   47:                 vtype = 'var' if var in var_list else 'extern'
   48:                 print(fn, f'has extraneous {vtype}: "{var}"')
   49: 
   50: 
   51: def slurp_file(fn, drop_externs=False):
   52:     with open(fn, 'r', encoding='utf-8') as fh:
   53:         txt = fh.read()
   54:     if drop_externs:
   55:         txt = EXTERNS_RE.sub('', txt)
   56:     return txt
   57: 
   58: 
   59: def parse_vars(fn, lines):
   60:     ret = [ ]
   61:     for line in lines:
   62:         line = re.sub(r'\s*\{.*\}', '', line)
   63:         line = re.sub(r'\s*\(.*\)', '', line)
   64:         for item in re.split(r'\s*,\s*', line):
   65:             item = re.sub(r'\s*=.*', '', item)
   66:             m = re.search(r'(?P<var>\w+)(?P<sz>\[.*?\])?$', item)
   67:             if not m:
   68:                 print(f"Bogus match? ({item})")
   69:                 continue
   70:             if m['sz']:
   71:                 if m['var'] in sizes:
   72:                     if sizes[m['var']] != m['sz']:
   73:                         var = m['var']
   74:                         print(fn, f'has inconsistent size for "{var}":', m['sz'], 'vs', sizes[var])
   75:                 else:
   76:                     sizes[m['var']] = m['sz']
   77:             ret.append(m['var'])
   78:     return ret
   79: 
   80: 
   81: if __name__ == '__main__':
   82:     parser = argparse.ArgumentParser(description='Check the *.c files for extraneous extern vars.', add_help=False)
   83:     parser.add_argument("--help", "-h", action="help", help="Output this help message and exit.")
   84:     args = parser.parse_args()
   85:     main()
   86: 
   87: # vim: sw=4 et ft=python

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