From 560fdd150aec7e891cb9d4a53778ace9e8dccf5f Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Thu, 10 Jun 2021 22:05:25 +0200 Subject: [PATCH] [SDK] Add script to check includes with modified struct packing --- sdk/tools/check_packing.py | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 sdk/tools/check_packing.py diff --git a/sdk/tools/check_packing.py b/sdk/tools/check_packing.py new file mode 100644 index 00000000000..f56e49a2fb6 --- /dev/null +++ b/sdk/tools/check_packing.py @@ -0,0 +1,72 @@ +''' +PROJECT: ReactOS code linter +LICENSE: MIT (https://spdx.org/licenses/MIT) +PURPOSE: Verifies that there are no headers included when 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)