# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os

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

# 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.
klee_obj_root = getattr(config, 'klee_obj_root', None)
if klee_obj_root is not None:
    config.test_exec_root = os.path.join(klee_obj_root, 'test')

# Tweak the PATH to include the tool dir.
if klee_obj_root is not None:
    klee_tools_dir = getattr(config, 'klee_tools_dir', None)
    if not klee_tools_dir:
        lit.fatal('No KLEE tools dir set!')
    path = os.path.pathsep.join((klee_tools_dir, config.environment['PATH']))
    config.environment['PATH'] = path

# Propogate 'HOME' through the environment.
config.environment['HOME'] = os.environ['HOME']

###

import os

# Check that the object root is known.
if config.test_exec_root is None:
    lit.fatal('test execution root not set!')

###

# 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.klee_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']:
    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]))

# FIXME: Give these proper paths.
config.substitutions.append(('%kleaver', 'kleaver'))
config.substitutions.append(('%klee', 'klee'))

def klee_supports_posix_runtime():
    return int(site_exp['ENABLE_POSIX_RUNTIME'])

def klee_supports_uclibc():
    return int(site_exp['ENABLE_UCLIBC'])

excludes = []

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

# 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.*\[?(klee[^ ]*)\].*{
 *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,match = m.groups()
        addSuffixes(match)

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

config.on_clone = on_clone
