1#!/usr/bin/env python3 2 3"""Compiles a source file and compares generated .mod files against expected. 4 5Parameters: 6 sys.argv[1]: a source file with contains the input and expected output 7 sys.argv[2]: the Flang frontend driver 8 sys.argv[3:]: Optional arguments to the Flang frontend driver""" 9 10import sys 11import re 12import os 13import tempfile 14import subprocess 15import glob 16import common as cm 17 18from pathlib import Path 19from difflib import unified_diff 20 21cm.check_args_long(sys.argv) 22srcdir = Path(sys.argv[1]) 23sources = list(glob.iglob(str(srcdir))) 24sources = sorted(sources) 25diffs = "" 26 27flang_fc1 = cm.set_executable(sys.argv[2]) 28flang_fc_args = sys.argv[3:] 29flang_fc1_options = "-fsyntax-only" 30 31with tempfile.TemporaryDirectory() as tmpdir: 32 for src in sources: 33 src = Path(src).resolve() 34 actual = "" 35 expect = "" 36 expected_files = set() 37 actual_files = set() 38 39 if not src.is_file(): 40 cm.die(src) 41 42 prev_files = set(os.listdir(tmpdir)) 43 cmd = [flang_fc1, *flang_fc_args, flang_fc1_options, str(src)] 44 proc = subprocess.check_output(cmd, stderr=subprocess.PIPE, 45 universal_newlines=True, cwd=tmpdir) 46 actual_files = set(os.listdir(tmpdir)).difference(prev_files) 47 48 # The first 3 bytes of the files are an UTF-8 BOM 49 with open(src, 'r', encoding="utf-8", errors="strict") as f: 50 for line in f: 51 m = re.search(r"^!Expect: (.*)", line) 52 if m: 53 expected_files.add(m.group(1)) 54 55 extra_files = actual_files.difference(expected_files) 56 if extra_files: 57 print(f"Unexpected .mod files produced: {extra_files}") 58 sys.exit(1) 59 60 for mod in expected_files: 61 mod = Path(tmpdir).joinpath(mod) 62 if not mod.is_file(): 63 print(f"Compilation did not produce expected mod file: {mod}") 64 sys.exit(1) 65 with open(mod, 'r', encoding="utf-8", errors="strict") as f: 66 for line in f: 67 if "!mod$" in line: 68 continue 69 actual += line 70 71 with open(src, 'r', encoding="utf-8", errors="strict") as f: 72 for line in f: 73 if f"!Expect: {mod.name}" in line: 74 for line in f: 75 if re.match(r"^$", line): 76 break 77 m = re.sub(r"^!", "", line.lstrip()) 78 expect += m 79 80 diffs = "\n".join(unified_diff(actual.replace(" ", "").split("\n"), 81 expect.replace(" ", "").split("\n"), 82 fromfile=mod.name, tofile="Expect", n=999999)) 83 84 if diffs != "": 85 print(diffs) 86 print() 87 print("FAIL") 88 sys.exit(1) 89 90print() 91print("PASS") 92 93