#!/usr/bin/env python3 # Author: cirakg & claude ai # Summary: Decode the barcodes the watch's encoders produced in a unit-test run with zxing-cpp (README 12.4 check 2). """Decode-check the CODEDUMP lines of a Monkey C test log. Each line is "CODEDUMP ". Every code is rendered with its quiet zone at 1, 2 and 3 pixels per module and must decode to the expected text at each size. Usage: check_codes.py LOG [LOG ...] Exit: 0 all decoded, 1 a failure, 2 no dump found. """ from __future__ import annotations import re import sys from pathlib import Path import barcode_ref as ref DUMP = re.compile(r"CODEDUMP (\d+) ([0-9a-f]*) ([01]+)") SCALES = (1, 2, 3) def check_log(path: Path) -> tuple[int, list[str]]: """(codes checked, failure messages) for one log.""" checked = 0 failures: list[str] = [] for match in DUMP.finditer(path.read_text(encoding="utf-8", errors="replace")): symbology = int(match.group(1)) text = bytes.fromhex(match.group(2)).decode("utf-8") modules = match.group(3) expected = ref.expected_reading(symbology, text) for scale in SCALES: got = ref.decode(ref.render_linear(modules, scale), symbology) if expected not in got: failures.append(f"symbology {symbology} '{text}' at {scale} px/module: read {got}") checked += 1 return checked, failures def main(argv: list[str] | None = None) -> int: paths = [Path(p) for p in (argv if argv is not None else sys.argv[1:])] total = 0 failed = False for path in paths: checked, failures = check_log(path) total += checked for failure in failures[:10]: print(f"[{path.stem}] {failure}") failed = failed or bool(failures) print(f"[{path.stem}] decoded {checked} barcodes at {len(SCALES)} sizes: {'FAILED' if failures else 'ok'}") if total == 0: print("no CODEDUMP lines found") return 2 return 1 if failed else 0 if __name__ == "__main__": raise SystemExit(main())