# -*- Python -*-

import os
import platform

# Configuration file for the 'lit' test runner.

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

# testFormat: The test format to use to interpret tests.
#
# For now we require '&&' between commands, until they get globally killed and
# the test runner updated.
execute_external = platform.system() != 'Windows'
config.test_format = lit.formats.ShTest(execute_external)

# suffixes: A list of file extensions to treat as test files.
config.suffixes = ['.c', '.cpp', '.m', '.mm']

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

# Set llvm_{src,obj}_root for use by others.
config.llvm_src_root = getattr(config, 'llvm_src_root', None)
config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)

# Tweak the PATH to include the tools dir and the scripts dir.
if clang_obj_root is not None:
    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

    llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
    if not llvm_libs_dir:
        lit.fatal('No LLVM libs dir set!')
    path = os.path.pathsep.join((llvm_libs_dir,
                                 config.environment.get('LD_LIBRARY_PATH','')))
    config.environment['LD_LIBRARY_PATH'] = path

###

# 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 'clang_site_config' user parameter, and use that if available.
    site_cfg = lit.params.get('clang_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. We should solve this by just having
    # the .cfg files generated during the configuration step.

    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()
    clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
    clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")

    # Validate that we got a tree which points to here, using the standard
    # tools/clang layout.
    this_src_root = os.path.dirname(config.test_source_root)
    if os.path.realpath(clang_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(clang_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' % clang_obj_root)
    lit.load_config(config, site_cfg)
    raise SystemExit

###

import re
site_exp = {}
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)

targets = set(site_exp['TARGETS_TO_BUILD'].split())
def llvm_supports_target(name):
    return name in targets
config.conditions['TARGET'] = llvm_supports_target

# Discover the 'clang' and 'clangcc' to use.

import os

def inferClang(PATH):
    # Determine which clang to use.
    clang = os.getenv('CLANG')

    # If the user set clang in the environment, definitely use that and don't
    # try to validate.
    if clang:
        return clang

    # Otherwise look in the path.
    clang = lit.util.which('clang', PATH)

    if not clang:
        lit.fatal("couldn't find 'clang' program, try setting "
                  "CLANG in your environment")

    return clang

config.clang = inferClang(config.environment['PATH'])
if not lit.quiet:
    lit.note('using clang: %r' % config.clang)
config.substitutions.append( ('%clang_cc1', config.clang + ' -cc1') )
config.substitutions.append( ('%clangxx', ' ' + config.clang + ' -ccc-cxx'))
config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )

# FIXME: Find nicer way to prohibit this.
config.substitutions.append(
    (' clang ', """*** Do not use 'clang' in tests, use '%clang'. ***""") )
config.substitutions.append(
    (' clang++ ', """*** Do not use 'clang++' in tests, use '%clangxx'. ***"""))
config.substitutions.append(
    (' clang-cc ',
     """*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") )
config.substitutions.append(
    (' clang -cc1 ',
     """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") )
