# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import sys
import re

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

# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.TclTest()

# To ignore test output on stderr so it doesn't trigger failures uncomment this:
#config.test_format = lit.formats.TclTest(ignoreStdErr=True)

# suffixes: A list of file extensions to treat as test files, this is actually
# set by on_clone().
config.suffixes = []

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

# Tweak PATH for Win32
if sys.platform in ['win32']:
    # Seek sane tools in directories and set to $PATH.
    path = getattr(config, 'lit_tools_dir', None)
    path = lit.getToolsPath(path,
                            config.environment['PATH'],
                            ['cmp.exe', 'grep.exe', 'sed.exe'])
    if path is not None:
        path = os.path.pathsep.join((path,
                                     config.environment['PATH']))
        config.environment['PATH'] = path

# test_exec_root: The root path where tests should be run.
llvm_obj_root = getattr(config, 'llvm_obj_root', None)
if llvm_obj_root is not None:
    config.test_exec_root = os.path.join(llvm_obj_root, 'test')

# Tweak the PATH to include the scripts dir, the tools dir, and the llvm-gcc bin
# dir (if available).
if llvm_obj_root is not None:
    # Include llvm-gcc first, as the llvm-gcc binaryies will not appear
    # neither in the tools nor in the scripts dir. However it might be
    # possible, that some old llvm tools are in the llvm-gcc dir. Adding
    # llvm-gcc dir first ensures, that those will always be overwritten
    # by the new tools in llvm_tools_dir. So now outdated tools are used
      # for testing
    llvmgcc_dir = getattr(config, 'llvmgcc_dir', None)
    if llvmgcc_dir:
        path = os.path.pathsep.join((os.path.join(llvmgcc_dir, 'bin'),
                                     config.environment['PATH']))
        config.environment['PATH'] = path

    llvm_src_root = getattr(config, 'llvm_src_root', None)
    if not llvm_src_root:
        lit.fatal('No LLVM source root set!')
    path = os.path.pathsep.join((os.path.join(llvm_src_root, 'test',
                                              'Scripts'),
                                 config.environment['PATH']))
    config.environment['PATH'] = path

    llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
    if not llvm_tools_dir:
        lit.fatal('No LLVM tools dir set!')
    path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
    config.environment['PATH'] = path

# Propagate 'HOME' through the environment.
if 'HOME' in os.environ:
    config.environment['HOME'] = os.environ['HOME']

# Propagate 'INCLUDE' through the environment.
if 'INCLUDE' in os.environ:
    config.environment['INCLUDE'] = os.environ['INCLUDE']

# Propagate 'LIB' through the environment.
if 'LIB' in os.environ:
    config.environment['LIB'] = os.environ['LIB']

# Propagate the temp directory. Windows requires this because it uses \Windows\
# if none of these are present.
if 'TMP' in os.environ:
    config.environment['TMP'] = os.environ['TMP']
if 'TEMP' in os.environ:
    config.environment['TEMP'] = os.environ['TEMP']

# Propagate LLVM_SRC_ROOT into the environment.
config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '')

# Propagate PYTHON_EXECUTABLE into the environment
config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable',
                                                  '')

###

import os

# Check that the object root is known.
if config.test_exec_root is None:
    # Otherwise, we haven't loaded the site specific configuration (the user is
    # probably trying to run on a test file directly, and either the site
    # configuration hasn't been created by the build system, or we are in an
    # out-of-tree build situation).

    # Check for 'llvm_site_config' user parameter, and use that if available.
    site_cfg = lit.params.get('llvm_site_config', None)
    if site_cfg and os.path.exists(site_cfg):
        lit.load_config(config, site_cfg)
        raise SystemExit

    # Try to detect the situation where we are using an out-of-tree build by
    # looking for 'llvm-config'.
    #
    # FIXME: I debated (i.e., wrote and threw away) adding logic to
    # automagically generate the lit.site.cfg if we are in some kind of fresh
    # build situation. This means knowing how to invoke the build system
    # though, and I decided it was too much magic.

    llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
    if not llvm_config:
        lit.fatal('No site specific configuration available!')

    # Get the source and object roots.
    llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
    llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()

    # Validate that we got a tree which points to here.
    this_src_root = os.path.dirname(config.test_source_root)
    if os.path.realpath(llvm_src_root) != os.path.realpath(this_src_root):
        lit.fatal('No site specific configuration available!')

    # Check that the site specific configuration exists.
    site_cfg = os.path.join(llvm_obj_root, 'test', 'lit.site.cfg')
    if not os.path.exists(site_cfg):
        lit.fatal('No site specific configuration available!')

    # Okay, that worked. Notify the user of the automagic, and reconfigure.
    lit.note('using out-of-tree build at %r' % llvm_obj_root)
    lit.load_config(config, site_cfg)
    raise SystemExit

###

# Load site data from DejaGNU's site.exp.
import re
site_exp = {}
# FIXME: Implement lit.site.cfg.
for line in open(os.path.join(config.llvm_obj_root, 'test', 'site.exp')):
    m = re.match('set ([^ ]+) "(.*)"', line)
    if m:
        site_exp[m.group(1)] = m.group(2)

# Add substitutions.
config.substitutions.append(('%llvmgcc_only', site_exp['llvmgcc']))
for sub in ['llvmgcc', 'llvmgxx', 'emitir', 'compile_cxx', 'compile_c',
            'link', 'shlibext', 'ocamlopt', 'llvmdsymutil', 'llvmlibsdir',
            'llvmshlibdir',
            'bugpoint_topts']:
    if sub in ('llvmgcc', 'llvmgxx'):
        config.substitutions.append(('%' + sub,
                                     site_exp[sub] + ' %emitir -w'))
    # FIXME: This is a hack to avoid LLVMC tests failing due to a clang driver
    #        warning when passing in "-fexceptions -fno-exceptions".
    elif sub == 'compile_cxx':
        config.substitutions.append(('%' + sub,
                                  site_exp[sub].replace('-fno-exceptions', '')))
    else:
        config.substitutions.append(('%' + sub, site_exp[sub]))

