parse_wordlist.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/env python3
  2. """Parse mnemonicode mn_wordlist.c and emit the wordlist as JSON."""
  3. import argparse
  4. import json
  5. import re
  6. import sys
  7. from pathlib import Path
  8. def parse_wordlist(src: Path) -> dict:
  9. text = src.read_text()
  10. version_match = re.search(r'mn_wordlist_version\s*=\s*"[^"]*?([\d]+\.[\d]+)"', text)
  11. if not version_match:
  12. # Try alternate form: version embedded in longer string
  13. version_match = re.search(r'mn_wordlist_version\s*=\s*"[^"]*?(\d[\d.]+\d)', text)
  14. if not version_match:
  15. raise ValueError("Could not find mn_wordlist_version in source file")
  16. version = version_match.group(1)
  17. array_match = re.search(r'mn_words\[.*?\]\s*=\s*\{(.*?)\};', text, re.DOTALL)
  18. if not array_match:
  19. raise ValueError("Could not find mn_words array in source file")
  20. array_body = array_match.group(1)
  21. # All quoted strings in the array body; first element is the null sentinel (0, not a string)
  22. words = re.findall(r'"([^"]+)"', array_body)
  23. return {"version": version, "words": words}
  24. def main():
  25. parser = argparse.ArgumentParser(
  26. description="Parse mnemonicode mn_wordlist.c and emit the wordlist as JSON"
  27. )
  28. parser.add_argument(
  29. "source",
  30. nargs="?",
  31. default=str(Path(__file__).parent.parent / "mnemonicode/mn_wordlist.c"),
  32. help="Path to mn_wordlist.c (default: ../mnemonicode/mn_wordlist.c relative to tools/)",
  33. )
  34. parser.add_argument(
  35. "-o", "--output",
  36. help="Write output to this file instead of stdout",
  37. )
  38. parser.add_argument(
  39. "--indent",
  40. type=int,
  41. default=2,
  42. help="JSON indent level (default: 2; use 0 for compact)",
  43. )
  44. args = parser.parse_args()
  45. src = Path(args.source)
  46. if not src.exists():
  47. print(f"error: source file not found: {src}", file=sys.stderr)
  48. sys.exit(1)
  49. result = parse_wordlist(src)
  50. indent = args.indent if args.indent > 0 else None
  51. output = json.dumps(result, indent=indent, ensure_ascii=False)
  52. if args.output:
  53. Path(args.output).write_text(output + "\n")
  54. print(f"wrote {len(result['words'])} words (version {result['version']}) -> {args.output}")
  55. else:
  56. print(output)
  57. if __name__ == "__main__":
  58. main()