# -*- Python -*-

# Configuration file for the 'lit' test runner.

import os
import sys
import re
import platform

import lit.util
import lit.formats

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

# Tweak PATH for Win32 to decide to use bash.exe or not.
if sys.platform in ['win32']:
    # 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.
config.test_format = lit.formats.ShTest(execute_external)

# suffixes: A list of file extensions to treat as test files. This is overriden
# by individual lit.local.cfg files in the test subdirectories.
config.suffixes = ['.ll', '.c', '.cxx', '.test', '.txt', '.s']

# 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.
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 tools dir.
if llvm_obj_root is not None:
    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((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',
                                                  '')

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

# Set up OCAMLPATH to include newly built OCaml libraries.
llvm_lib_dir = getattr(config, 'llvm_lib_dir', None)
if llvm_lib_dir is None:
    if llvm_obj_root is not None:
        llvm_lib_dir = os.path.join(llvm_obj_root, 'lib')

if llvm_lib_dir is not None:
    llvm_ocaml_lib = os.path.join(llvm_lib_dir, 'ocaml')
    if llvm_ocaml_lib is not None:
        if 'OCAMLPATH' in os.environ:
            ocamlpath = os.path.pathsep.join((llvm_ocaml_lib, os.environ['OCAMLPATH']))
            config.environment['OCAMLPATH'] = ocamlpath
        else:
            config.environment['OCAMLPATH'] = llvm_ocaml_lib

        if 'CAML_LD_LIBRARY_PATH' in os.environ:
            caml_ld_library_path = os.path.pathsep.join((llvm_ocaml_lib,
                                        os.environ['CAML_LD_LIBRARY_PATH']))
            config.environment['CAML_LD_LIBRARY_PATH'] = caml_ld_library_path
        else:
            config.environment['CAML_LD_LIBRARY_PATH'] = llvm_ocaml_lib

# Set up OCAMLRUNPARAM to enable backtraces in OCaml tests.
config.environment['OCAMLRUNPARAM'] = 'b'

###

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_config.params.get('llvm_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.

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

    # 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_config.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_config.fatal('No site specific configuration available!')

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

###

lli = 'lli'
# The target triple used by default by lli is the process target triple (some
# triple appropriate for generating code for the current process) but because
# we don't support COFF in MCJIT well enough for the tests, force ELF format on
# Windows.  FIXME: the process target triple should be used here, but this is
# difficult to obtain on Windows.
if re.search(r'cygwin|mingw32|windows-gnu|windows-msvc|win32', config.host_triple):
  lli += ' -mtriple='+config.host_triple+'-elf'
config.substitutions.append( ('%lli', lli ) )

# Similarly, have a macro to use llc with DWARF even when the host is win32.
llc_dwarf = 'llc'
if re.search(r'win32', config.target_triple):
  llc_dwarf += ' -mtriple='+config.target_triple.replace('-win32', '-mingw32')
config.substitutions.append( ('%llc_dwarf', llc_dwarf) )

# Add site-specific substitutions.
config.substitutions.append( ('%gold', config.gold_executable) )
config.substitutions.append( ('%ld64', config.ld64_executable) )
config.substitutions.append( ('%go', config.go_executable) )
config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
config.substitutions.append( ('%shlibext', config.llvm_shlib_ext) )
config.substitutions.append( ('%exeext', config.llvm_exe_ext) )
config.substitutions.append( ('%python', config.python_executable) )
config.substitutions.append( ('%host_cc', config.host_cc) )

# OCaml substitutions.
# Support tests for both native and bytecode builds.
config.substitutions.append( ('%ocamlc',
    "%s ocamlc -cclib -L%s %s" %
        (config.ocamlfind_executable, llvm_lib_dir, config.ocaml_flags)) )
if config.have_ocamlopt in ('1', 'TRUE'):
    config.substitutions.append( ('%ocamlopt',
        "%s ocamlopt -cclib -L%s -cclib -Wl,-rpath,%s %s" %
            (config.ocamlfind_executable, llvm_lib_dir, llvm_lib_dir, config.ocaml_flags)) )
else:
    config.substitutions.append( ('%ocamlopt', "true" ) )

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

# Avoid matching RUN line fragments that are actually part of
# path names or options or whatever.
# The regex is a pre-assertion to avoid matching a preceding
# dot, hyphen, carat, or slash (.foo, -foo, etc.).  Some patterns
# also have a post-assertion to not match a trailing hyphen (foo-).
NOJUNK = r"(?<!\.|-|\^|/)"


def find_tool_substitution(pattern):
    # 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)
    # Did the user specify the tool path + arguments? This allows things like
    # llvm-lit "-Dllc=llc -enable-misched -verify-machineinstrs"
    tool_path = lit_config.params.get(tool_name)
    if tool_path is None:
        tool_path = lit.util.which(tool_name, llvm_tools_dir)
        if tool_path is None:
            return tool_name, tool_path, tool_pipe
    if (tool_name == "llc" and
       'LLVM_ENABLE_MACHINE_VERIFIER' in os.environ and
       os.environ['LLVM_ENABLE_MACHINE_VERIFIER'] == "1"):
        tool_path += " -verify-machineinstrs"
    if (tool_name == "llvm-go"):
        tool_path += " go=" + config.go_executable
    return tool_name, tool_path, tool_pipe


for pattern in [r"\bbugpoint\b(?!-)",
                NOJUNK + r"\bllc\b",
                r"\blli\b",
                r"\bllvm-ar\b",
                r"\bllvm-as\b",
                r"\bllvm-bcanalyzer\b",
                r"\bllvm-config\b",
                r"\bllvm-cov\b",
                r"\bllvm-cxxdump\b",
                r"\bllvm-diff\b",
                r"\bllvm-dis\b",
                r"\bllvm-dsymutil\b",
                r"\bllvm-dwarfdump\b",
                r"\bllvm-extract\b",
                r"\bllvm-lib\b",
                r"\bllvm-link\b",
                r"\bllvm-lto\b",
                r"\bllvm-mc\b",
                r"\bllvm-mcmarkup\b",
                r"\bllvm-nm\b",
                r"\bllvm-objdump\b",
                r"\bllvm-profdata\b",
                r"\bllvm-ranlib\b",
                r"\bllvm-readobj\b",
                r"\bllvm-rtdyld\b",
                r"\bllvm-size\b",
                r"\bllvm-split\b",
                r"\bllvm-tblgen\b",
                r"\bllvm-c-test\b",
                NOJUNK + r"\bllvm-symbolizer\b",
                NOJUNK + r"\bopt\b",
                r"\bFileCheck\b",
                r"\bobj2yaml\b",
                NOJUNK + r"\bsancov\b",
                r"\byaml2obj\b",
                r"\byaml-bench\b",
                r"\bverify-uselistorder\b",
                # Handle these specially as they are strings searched
                # for during testing.
                r"\| \bcount\b",
                r"\| \bnot\b"]:
    tool_name, tool_path, tool_pipe = find_tool_substitution(pattern)
    if not tool_path:
        # Warn, but still provide a substitution.
        lit_config.note('Did not find ' + tool_name + ' in ' + llvm_tools_dir)
        tool_path = llvm_tools_dir + '/' + tool_name
    config.substitutions.append((pattern, tool_pipe + tool_path))

# For tools that are optional depending on the config, we won't warn
# if they're missing.
for pattern in [r"\bllvm-go\b",
                r"\bKaleidoscope-Ch3\b",
                r"\bKaleidoscope-Ch4\b",
                r"\bKaleidoscope-Ch5\b",
                r"\bKaleidoscope-Ch6\b",
                r"\bKaleidoscope-Ch7\b",
                r"\bKaleidoscope-Ch8\b"]:
    tool_name, tool_path, tool_pipe = find_tool_substitution(pattern)
    if not tool_path:
        # Provide a substitution anyway, for the sake of consistent errors.
        tool_path = llvm_tools_dir + '/' + tool_name
    config.substitutions.append((pattern, tool_pipe + tool_path))


### Targets

config.targets = frozenset(config.targets_to_build.split())

### Features

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

# Others/can-execute.txt
if sys.platform not in ['win32']:
    config.available_features.add('can-execute')

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

# Sanitizers.
if config.llvm_use_sanitizer == "Address":
    config.available_features.add("asan")
if (config.llvm_use_sanitizer == "Memory" or
        config.llvm_use_sanitizer == "MemoryWithOrigins"):
    config.available_features.add("msan")
else:
    config.available_features.add("not_msan")
if config.llvm_use_sanitizer == "Undefined":
    config.available_features.add("ubsan")
else:
    config.available_features.add("not_ubsan")

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

# Direct object generation
if not 'hexagon' in config.target_triple:
    config.available_features.add("object-emission")

if config.have_zlib == "1":
    config.available_features.add("zlib")
else:
    config.available_features.add("nozlib")

# LLVM can be configured with an empty default triple
# Some tests are "generic" and require a valid default triple
if config.target_triple:
    config.available_features.add("default_triple")
    if re.match(r'^x86_64.*-linux', config.target_triple):
      config.available_features.add("x86_64-linux")

# Native compilation: host arch == default triple arch
# 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")

import subprocess

def have_ld_plugin_support():
    if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')):
        return False

    ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE, env={'LANG': 'C'})
    ld_out = ld_cmd.stdout.read().decode()
    ld_cmd.wait()

    if not '-plugin' in ld_out:
        return False

    # check that the used emulations are supported.
    emu_line = [l for l in ld_out.split('\n') if 'supported emulations' in l]
    if len(emu_line) != 1:
        return False
    emu_line = emu_line[0]
    fields = emu_line.split(':')
    if len(fields) != 3:
        return False
    emulations = fields[2].split()
    if 'elf_x86_64' not in emulations:
        return False
    if 'elf32ppc' in emulations:
        config.available_features.add('ld_emu_elf32ppc')

    ld_version = subprocess.Popen([config.gold_executable, '--version'], stdout = subprocess.PIPE, env={'LANG': 'C'})
    if not 'GNU gold' in ld_version.stdout.read().decode():
        return False
    ld_version.wait()

    return True

if have_ld_plugin_support():
    config.available_features.add('ld_plugin')

def have_ld64_plugin_support():
    if config.ld64_executable == '':
        return False

    ld_cmd = subprocess.Popen([config.ld64_executable, '-v'], stderr = subprocess.PIPE)
    ld_out = ld_cmd.stderr.read().decode()
    ld_cmd.wait()

    if 'ld64' not in ld_out or 'LTO' not in ld_out:
        return False

    return True

if have_ld64_plugin_support():
    config.available_features.add('ld64_plugin')

# Ask llvm-config about assertion mode.
try:
    llvm_config_cmd = subprocess.Popen(
        [os.path.join(llvm_tools_dir, 'llvm-config'), '--assertion-mode'],
        stdout = subprocess.PIPE,
        env=config.environment)
except OSError:
    print("Could not find llvm-config in " + llvm_tools_dir)
    exit(42)

if re.search(r'ON', llvm_config_cmd.stdout.read().decode('ascii')):
    config.available_features.add('asserts')
llvm_config_cmd.wait()

if 'darwin' == sys.platform:
    try:
        sysctl_cmd = subprocess.Popen(['sysctl', 'hw.optional.fma'],
                                    stdout = subprocess.PIPE)
    except OSError:
        print("Could not exec sysctl")
    result = sysctl_cmd.stdout.read().decode('ascii')
    if -1 != result.find("hw.optional.fma: 1"):
        config.available_features.add('fma3')
    sysctl_cmd.wait()

if platform.system() in ['Windows'] and re.match(r'.*-win32$', config.target_triple):
    # For tests that require Windows to run.
    config.available_features.add('system-windows')

# .debug_frame is not emitted for targeting Windows x64.
if not re.match(r'^x86_64.*-(mingw32|windows-gnu|win32)', config.target_triple):
    config.available_features.add('debug_frame')

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