# -*- Python -*-
# Taken from utils/lit/tests in the LLVM tree and hacked together to support
# our tests.
#
# Note: This configuration has simple commands to run Subzero's translator.
# They have the form %X2i (i.e. %p2i, %l2i, and %lc2i) where X is defined
# as follows:
#
#   p : Run Subzero's translator, building ICE from PNaCl bitcode directly.
#   l : Run Subzero's translator, converting the .ll file to a PNaCl bitcode
#       file, reading in the bitcode file and generating LLVM IR, and
#       then convert LLVM IR to ICE IR.
#   lc : Run Subzero's translator, directly parsing the .ll file into LLVM IR,
#        and then convert it to ICE IR.
#
# These commands can be used in RUN lines by FileCheck. If the Subzero
# build being tested lacks any required attributes (e.g., the ability
# to parse .ll files), the command will simply return successfully,
# generating no output. This allows translation tests to be able to
# conditionally test the translator, based on the translator built.
#
# This conditional handling of translation introduces potential problems
# when the output is piped to another command on a RUN line. Executables
# like FileCheck expect non-empty input.
#
# To handle the problem that the pipe is conditional, any command that
# doesn't accept empty input should be prefixed by a corresponding
# %ifX (i.e. %p2i, %ifl, or %ifpc). Note: %p2i should always work, and
# hence %ifp is not necessary (i.e. it is a nop).
#
# If you need to check other build attributes (other than the
# existence of %l2i and %lc2i), you can use the %if command (which is
# a short hand for using pydir/ifatts.py).

import os
import re
import sys

import lit.formats

sys.path.insert(0, 'pydir')
from utils import FindBaseNaCl, shellcmd

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

# testFormat: The test format to use to interpret tests.
config.test_format = lit.formats.ShTest()

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

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

src_root = os.path.join(FindBaseNaCl(), 'toolchain_build/src/subzero')
bin_root = src_root
config.substitutions.append(('%{src_root}', src_root))
config.substitutions.append(('%{python}', sys.executable))

pydir = os.path.join(bin_root, 'pydir')

# Finding LLVM binary tools. All tools used in the tests must be listed in
# the llvmbintools list.
llvmbinpath = os.path.abspath(os.environ.get('LLVM_BIN_PATH'))

# Define the location of the llvm2ice tool.
llvm2icetool = os.path.join(bin_root, 'llvm2ice')
llvm2iceatts = shellcmd(' '.join([llvm2icetool, '--build-atts']),
                        echo=False).split()

# Add build attributes of llvm2ice tool to the set of available features.
config.available_features.update(llvm2iceatts)

def if_cond_flag(Value):
  return '--cond=true' if Value else '--cond=false'

# shell conditional commands.
if_atts = [os.path.join(pydir, 'if.py')]
if_atts_cmd = if_atts + ['--have=' + att for att in llvm2iceatts]
ifl2i_atts_cmd = if_atts + [if_cond_flag('allow_llvm_ir' in llvm2iceatts),
                            '--command']
iflc2i_atts_cmd = if_atts + [if_cond_flag('allow_llvm_ir_as_input'
                                          in llvm2iceatts), '--command']

# Base command for running llvm2ice
llvm2ice_cmd = [os.path.join(pydir, 'run-llvm2ice.py'),
                '--llvm2ice', llvm2icetool,
                '--llvm-bin-path', llvmbinpath]

# Run commands only if corresponding build attributes apply, including
# for each compiler setup.
config.substitutions.append(('%ifp', ' '))
config.substitutions.append(('%iflc', ' '.join(iflc2i_atts_cmd)))
config.substitutions.append(('%ifl', ' '.join(ifl2i_atts_cmd)))
config.substitutions.append(('%if', ' '.join(if_atts_cmd)))

# Translate LLVM source for each compiler setup.
config.substitutions.append(('%p2i', ' '.join(llvm2ice_cmd)))
config.substitutions.append(('%l2i', ' '.join(ifl2i_atts_cmd + llvm2ice_cmd
                                              + ['--llvm'])))
config.substitutions.append(('%lc2i', ' '.join(iflc2i_atts_cmd + llvm2ice_cmd
                                               + ['--llvm-source'])))

config.substitutions.append(('%llvm2ice', llvm2icetool))

llvmbintools = [r"\bFileCheck\b",
                r"\bllvm-as\b",
                r"\bllvm-mc\b",
                r"\bllvm-objdump\b",
                r"\bllvm-readobj\b",
                r"\bnot\b",
                r"\bpnacl-freeze\b",
                r"\bpnacl-bcdis\b"]

for tool in llvmbintools:
  # The re.sub() line is adapted from one of LLVM's lit.cfg files.
  # 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.
  substitution = re.sub(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
                        r"\2" + llvmbinpath + "/" + r"\4",
                        tool)
  config.substitutions.append((tool, substitution))

# Add a feature to detect the Python version.
config.available_features.add("python%d.%d" % (sys.version_info[0],
                                               sys.version_info[1]))

# Debugging output
def dbg(s):
  print '[DBG] %s' % s

dbg('bin_root = %s' % bin_root)
dbg('llvmbinpath = %s' % llvmbinpath)
dbg("Build attributes = %s" % llvm2iceatts)
