# -*- Python -*-

import os
import platform
import re
import subprocess
import tempfile

import lit.formats
import lit.util

# Configuration file for the 'lit' test runner.

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

# Tweak PATH for Win32
if platform.system() == 'Windows':
    # Seek sane tools in directories and set to $PATH.
    path = getattr(config, 'lit_tools_dir', None)
    path = lit_config.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

# Choose between lit's internal shell pipeline runner and a real shell.  If
# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
if use_lit_shell:
    # 0 is external, "" is default, and everything else is internal.
    execute_external = (use_lit_shell == "0")
else:
    # Otherwise we default to internal on Windows and external elsewhere, as
    # bash on Windows is usually very slow.
    execute_external = (not sys.platform in ['win32'])

# 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.
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', '.cu', '.ll', '.cl', '.s', '.S', '.modulemap']

# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
# subdirectories contain auxiliary inputs for various tests in their parent
# directories.
config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']

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

# Clear some environment variables that might affect Clang.
#
# This first set of vars are read by Clang, but shouldn't affect tests
# that aren't specifically looking for these features, or are required
# simply to run the tests at all.
#
# FIXME: Should we have a tool that enforces this?

# safe_env_vars = ('TMPDIR', 'TEMP', 'TMP', 'USERPROFILE', 'PWD',
#                  'MACOSX_DEPLOYMENT_TARGET', 'IPHONEOS_DEPLOYMENT_TARGET',
#                  'VCINSTALLDIR', 'VC100COMNTOOLS', 'VC90COMNTOOLS',
#                  'VC80COMNTOOLS')
possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS',
                               'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH',
                               'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH',
                               'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH',
                               'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING',
                               'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX',
                               'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS',
                               'LIBCLANG_RESOURCE_USAGE',
                               'LIBCLANG_CODE_COMPLETION_LOGGING']
# Clang/Win32 may refer to %INCLUDE%. vsvarsall.bat sets it.
if platform.system() != 'Windows':
    possibly_dangerous_env_vars.append('INCLUDE')
for name in possibly_dangerous_env_vars:
  if name in config.environment:
    del config.environment[name]

