File: test_errors.py

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (82 lines) | stat: -rwxr-xr-x 2,317 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#!/usr/bin/env python3

"""Compiles a source file and checks errors against those listed in the file.

Parameters:
    sys.argv[1]: a source file with contains the input and expected output
    sys.argv[2]: the Flang frontend driver
    sys.argv[3:]: Optional arguments to the Flang frontend driver"""

import sys
import re
import tempfile
import subprocess
import common as cm

from difflib import unified_diff

cm.check_args(sys.argv)
srcdir = cm.set_source(sys.argv[1])
with open(srcdir, "r") as f:
    src = f.readlines()
actual = ""
expect = ""
diffs = ""
log = ""

flang_fc1 = cm.set_executable(sys.argv[2])
flang_fc1_args = sys.argv[3:]
flang_fc1_options = "-fsyntax-only"

# Compiles, and reads in the output from the compilation process
cmd = [flang_fc1, *flang_fc1_args, flang_fc1_options, str(srcdir)]
with tempfile.TemporaryDirectory() as tmpdir:
    try:
        proc = subprocess.run(
            cmd,
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            check=True,
            universal_newlines=True,
            cwd=tmpdir,
        )
    except subprocess.CalledProcessError as e:
        log = e.stderr
        if e.returncode >= 128:
            print(f"{log}")
            sys.exit(1)

# Cleans up the output from the compilation process to be easier to process
for line in log.split("\n"):
    m = re.search(r"[^:]*:(\d+:).*(?:error|warning|portability|because):(.*)", line)
    if m:
        if re.search(r"warning: .*fold.*host", line):
            continue  # ignore host-dependent folding warnings
        actual += m.expand(r"\1\2\n")

# Gets the expected errors and their line numbers
errors = []
for i, line in enumerate(src, 1):
    m = re.search(r"(?:^\s*!\s*(?:ERROR|WARNING|PORTABILITY|BECAUSE): )(.*)", line)
    if m:
        errors.append(m.group(1))
        continue
    if errors:
        for x in errors:
            expect += f"{i}: {x}\n"
        errors = []

# Compares the expected errors with the compiler errors
for line in unified_diff(actual.split("\n"), expect.split("\n"), n=0):
    line = re.sub(r"(^\-)(\d+:)", r"\nactual at \g<2>", line)
    line = re.sub(r"(^\+)(\d+:)", r"\nexpect at \g<2>", line)
    diffs += line

if diffs != "":
    print(diffs)
    print()
    print("FAIL")
    sys.exit(1)
else:
    print()
    print("PASS")