| #!/usr/bin/env python3 |
| """Generate test body using split-file and a custom script. |
| |
| The script will prepare extra files with `split-file`, invoke `gen`, and then |
| rewrite the part after `gen` with its stdout. |
| |
| https://llvm.org/docs/TestingGuide.html#elaborated-tests |
| |
| Example: |
| PATH=/path/to/clang_build/bin:$PATH llvm/utils/update_test_body.py path/to/test.s |
| """ |
| import argparse |
| import contextlib |
| import os |
| import re |
| import subprocess |
| import sys |
| import tempfile |
| |
| |
| @contextlib.contextmanager |
| def cd(directory): |
| cwd = os.getcwd() |
| os.chdir(directory) |
| try: |
| yield |
| finally: |
| os.chdir(cwd) |
| |
| |
| def process(args, path): |
| prolog = [] |
| seen_gen = False |
| with open(path) as f: |
| for line in f.readlines(): |
| line = line.rstrip() |
| prolog.append(line) |
| if (seen_gen and re.match(r"(.|//)---", line)) or line.startswith(".endif"): |
| break |
| if re.match(r"(.|//)--- gen", line): |
| seen_gen = True |
| else: |
| print( |
| "'gen' should be followed by another part (---) or .endif", |
| file=sys.stderr, |
| ) |
| return 1 |
| |
| if not seen_gen: |
| print("'gen' does not exist", file=sys.stderr) |
| return 1 |
| with tempfile.TemporaryDirectory(prefix="update_test_body_") as dir: |
| try: |
| # If the last line starts with ".endif", remove it. |
| sub = subprocess.run( |
| ["split-file", "-", dir], |
| input="\n".join( |
| prolog[:-1] if prolog[-1].startswith(".endif") else prolog |
| ).encode(), |
| capture_output=True, |
| check=True, |
| ) |
| except subprocess.CalledProcessError as ex: |
| sys.stderr.write(ex.stderr.decode()) |
| return 1 |
| with cd(dir): |
| if args.shell: |
| print(f"invoke shell in the temporary directory '{dir}'") |
| subprocess.run([os.environ.get("SHELL", "sh")]) |
| return 0 |
| |
| sub = subprocess.run( |
| ["sh", "-eu", "gen"], |
| capture_output=True, |
| # Don't encode the directory information to the Clang output. |
| # Remove unneeded details (.ident) as well. |
| env=dict( |
| os.environ, |
| CCC_OVERRIDE_OPTIONS="#^-fno-ident", |
| PWD="/proc/self/cwd", |
| ), |
| ) |
| sys.stderr.write(sub.stderr.decode()) |
| if sub.returncode != 0: |
| print("'gen' failed", file=sys.stderr) |
| return sub.returncode |
| if not sub.stdout: |
| print("stdout is empty; forgot -o - ?", file=sys.stderr) |
| return 1 |
| content = sub.stdout.decode() |
| |
| with open(path, "w") as f: |
| # Print lines up to '.endif'. |
| print("\n".join(prolog), file=f) |
| # Then print the stdout of 'gen'. |
| f.write(content) |
| |
| |
| parser = argparse.ArgumentParser( |
| description="Generate test body using split-file and a custom script" |
| ) |
| parser.add_argument("files", nargs="+") |
| parser.add_argument( |
| "--shell", action="store_true", help="invoke shell instead of 'gen'" |
| ) |
| args = parser.parse_args() |
| for path in args.files: |
| retcode = process(args, path) |
| if retcode != 0: |
| sys.exit(retcode) |