brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.3 KiB · 661b027 Raw
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