# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import sys
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:
                compile_cmd = [self.cxx_under_test, '-o', exec_path,
                       source_path] + self.cpp_flags + self.ld_flags
                cmd = compile_cmd
                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 = """Compiled With: %s\n""" % ' '.join(["'%s'" % a
                                                                   for a in compile_cmd])
                    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:
    cxx_under_test = getattr(config, '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++)')
include_paths = []
library_paths = []

libcxx_src_root = getattr(config, 'libcxx_src_root', None)
if libcxx_src_root is not None:
  include_paths += ['-I' + libcxx_src_root + '/include']
else:
  include_paths += ['-I/usr/include/c++/v1']

libcxx_obj_root = getattr(config, 'libcxx_obj_root', None)
if libcxx_obj_root is not None:
  library_paths += ['-L' + libcxx_obj_root + '/lib']
else:
  libcxx_obj_root = "/usr"

# Configure extra compiler flags.
compile_flags = []
if getattr(config, 'cxx_has_stdcxx0x_flag', False):
  compile_flags += ['-std=c++0x']

# Configure extra libraries.
libraries = []
if sys.platform == 'darwin':
  libraries += ['-lSystem']
if sys.platform == 'linux2':
  libraries += ['-lgcc_eh', '-lsupc++', '-lc', '-lm', '-lrt', '-lgcc_s']
  libraries += ['-Wl,-R', libcxx_obj_root + '/lib']

config.test_format = LibcxxTestFormat(cxx_under_test,
                                      cpp_flags = ['-nostdinc++'] + compile_flags + include_paths,
                                      ld_flags = ['-nodefaultlibs'] + library_paths + ['-lc++'] + libraries)

config.target_triple = None
