# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os

# 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__)

# 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:
    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

    llvmgcc_dir = getattr(config, 'llvmgcc_dir', None)
    if not llvm_tools_dir:
        lit.fatal('No llvm-gcc dir set!')
    if llvmgcc_dir:
        path = os.path.pathsep.join((os.path.join(llvmgcc_dir, 'bin'),
                                     config.environment['PATH']))
        config.environment['PATH'] = path

###

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', 'compile_cxx', 'compile_c',
            'link', 'shlibext', 'ocamlopt', 'llvmdsymutil', 'llvmlibsdir',
            'bugpoint_topts']:
    if sub in ('llvmgcc', 'llvmgxx'):
        config.substitutions.append(('%' + sub,
                                     site_exp[sub] + ' -emit-llvm -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]))

excludes = []

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

# 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(site_exp['llvmgcc_langs'].split(','))
def llvm_gcc_supports(name):
    return name in langs

bindings = set(site_exp['llvm_bindings'].split(','))
def llvm_supports_binding(name):
    return name 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
