#!/usr/bin/env python3
"""Read-only structure audit for the decompiled BIOS source tree."""
from __future__ import annotations
import argparse
from collections import Counter
from pathlib import Path
import re
PHASE_PATTERNS = {
"PEI-like": re.compile(r"(Pei|PEI)", re.ASCII),
"DXE-like": re.compile(r"(Dxe|DXE)", re.ASCII),
"SMM-like": re.compile(r"(Smm|SMM)", re.ASCII),
"PPI-like": re.compile(r"(Ppi|PPI)", re.ASCII),
"variant/update-like": re.compile(
r"(Setup|Config|Sku|Slot|Oprom|UsbOc|IioCfg|SmbiosDataUpdate)", re.ASCII
),
"GUID-named": re.compile(r"^[0-9A-Fa-f]{8}-[0-9A-Fa-f-]{27}$", re.ASCII),
}
SKIP_DIRS = {".git", ".codex", ".agents", "__pycache__", "tools", "docs"}
EXPECTED_MODULE_SIDECARS = ("README.md",)
def top_level_modules(root: Path) -> list[Path]:
return sorted(
path
for path in root.iterdir()
if path.is_dir() and path.name not in SKIP_DIRS and not path.name.startswith(".")
)
def artifact_suffix(path: Path) -> str:
return path.suffix.lower()[1:] if path.suffix else "[no-ext]"
def count_artifacts(root: Path) -> Counter[str]:
counts: Counter[str] = Counter()
for path in root.rglob("*"):
if not path.is_file():
continue
if any(part in SKIP_DIRS for part in path.relative_to(root).parts[:-1]):
continue
counts[artifact_suffix(path)] += 1
return counts
def classify_modules(modules: list[Path]) -> dict[str, list[str]]:
buckets: dict[str, list[str]] = {name: [] for name in PHASE_PATTERNS}
for module in modules:
for name, pattern in PHASE_PATTERNS.items():
if pattern.search(module.name):
buckets[name].append(module.name)
return buckets
def missing_sidecars(modules: list[Path]) -> dict[str, list[str]]:
missing: dict[str, list[str]] = {}
for module in modules:
absent = [name for name in EXPECTED_MODULE_SIDECARS if not (module / name).exists()]
has_c = any(module.glob("*.c"))
has_h = any(module.glob("*.h"))
if has_c and not has_h:
absent.append("*.h")
if has_h and not has_c:
absent.append("*.c")
if absent:
missing[module.name] = absent
return missing
def print_counter(title: str, counter: Counter[str], limit: int) -> None:
print(f"\n{title}")
print("-" * len(title))
for key, value in counter.most_common(limit):
print(f"{value:5d} {key}")
def main() -> int:
parser = argparse.ArgumentParser(
description="Print a read-only structure audit for decompiled BIOS modules."
)
parser.add_argument(
"root",
nargs="?",
default=".",
help="repository root to inspect, default: current directory",
)
parser.add_argument(
"--limit",
type=int,
default=20,
help="maximum rows to print for long sections",
)
args = parser.parse_args()
root = Path(args.root).resolve()
modules = top_level_modules(root)
artifacts = count_artifacts(root)
phase_buckets = classify_modules(modules)
missing = missing_sidecars(modules)
print(f"BIOS source tree: {root}")
print(f"Top-level module directories: {len(modules)}")
print(f"Files scanned: {sum(artifacts.values())}")
print_counter("Artifact types", artifacts, args.limit)
print("\nName buckets")
print("------------")
for name, members in phase_buckets.items():
print(f"{len(members):5d} {name}")
print("\nPotential cleanup targets")
print("-------------------------")
if not missing:
print("No missing expected sidecars found.")
else:
for module, absent in sorted(missing.items())[: args.limit]:
print(f"{module}: missing {', '.join(absent)}")
remaining = len(missing) - args.limit
if remaining > 0:
print(f"... {remaining} more; rerun with --limit {len(missing)} to list all")
print("\nNotes")
print("-----")
print("This tool is read-only and uses file names as hints, not proof of behavior.")
print("Review module README.md and local call sites before renaming decompiled code.")
return 0
if __name__ == "__main__":
raise SystemExit(main())