''' PROJECT: ReactOS code linter LICENSE: MIT (https://spdx.org/licenses/MIT) PURPOSE: Verifies that there are no headers included where packing is modified COPYRIGHT: Copyright 2021 Mark Jansen ''' from pathlib import Path import re DEFAULT_SUFFIXES = [ '.cpp', '.cxx', '.cc', '.c', '.idl', '.hpp', '.h', '.inc' ] START_HEADERS = [ 'pshpack1.h', 'pshpack2.h', 'pshpack4.h', 'pshpack8.h', ] END_HEADERS = [ 'poppack.h', ] def print_error(file, line, text): print(f'{file}({line}): ERROR: {text}') def print_warning(file, line, text): print(f'{file}({line}): WARNING: {text}') def check_file(filename): cur_packing = [] with open (filename, 'rb') as input_file: for line_nr, line in enumerate(input_file): res = re.search(rb'#[\s]*include[\s]+[<"]([^[">]+)[">]', line) if res: header = res.group(1).decode('utf-8') line_nr += 1 # Line numbers start at 1 if header in START_HEADERS: if cur_packing: print_warning(filename, line_nr, f'Overrides packing from {cur_packing[-1][0]} to {header}') cur_packing.append([header, line_nr]) elif header in END_HEADERS: if cur_packing: cur_packing.pop() else: print_error(filename, line_nr, f'Unexpected "{header}"') elif cur_packing: err = f'Include "{header}" while struct packing is modified ({cur_packing[-1][0]})' print_error(filename, line_nr, err) if cur_packing: print_error(filename, cur_packing[-1][1], 'Struct packing not restored!') def check_packing(path, include_suffixes): global EXCLUDE_SUFFIXES for item in path.iterdir(): if item.is_dir() and item.name[0] != '.': check_packing(item, include_suffixes) continue suffix = item.suffix if suffix in include_suffixes: check_file(item) if __name__ == '__main__': # Skip filename and 'sdk/tools' use_path = Path(__file__).parents[2] check_packing(use_path, DEFAULT_SUFFIXES)