Annotation of embedaddon/rsync/packaging/var-checker, revision 1.1.1.2
1.1.1.2 ! misho 1: #!/usr/bin/env -S python3 -B
! 2:
1.1 misho 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:
1.1.1.2 ! misho 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()
1.1 misho 86:
1.1.1.2 ! misho 87: # vim: sw=4 et ft=python
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>