# For each occurrence of an llvm tool name as its own word, replace it
# with the full path to the build directory holding that tool.  This
# ensures that we are testing the tools just built and not some random
# tools that might happen to be in the user's PATH.  Thus this list
# includes every tool placed in $(LLVM_OBJ_ROOT)/$(BuildMode)/bin
# (llvm_tools_dir in lit parlance).
                # Don't match 'bugpoint-' or 'clang-'.
                # Don't match '/clang' or '-clang'.
if os.pathsep == ';':
    pathext = os.environ.get('PATHEXT', '').split(';')
else:
    pathext = ['']
for pattern in [r"\bbugpoint\b(?!-)",   r"(?<!/|-)\bclang\b(?!-)",
                r"\bgold\b",
                r"\bllc\b",             r"\blli\b",
                r"\bllvm-ar\b",         r"\bllvm-as\b",
                r"\bllvm-bcanalyzer\b", r"\bllvm-config\b",
                r"\bllvm-diff\b",       r"\bllvm-dis\b",
                r"\bllvm-extract\b",    r"\bllvm-ld\b",
                r"\bllvm-link\b",       r"\bllvm-mc\b",
                r"\bllvm-nm\b",         r"\bllvm-prof\b",
                r"\bllvm-ranlib\b",     r"\bllvm-shlib\b",
                r"\bllvm-stub\b",       r"\bllvm2cpp\b",
                # Don't match '-llvmc'.
                r"(?<!-)\bllvmc\b",     r"\blto\b",
                                        # Don't match '.opt', '-opt',
                                        # '^opt' or '/opt'.
                r"\bmacho-dump\b",      r"(?<!\.|-|\^|/)\bopt\b",
                r"\bllvm-tblgen\b",     r"\bFileCheck\b",
                r"\bFileUpdate\b",      r"\bc-index-test\b",
                r"\bfpcmp\b",           r"\bllvm-PerfectShuffle\b",
                # Handle these specially as they are strings searched
                # for during testing.
                r"\| \bcount\b",         r"\| \bnot\b"]:
    # Extract the tool name from the pattern.  This relies on the tool
    # name being surrounded by \b word match operators.  If the
    # pattern starts with "| ", include it in the string to be
    # substituted.
    substitution = re.sub(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
                          r"\2" + llvm_tools_dir + "/" + r"\4",
                          pattern)
    for ext in pathext:
        substitution_ext = substitution + ext
        if os.path.exists(substitution_ext):
             substitution = substitution_ext
             break
    config.substitutions.append((pattern, substitution))

excludes = []

# Provide target_triple for use in XFAIL and XTARGET.
config.target_triple = site_exp['target_triplet']

# When running under valgrind, we mangle '-vg' or '-vg_leak' onto the end of the
# triple so we can check it with XFAIL and XTARGET.
config.target_triple += lit.valgrindTriple

# Provide llvm_supports_target for use in local configs.
targets = set(site_exp["TARGETS_TO_BUILD"].split())
def llvm_supports_target(name):
    return name in targets

def llvm_supports_darwin_and_target(name):
    return 'darwin' in config.target_triple and llvm_supports_target(name)

bindings = set([s.strip() for s in site_exp['llvm_bindings'].split(',')])
def llvm_supports_binding(name):
    return name.strip() in bindings

# Provide on_clone hook for reading 'dg.exp'.
import os
simpleLibData = re.compile(r"""load_lib llvm.exp

RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]""",
                           re.MULTILINE)
conditionalLibData = re.compile(r"""load_lib llvm.exp

if.*\[ ?(llvm[^ ]*) ([^ ]*) ?\].*{
 *RunLLVMTests \[lsort \[glob -nocomplain \$srcdir/\$subdir/\*\.(.*)\]\]
\}""", re.MULTILINE)
def on_clone(parent, cfg, for_path):
    def addSuffixes(match):
        if match[0] == '{' and match[-1] == '}':
            cfg.suffixes = ['.' + s for s in match[1:-1].split(',')]
        else:
            cfg.suffixes = ['.' + match]

    libPath = os.path.join(os.path.dirname(for_path),
                           'dg.exp')
    if not os.path.exists(libPath):
        cfg.unsupported = True
        return

    # Reset unsupported, in case we inherited it.
    cfg.unsupported = False
    lib = open(libPath).read().strip()

    # Check for a simple library.
    m = simpleLibData.match(lib)
    if m:
        addSuffixes(m.group(1))
        return

    # Check for a conditional test set.
    m = conditionalLibData.match(lib)
    if m:
        funcname,arg,match = m.groups()
        addSuffixes(match)

        func = globals().get(funcname)
        if not func:
            lit.error('unsupported predicate %r' % funcname)
        elif not func(arg):
            cfg.unsupported = True
        return
    # Otherwise, give up.
    lit.error('unable to understand %r:\n%s' % (libPath, lib))

config.on_clone = on_clone

### Features

# Shell execution
if sys.platform not in ['win32'] or lit.getBashPath() != '':
    config.available_features.add('shell')

# Loadable module
# FIXME: This should be supplied by Makefile or autoconf.
if sys.platform in ['win32', 'cygwin']:
    loadable_module = (config.enable_shared == 1)
else:
    loadable_module = True

if loadable_module:
    config.available_features.add('loadable_module')

if config.enable_assertions:
    config.available_features.add('asserts')
