111 lines · python
1#!/usr/bin/env python32"""Generate test body using split-file and a custom script.3 4The script will prepare extra files with `split-file`, invoke `gen`, and then5rewrite the part after `gen` with its stdout.6 7https://llvm.org/docs/TestingGuide.html#elaborated-tests8 9Example:10PATH=/path/to/clang_build/bin:$PATH llvm/utils/update_test_body.py path/to/test.s11"""12import argparse13import contextlib14import os15import re16import subprocess17import sys18import tempfile19 20 21@contextlib.contextmanager22def cd(directory):23 cwd = os.getcwd()24 os.chdir(directory)25 try:26 yield27 finally:28 os.chdir(cwd)29 30 31def process(args, path):32 prolog = []33 seen_gen = False34 with open(path) as f:35 for line in f.readlines():36 line = line.rstrip()37 prolog.append(line)38 if (seen_gen and re.match(r"(.|//)---", line)) or line.startswith(".endif"):39 break40 if re.match(r"(.|//)--- gen", line):41 seen_gen = True42 else:43 print(44 "'gen' should be followed by another part (---) or .endif",45 file=sys.stderr,46 )47 return 148 49 if not seen_gen:50 print("'gen' does not exist", file=sys.stderr)51 return 152 with tempfile.TemporaryDirectory(prefix="update_test_body_") as dir:53 try:54 # If the last line starts with ".endif", remove it.55 sub = subprocess.run(56 ["split-file", "-", dir],57 input="\n".join(58 prolog[:-1] if prolog[-1].startswith(".endif") else prolog59 ).encode(),60 capture_output=True,61 check=True,62 )63 except subprocess.CalledProcessError as ex:64 sys.stderr.write(ex.stderr.decode())65 return 166 with cd(dir):67 if args.shell:68 print(f"invoke shell in the temporary directory '{dir}'")69 subprocess.run([os.environ.get("SHELL", "sh")])70 return 071 72 sub = subprocess.run(73 ["sh", "-eu", "gen"],74 capture_output=True,75 # Don't encode the directory information to the Clang output.76 # Remove unneeded details (.ident) as well.77 env=dict(78 os.environ,79 CCC_OVERRIDE_OPTIONS="#^-fno-ident",80 PWD="/proc/self/cwd",81 ),82 )83 sys.stderr.write(sub.stderr.decode())84 if sub.returncode != 0:85 print("'gen' failed", file=sys.stderr)86 return sub.returncode87 if not sub.stdout:88 print("stdout is empty; forgot -o - ?", file=sys.stderr)89 return 190 content = sub.stdout.decode()91 92 with open(path, "w") as f:93 # Print lines up to '.endif'.94 print("\n".join(prolog), file=f)95 # Then print the stdout of 'gen'.96 f.write(content)97 98 99parser = argparse.ArgumentParser(100 description="Generate test body using split-file and a custom script"101)102parser.add_argument("files", nargs="+")103parser.add_argument(104 "--shell", action="store_true", help="invoke shell instead of 'gen'"105)106args = parser.parse_args()107for path in args.files:108 retcode = process(args, path)109 if retcode != 0:110 sys.exit(retcode)111