# -*- 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 = 'PoolAlloc/DSA'

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

# To ignore test output on stderr so it doesn't trigger failures uncomment this:
#config.test_format = lit.formats.TclTest(ignoreStdErr=True)

# suffixes: A list of file extensions to treat as test files, this is actually
# set by on_clone().
config.suffixes = []

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

# Tweak the PATH to include the scripts dir, the tools dir, and the llvm-gcc bin
# dir (if available).
llvm_obj_root = getattr(config, 'llvm_obj_root', None)
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

    if proj_obj_root is not None:
        path = os.path.pathsep.join((os.path.join(proj_obj_root, 'test', 'tools'),
                                     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]

###

import os

# Check that the object root is known.
if config.test_exec_root is None:
    lit.fatal('Object root unknown!')

    # 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

###

# Provide a command line for mcjit tests
lli_mcjit = 'lli -use-mcjit'
# 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|win32', config.host_triple):
  lli_mcjit += ' -mtriple='+config.host_triple+'-elf'
config.substitutions.append( ('%lli_mcjit', lli_mcjit) )

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

# Provide a substition for those tests that need to run the jit to obtain data
# but simply want use the currently considered most reliable jit for platform
# FIXME: ppc32 is not ready for mcjit.
if 'arm' in config.target_triple \
   or 'aarch64' in config.target_triple \
   or 'powerpc64' in config.target_triple \
   or 's390x' in config.target_triple:
    defaultIsMCJIT = 'true'
else:
    defaultIsMCJIT = 'false'
config.substitutions.append( ('%defaultjit', '-use-mcjit='+defaultIsMCJIT) )

# Process jit implementation option
jit_impl_cfg = lit_config.params.get('jit_impl', None)
if jit_impl_cfg == 'mcjit':
  # When running with mcjit, mangle -mcjit into target triple
  # and add -use-mcjit flag to lli invocation
  if 'i386' in config.target_triple or 'i686' in config.target_triple:
    config.target_triple += jit_impl_cfg + '-ia32'
  elif 'x86_64' in config.target_triple:
    config.target_triple += jit_impl_cfg + '-ia64'
  else:
    config.target_triple += jit_impl_cfg

  config.substitutions.append( ('%lli', 'lli -use-mcjit') )
else:
  config.substitutions.append( ('%lli', 'lli') )

# Add site-specific substitutions.
config.substitutions.append( ('%ocamlopt', config.ocamlopt_executable) )
config.substitutions.append( ('%llvmshlibdir', config.llvm_shlib_dir) )
config.substitutions.append( ('%shlibext', config.llvm_shlib_ext) )

# 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"(?<!\.|-|\^|/)"

for pattern in [r"\bbugpoint\b(?!-)",
                NOJUNK + r"\bclang\b(?!-)",
                NOJUNK + r"\bllc\b",
                r"\blli\b",
                r"\bllvm-PerfectShuffle\b",
                r"\bllvm-ar\b",
                r"\bllvm-as\b",
                r"\bllvm-bcanalyzer\b",
                r"\bllvm-config\b",
                r"\bllvm-cov\b",
                r"\bllvm-diff\b",
                r"\bllvm-dis\b",
                r"\bllvm-dwarfdump\b",
                r"\bllvm-extract\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-tblgen\b",
                r"\bllvm-c-test\b",
                r"\bmacho-dump\b",
                NOJUNK + r"\bopt\b",
                r"\bFileCheck\b",
                r"\bFileUpdate\b",
                r"\bc-index-test\b",
                r"\bfpcmp\b",
                r"\bobj2yaml\b",
                r"\byaml2obj\b",
                # Handle these specially as they are strings searched
                # for during testing.
                r"\| \bcount\b",
                r"\| \bnot\b"]:
    # 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, llvm_tools_dir)
    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))
### Helper tools

dsa_so = config.llvm_shlib_dir + "/LLVMDataStructure" + config.llvm_shlib_ext
adsa_so = config.llvm_shlib_dir + "/AssistDS" + config.llvm_shlib_ext
pa_so = config.llvm_shlib_dir + "/poolalloc" + config.llvm_shlib_ext
config.substitutions.append((r'\bdsaopt\b', 'opt -load ' + dsa_so))
config.substitutions.append((r'\badsaopt\b', 'opt -load ' + dsa_so
                                              + ' -load ' + adsa_so))
config.substitutions.append((r'\bpaopt\b', 'opt -load ' + dsa_so
                                              + ' -load ' + pa_so))

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

# Direct object generation
if not 'hexagon' in config.target_triple and \
   not re.match('(arm|thumb).*windows', 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")

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

# Ask llvm-config about assertion mode.
import subprocess
try:
    llvm_config_cmd = subprocess.Popen(
        [os.path.join(llvm_tools_dir, 'llvm-config'), '--assertion-mode'],
        stdout = subprocess.PIPE)
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()

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