#!/usr/bin/env python3 """Parse mnemonicode mn_wordlist.c and emit the wordlist as JSON.""" import argparse import json import re import sys from pathlib import Path def parse_wordlist(src: Path) -> dict: text = src.read_text() version_match = re.search(r'mn_wordlist_version\s*=\s*"[^"]*?([\d]+\.[\d]+)"', text) if not version_match: # Try alternate form: version embedded in longer string version_match = re.search(r'mn_wordlist_version\s*=\s*"[^"]*?(\d[\d.]+\d)', text) if not version_match: raise ValueError("Could not find mn_wordlist_version in source file") version = version_match.group(1) array_match = re.search(r'mn_words\[.*?\]\s*=\s*\{(.*?)\};', text, re.DOTALL) if not array_match: raise ValueError("Could not find mn_words array in source file") array_body = array_match.group(1) # All quoted strings in the array body; first element is the null sentinel (0, not a string) words = re.findall(r'"([^"]+)"', array_body) return {"version": version, "words": words} def main(): parser = argparse.ArgumentParser( description="Parse mnemonicode mn_wordlist.c and emit the wordlist as JSON" ) parser.add_argument( "source", nargs="?", default=str(Path(__file__).parent.parent / "mnemonicode/mn_wordlist.c"), help="Path to mn_wordlist.c (default: ../mnemonicode/mn_wordlist.c relative to tools/)", ) parser.add_argument( "-o", "--output", help="Write output to this file instead of stdout", ) parser.add_argument( "--indent", type=int, default=2, help="JSON indent level (default: 2; use 0 for compact)", ) args = parser.parse_args() src = Path(args.source) if not src.exists(): print(f"error: source file not found: {src}", file=sys.stderr) sys.exit(1) result = parse_wordlist(src) indent = args.indent if args.indent > 0 else None output = json.dumps(result, indent=indent, ensure_ascii=False) if args.output: Path(args.output).write_text(output + "\n") print(f"wrote {len(result['words'])} words (version {result['version']}) -> {args.output}") else: print(output) if __name__ == "__main__": main()