Files
object/scripts/winnt-diff.py
T
Philip Craig a53748df83 Update PE definitions from winnt.h (#903)
Most of these are commented out until we need them.
2026-05-16 20:35:38 +10:00

101 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""Compare PE struct and constant definitions between winnt.h and src/pe.rs."""
import re
import sys
from pathlib import Path
def normalize(name):
s = re.sub(r'(?<=[a-z0-9])(?=[A-Z])', '_', name)
s = re.sub(r'(?<=[A-Z])(?=[A-Z][a-z])', '_', s)
return s.upper()
def print_norm(orig, norm):
if orig == norm:
print(f" {orig}")
else:
print(f" {orig} -> {norm}")
def ordered_norm(items):
items.sort(key=lambda x: x[0])
return {norm: (name, norm) for _, name, norm in items}
def extract_image_format(text):
start = re.search(r'^// Image Format\s*$', text, re.MULTILINE)
end = re.search(r'^// End Image Format\s*$', text, re.MULTILINE)
if start and end:
return text[start.start():end.end()]
return text
def parse_winnt_h(path):
text = extract_image_format(path.read_text())
items = []
# struct _NAME { or union _NAME {
for m in re.finditer(
r'(?:struct|union)\s+(?:\w+\s+)?_?(\w+)\s*\{',
text
):
name = m.group(1).lstrip('_')
items.append((m.start(), name, normalize(name)))
# #define NAME value
for m in re.finditer(r'^#\s*define\s+([A-Z]\w+)\s', text, re.MULTILINE):
name = m.group(1)
items.append((m.start(), name, name.upper()))
# NAME = value,
for m in re.finditer(r'^\s+(\w+)\s*=\s*\w+', text, re.MULTILINE):
name = m.group(1)
items.append((m.start(), name, name.upper()))
return ordered_norm(items)
def parse_pe_rs(path):
text = path.read_text()
items = []
# pub struct Name
for m in re.finditer(r'^pub struct (\w+)', text, re.MULTILINE):
name = m.group(1)
items.append((m.start(), name, normalize(name)))
# pub const NAME:
for m in re.finditer(r'^pub const (\w+)\s*:', text, re.MULTILINE):
name = m.group(1)
items.append((m.start(), name, name.upper()))
# NAME = value,
for m in re.finditer(r'^\s+(\w+)\s*=\s*-?[\w.]+\s*[,=]', text, re.MULTILINE):
name = m.group(1)
items.append((m.start(), name, name.upper()))
return ordered_norm(items)
def main():
winnt_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path('.') / 'winnt.h'
winnt = parse_winnt_h(winnt_path)
pe = parse_pe_rs(Path('.') / 'src' / 'pe.rs')
only_winnt = [k for k in winnt if k not in pe]
only_pe = [k for k in pe if k not in winnt]
print("=== in winnt.h but not in pe.rs ===")
for k in only_winnt:
print_norm(*winnt[k])
print("\n=== in pe.rs but not in winnt.h ===")
for k in only_pe:
print_norm(*pe[k])
if __name__ == '__main__':
main()