# -*- 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()

# 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'.
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"\btblgen\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)

langs = set([s.strip() for s in site_exp['llvmgcc_langs'].split(',')])
def llvm_gcc_supports(name):
    return name.strip() in langs

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')
