# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import platform
import tempfile
import signal
import subprocess

class LibcxxTestFormat(lit.formats.FileBasedTest):
    """
    Custom test format handler for use with the test format use by libc++.

    Tests fall into two categories:
      FOO.pass.cpp - Executable test which should compile, run, and exit with
                     code 0.
      FOO.fail.cpp - Negative test case which is expected to fail compilation.
    """

    def __init__(self, cxx_under_test, cpp_flags, ld_flags):
        self.cxx_under_test = cxx_under_test
        self.cpp_flags = list(cpp_flags)
        self.ld_flags = list(ld_flags)

    def execute_command(self, command):
        p = subprocess.Popen(command, stdin=subprocess.PIPE,
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out,err = p.communicate()
        exitCode = p.wait()

        # Detect Ctrl-C in subprocess.
        if exitCode == -signal.SIGINT:
            raise KeyboardInterrupt

        return out, err, exitCode

    def execute(self, test, lit_config):
        name = test.path_in_suite[-1]
        source_path = test.getSourcePath()

        # Check what kind of test this is.
        assert name.endswith('.pass.cpp') or name.endswith('.fail.cpp')
        expected_compile_fail = name.endswith('.fail.cpp')

        # If this is a compile (failure) test, build it and check for failure.
        if expected_compile_fail:
            cmd = [self.cxx_under_test, '-c',
                   '-o', '/dev/null', source_path] + self.cpp_flags
            out, err, exitCode = self.execute_command(cmd)
            if exitCode == 1:
                return lit.Test.PASS, ""
            else:
                report = """Command: %s\n""" % ' '.join(["'%s'" % a
                                                         for a in cmd])
                report += """Exit Code: %d\n""" % exitCode
                if out:
                    report += """Standard Output:\n--\n%s--""" % out
                if err:
                    report += """Standard Error:\n--\n%s--""" % err
                report += "\n\nExpected compilation to fail!"
                return lit.Test.FAIL, report
        else:
            exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
            exec_path = exec_file.name
            exec_file.close()

            try:
                cmd = [self.cxx_under_test, '-o', exec_path,
                       source_path] + self.cpp_flags + self.ld_flags
                out, err, exitCode = self.execute_command(cmd)
                if exitCode != 0:
                    report = """Command: %s\n""" % ' '.join(["'%s'" % a
                                                             for a in cmd])
                    report += """Exit Code: %d\n""" % exitCode
                    if out:
                        report += """Standard Output:\n--\n%s--""" % out
                    if err:
                        report += """Standard Error:\n--\n%s--""" % err
                    report += "\n\nCompilation failed unexpectedly!"
                    return lit.Test.FAIL, report

                cmd = [exec_path]
                out, err, exitCode = self.execute_command(cmd)
                if exitCode != 0:
                    report = """Command: %s\n""" % ' '.join(["'%s'" % a
                                                             for a in cmd])
                    report += """Exit Code: %d\n""" % exitCode
                    if out:
                        report += """Standard Output:\n--\n%s--""" % out
                    if err:
                        report += """Standard Error:\n--\n%s--""" % err
                    report += "\n\nCompiled test failed unexpectedly!"
                    return lit.Test.FAIL, report
            finally:
                try:
                    os.remove(exec_path)
                except:
                    pass
        return lit.Test.PASS, ""

# name: The name of this test suite.
config.name = 'libc++'

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.cpp']

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)

# FIXME: Would be nice to Use -stdlib=libc++ option with Clang's that accept it.
cxx_under_test = lit.params.get('cxx_under_test', None)
if cxx_under_test is None:
    lit.fatal('must specify user parameter cxx_under_test '
              '(e.g., --param=cxx_under_test=clang++)')
config.test_format = LibcxxTestFormat(cxx_under_test,
                                      cpp_flags = ['-nostdinc++',
                                                   '-I/usr/include/c++/v1'],
                                      ld_flags = ['-nodefaultlibs', '-lc++',
                                                  '-lSystem'])

config.target_triple = None