# Tweak the PATH to include the tools dir and the scripts dir.
if clang_obj_root is not None:
    clang_tools_dir = getattr(config, 'clang_tools_dir', None)
    if not clang_tools_dir:
        lit_config.fatal('No Clang tools dir set!')
    llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
    if not llvm_tools_dir:
        lit_config.fatal('No LLVM tools dir set!')
    path = os.path.pathsep.join((
            clang_tools_dir, 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_config.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

# Propagate path to symbolizer for ASan/MSan.
for symbolizer in ['ASAN_SYMBOLIZER_PATH', 'MSAN_SYMBOLIZER_PATH']:
    if symbolizer in os.environ:
        config.environment[symbolizer] = os.environ[symbolizer]

###

# 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_config.params.get('clang_site_config', None)
    if site_cfg and os.path.exists(site_cfg):
        lit_config.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_config.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_config.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_config.fatal(
            'No site specific configuration available! You may need to '
            'run "make test" in your Clang build directory.')

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

###

# 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_config.fatal("couldn't find 'clang' program, try setting "
                         "CLANG in your environment")

    return clang

config.clang = inferClang(config.environment['PATH']).replace('\\', '/')
if not lit_config.quiet:
    lit_config.note('using clang: %r' % config.clang)

# Plugins (loadable modules)
# TODO: This should be supplied by Makefile or autoconf.
if sys.platform in ['win32', 'cygwin']:
    has_plugins = (config.enable_shared == 1)
else:
    has_plugins = True

if has_plugins and config.llvm_plugin_ext:
    config.available_features.add('plugins')

config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
config.substitutions.append( ('%pluginext', config.llvm_plugin_ext) )
config.substitutions.append( ('%PATH%', config.environment['PATH']) )

if config.clang_examples:
    config.available_features.add('examples')

# Note that when substituting %clang_cc1 also fill in the include directory of
# the builtin headers. Those are part of even a freestanding environment, but
# Clang relies on the driver to locate them.
def getClangBuiltinIncludeDir(clang):
    # FIXME: Rather than just getting the version, we should have clang print
    # out its resource dir here in an easy to scrape form.
    cmd = subprocess.Popen([clang, '-print-file-name=include'],
                           stdout=subprocess.PIPE,
                           env=config.environment)
    if not cmd.stdout:
      lit_config.fatal("Couldn't find the include dir for Clang ('%s')" % clang)
    dir = cmd.stdout.read().strip()
    if sys.platform in ['win32'] and execute_external:
        # Don't pass dosish path separator to msys bash.exe.
        dir = dir.replace('\\', '/')
    # Ensure the result is an ascii string, across Python2.5+ - Python3.
    return str(dir.decode('ascii'))

def makeItaniumABITriple(triple):
    m = re.match(r'(\w+)-(\w+)-(\w+)', triple)
    if not m:
      lit_config.fatal("Could not turn '%s' into Itanium ABI triple" % triple)
    if m.group(3).lower() != 'win32':
      # All non-win32 triples use the Itanium ABI.
      return triple
    return m.group(1) + '-' + m.group(2) + '-mingw32'

def makeMSABITriple(triple):
    m = re.match(r'(\w+)-(\w+)-(\w+)', triple)
    if not m:
      lit_config.fatal("Could not turn '%s' into MS ABI triple" % triple)
    isa = m.group(1).lower()
    vendor = m.group(2).lower()
    os = m.group(3).lower()
    if os == 'win32':
      # If the OS is win32, we're done.
      return triple
    if isa.startswith('x86') or isa == 'amd64' or re.match(r'i\d86', isa): 
      # For x86 ISAs, adjust the OS.
      return isa + '-' + vendor + '-win32'
    # -win32 is not supported for non-x86 targets; use a default.
    return 'i686-pc-win32'

config.substitutions.append( ('%clang_cc1',
                              '%s -cc1 -internal-isystem %s -nostdsysteminc'
                              % (config.clang,
                                 getClangBuiltinIncludeDir(config.clang))) )
config.substitutions.append( ('%clang_cpp', ' ' + config.clang +
                              ' --driver-mode=cpp '))
config.substitutions.append( ('%clang_cl', ' ' + config.clang +
                              ' --driver-mode=cl '))
config.substitutions.append( ('%clangxx', ' ' + config.clang +
                              ' --driver-mode=g++ '))
config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/utils/test_debuginfo.pl ') )
config.substitutions.append( ('%itanium_abi_triple', makeItaniumABITriple(config.target_triple)) )
config.substitutions.append( ('%ms_abi_triple', makeMSABITriple(config.target_triple)) )

# The host triple might not be set, at least if we're compiling clang from
# an already installed llvm.
if config.host_triple and config.host_triple != '@LLVM_HOST_TRIPLE@':
    config.substitutions.append( ('%target_itanium_abi_host_triple', '--target=%s' % makeItaniumABITriple(config.host_triple)) )
else:
    config.substitutions.append( ('%target_itanium_abi_host_triple', '') )

# 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'. ***""") )
config.substitutions.append(
    (' %clang-cc1 ',
     """*** invalid substitution, use '%clang_cc1'. ***""") )
config.substitutions.append(
    (' %clang-cpp ',
     """*** invalid substitution, use '%clang_cpp'. ***""") )
config.substitutions.append(
    (' %clang-cl ',
     """*** invalid substitution, use '%clang_cl'. ***""") )

# For each occurrence of a clang 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.
tool_dirs = os.path.pathsep.join((clang_tools_dir, llvm_tools_dir))

# Regex assertions to reject neighbor hyphens/dots (seen in some tests).
# For example, don't match 'clang-check-' or '.clang-format'.
NoPreHyphenDot = r"(?<!(-|\.))"
NoPostHyphenDot = r"(?!(-|\.))"
NoPostBar = r"(?!(/|\\))"

tool_patterns = [r"\bFileCheck\b",
                 r"\bc-index-test\b",
                 NoPreHyphenDot + r"\bclang-check\b" + NoPostHyphenDot,
                 NoPreHyphenDot + r"\bclang-format\b" + NoPostHyphenDot,
                 # FIXME: Some clang test uses opt?
                 NoPreHyphenDot + r"\bopt\b" + NoPostBar + NoPostHyphenDot,
                 # Handle these specially as they are strings searched
                 # for during testing.
                 r"\| \bcount\b",
                 r"\| \bnot\b"]

if config.clang_examples:
    tool_patterns.append(NoPreHyphenDot + r"\bclang-interpreter\b" + NoPostHyphenDot)

for pattern in tool_patterns:
    # 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.
    tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
                          pattern)
    tool_pipe = tool_match.group(2)
    tool_name = tool_match.group(4)
    tool_path = lit.util.which(tool_name, tool_dirs)
    if not tool_path:
        # Warn, but still provide a substitution.
        lit_config.note('Did not find ' + tool_name + ' in ' + tool_dirs)
        tool_path = clang_tools_dir + '/' + tool_name
    config.substitutions.append((pattern, tool_pipe + tool_path))

###

# Set available features we allow tests to conditionalize on.
#
# Enabled/disabled features
if config.clang_staticanalyzer != 0:
    config.available_features.add("staticanalyzer")

# As of 2011.08, crash-recovery tests still do not pass on FreeBSD.
if platform.system() not in ['FreeBSD']:
    config.available_features.add('crash-recovery')

# Shell execution
if execute_external:
    config.available_features.add('shell')

