1#!/usr/bin/env python3
2
3import argparse
4import difflib
5import errno
6import os
7import pathlib
8import subprocess
9import sys
10
11# The meson version handles windows paths better, but if it's not available
12# fall back to shlex
13try:
14    from meson.mesonlib import split_args
15except ImportError:
16    from shlex import split as split_args
17
18parser = argparse.ArgumentParser()
19parser.add_argument('--i965_asm',
20                    help='path to i965_asm binary')
21parser.add_argument('--gen_name',
22                    help='name of the hardware generation (as understood by i965_asm)')
23parser.add_argument('--gen_folder',
24                    type=pathlib.Path,
25                    help='name of the folder for the generation')
26args = parser.parse_args()
27
28wrapper = os.environ.get('MESON_EXE_WRAPPER')
29if wrapper is not None:
30    i965_asm = split_args(wrapper) + [args.i965_asm]
31else:
32    i965_asm = [args.i965_asm]
33
34success = True
35
36for asm_file in args.gen_folder.glob('*.asm'):
37    expected_file = asm_file.stem + '.expected'
38    expected_path = args.gen_folder / expected_file
39
40    try:
41        command = i965_asm + [
42            '--type', 'hex',
43            '--gen', args.gen_name,
44            asm_file
45        ]
46        with subprocess.Popen(command,
47                              stdout=subprocess.PIPE,
48                              stderr=subprocess.DEVNULL) as cmd:
49            lines_after = [line.decode('ascii') for line in cmd.stdout.readlines()]
50    except OSError as e:
51        if e.errno == errno.ENOEXEC:
52            print('Skipping due to inability to run host binaries.',
53                  file=sys.stderr)
54            exit(77)
55        raise
56
57    with expected_path.open() as f:
58        lines_before = f.readlines()
59
60    diff = ''.join(difflib.unified_diff(lines_before, lines_after,
61                                        expected_file, asm_file.stem + '.out'))
62
63    if diff:
64        print('Output comparison for {}:'.format(asm_file.name))
65        print(diff)
66        success = False
67    else:
68        print('{} : PASS'.format(asm_file.name))
69
70if not success:
71    exit(1)
72