cpp_proto_wrapper.py 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import sys
  2. import os
  3. import subprocess
  4. import re
  5. import argparse
  6. FROM_RE = re.compile(r"((?:struct|class)\s+\S+\s+)final\s*:")
  7. TO_RE = r"\1:"
  8. def parse_args() -> argparse.Namespace:
  9. parser = argparse.ArgumentParser()
  10. parser.add_argument('--outputs', nargs='+', required=True)
  11. parser.add_argument('subcommand', nargs='+')
  12. return parser.parse_args()
  13. def patch_proto_file(text: str) -> tuple[str, int]:
  14. return re.subn(FROM_RE, TO_RE, text)
  15. def main(namespace: argparse.Namespace) -> int:
  16. try:
  17. subprocess.check_output(namespace.subcommand, stdin=None, stderr=subprocess.STDOUT)
  18. except subprocess.CalledProcessError as e:
  19. sys.stderr.write(
  20. '{} returned non-zero exit code {}.\n{}\n'.format(' '.join(e.cmd), e.returncode, e.output.decode('utf-8', errors='ignore'))
  21. )
  22. return e.returncode
  23. for output in namespace.outputs:
  24. with open(output, 'rt', encoding="utf-8") as f:
  25. patched_text, num_patches = patch_proto_file(f.read())
  26. if num_patches:
  27. with open(output, 'wt', encoding="utf-8") as f:
  28. f.write(patched_text)
  29. return 0
  30. if __name__ == '__main__':
  31. sys.exit(main(parse_args()))