# For tests that require Darwin to run.
# This is used by debuginfo-tests/*block*.m and debuginfo-tests/foreach.m.
if platform.system() in ['Darwin']:
    config.available_features.add('system-darwin')
elif platform.system() in ['Windows']:
    # For tests that require Windows to run.
    config.available_features.add('system-windows')

# ANSI escape sequences in non-dumb terminal
if platform.system() not in ['Windows']:
    config.available_features.add('ansi-escape-sequences')

# Capability to print utf8 to the terminal.
# Windows expects codepage, unless Wide API.
if platform.system() not in ['Windows']:
    config.available_features.add('utf8-capable-terminal')

# Native compilation: Check if triples match.
# FIXME: Consider cases that target can be executed
# even if host_triple were different from target_triple.
if config.host_triple == config.target_triple:
    config.available_features.add("native")

# Case-insensitive file system
def is_filesystem_case_insensitive():
    handle, path = tempfile.mkstemp(prefix='case-test', dir=config.test_exec_root)
    isInsensitive = os.path.exists(
        os.path.join(
            os.path.dirname(path),
            os.path.basename(path).upper()
            ))
    os.close(handle)
    os.remove(path)
    return isInsensitive

if is_filesystem_case_insensitive():
    config.available_features.add('case-insensitive-filesystem')

# Tests that require the /dev/fd filesystem.
if os.path.exists("/dev/fd/0") and sys.platform not in ['cygwin']:
    config.available_features.add('dev-fd-fs')

# DW2 Target
if not re.match(r'.*-win32$', config.target_triple):
    config.available_features.add('dw2')

# Not set on native MS environment.
if not re.match(r'.*-win32$', config.target_triple):
    config.available_features.add('non-ms-sdk')

# Not set on native PS4 environment.
if not re.match(r'.*-scei-ps4', config.target_triple):
    config.available_features.add('non-ps4-sdk')

# [PR8833] LLP64-incompatible tests
if not re.match(r'^x86_64.*-(win32|mingw32|windows-gnu)$', config.target_triple):
    config.available_features.add('LP64')

# [PR12920] "clang-driver" -- set if gcc driver is not used.
if not re.match(r'.*-(cygwin)$', config.target_triple):
    config.available_features.add('clang-driver')

# [PR18856] Depends to remove opened file. On win32, a file could be removed
# only if all handles were closed.
if platform.system() not in ['Windows']:
    config.available_features.add('can-remove-opened-file')

# Returns set of available features, registered-target(s) and asserts.
def get_llvm_config_props():
    set_of_features = set()

    cmd = subprocess.Popen(
        [
            os.path.join(llvm_tools_dir, 'llvm-config'),
            '--assertion-mode',
            '--targets-built',
            ],
        stdout=subprocess.PIPE,
        env=config.environment
        )
    # 1st line corresponds to --assertion-mode, "ON" or "OFF".
    line = cmd.stdout.readline().strip().decode('ascii')
    if line == "ON":
        set_of_features.add('asserts')

    # 2nd line corresponds to --targets-built, like;
    # AArch64 ARM CppBackend X86
    for arch in cmd.stdout.readline().decode('ascii').split():
        set_of_features.add(arch.lower() + '-registered-target')

    return set_of_features

config.available_features.update(get_llvm_config_props())

if lit.util.which('xmllint'):
    config.available_features.add('xmllint')

# Sanitizers.
if 'Address' in config.llvm_use_sanitizer:
    config.available_features.add("asan")
else:
    config.available_features.add("not_asan")
if 'Memory' in config.llvm_use_sanitizer:
    config.available_features.add("msan")
if 'Undefined' in config.llvm_use_sanitizer:
    config.available_features.add("ubsan")
else:
    config.available_features.add("not_ubsan")

if config.enable_backtrace == "1":
    config.available_features.add("backtrace")

# Check if we should run long running tests.
if lit_config.params.get("run_long_tests", None) == "true":
    config.available_features.add("long_tests")

# Check if we should use gmalloc.
use_gmalloc_str = lit_config.params.get('use_gmalloc', None)
if use_gmalloc_str is not None:
    if use_gmalloc_str.lower() in ('1', 'true'):
        use_gmalloc = True
    elif use_gmalloc_str.lower() in ('', '0', 'false'):
        use_gmalloc = False
    else:
        lit_config.fatal('user parameter use_gmalloc should be 0 or 1')
else:
    # Default to not using gmalloc
    use_gmalloc = False

# Allow use of an explicit path for gmalloc library.
# Will default to '/usr/lib/libgmalloc.dylib' if not set.
gmalloc_path_str = lit_config.params.get('gmalloc_path',
                                         '/usr/lib/libgmalloc.dylib')
if use_gmalloc:
     config.environment.update({'DYLD_INSERT_LIBRARIES' : gmalloc_path_str})

lit.util.usePlatformSdkOnDarwin(config, lit_config)
