# -*- Python -*- vim: set ft=python ts=4 sw=4 expandtab tw=79:
# Configuration file for the 'lit' test runner.

import os
import re
import subprocess
import lit.formats

# Tell pylint that we know config and lit_config exist somewhere.
if 'PYLINT_IMPORT' in os.environ:
    config = object()
    lit_config = object()

def append_dynamic_library_path(path):
    if config.operating_system == 'Windows':
        name = 'PATH'
        sep = ';'
    elif config.operating_system == 'Darwin':
        name = 'DYLD_LIBRARY_PATH'
        sep = ':'
    else:
        name = 'LD_LIBRARY_PATH'
        sep = ':'
    if name in config.environment:
        config.environment[name] = path + sep + config.environment[name]
    else:
        config.environment[name] = path

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

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

# test_source_root: The root path where tests are located.
config.test_source_root = os.path.dirname(__file__)

# test_exec_root: The root object directory where output is placed
config.test_exec_root = config.test_obj_root

# test format
config.test_format = lit.formats.ShTest()

# compiler flags
config.test_flags = " -I " + config.test_source_root + "/.."\
    " -I " + config.omp_header_dir + \
    " -L " + config.omp_library_dir + \
    " -I " + config.ompt_print_callback_dir + \
    " -Wl,-rpath," + config.omp_library_dir + \
    " " + config.test_openmp_flags + \
    " " + config.test_extra_flags

# to run with icc INTEL_LICENSE_FILE must be set
if 'INTEL_LICENSE_FILE' in os.environ:
    config.environment['INTEL_LICENSE_FILE'] = os.environ['INTEL_LICENSE_FILE']

# Allow XFAIL to work
config.target_triple = [ ]
for feature in config.test_compiler_features:
    config.available_features.add(feature)

# Setup environment to find dynamic library at runtime
append_dynamic_library_path(config.omp_library_dir)
append_dynamic_library_path(config.test_obj_root+"/..")

# Rpath modifications for Darwin
if config.operating_system == 'Darwin':
    config.test_flags += " -Wl,-rpath," + config.omp_library_dir

# Find the SDK on Darwin
if config.operating_system == 'Darwin':
  cmd = subprocess.Popen(['xcrun', '--show-sdk-path'],
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  out, err = cmd.communicate()
  out = out.strip()
  res = cmd.wait()
  if res == 0 and out:
    config.test_flags += " -isysroot " + out

if 'Linux' in config.operating_system:
    config.available_features.add("linux")

# substitutions
config.substitutions.append(("FileCheck", "tee %%t.out | %s" % config.test_filecheck))
config.substitutions.append(("%sort-threads", "sort --numeric-sort --stable"))

config.substitutions.append(("%libomp-compile-and-run", \
    "%libomp-compile && %libomp-run"))
config.substitutions.append(("%libomp-compile", \
    "%clang %cflags %s -o %t"))
config.substitutions.append(("%libomp-tool", \
    "%clang %cflags -shared -fPIC -g"))
config.substitutions.append(("%libomp-run", "%t"))
config.substitutions.append(("%clang", config.test_c_compiler))
config.substitutions.append(("%openmp_flag", config.test_openmp_flags))
config.substitutions.append(("%cflags", config.test_flags))

