# -*- 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. Tools used in the tests must be listed in
# the llvmbintools list or binutilsbintools.
llvmbinpath = os.path.abspath(os.environ.get('LLVM_BIN_PATH'))

# Find binutils tools. This is used for objdump.
binutilsbinpath = os.path.abspath(os.environ.get('BINUTILS_BIN_PATH'))

# Define the location of the pnacl-sz tool.
pnacl_sz_tool = os.path.join(bin_root, 'pnacl-sz')
pnacl_sz_atts = shellcmd(' '.join([pnacl_sz_tool, '--build-atts']),
                        echo=False).split()

# Add build attributes of pnacl-sz tool to the set of available features.
config.available_features.update(pnacl_sz_atts)

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 pnacl_sz_atts]
ifl2i_atts_cmd = if_atts + [if_cond_flag('allow_llvm_ir' in pnacl_sz_atts),
                            '--command']
iflc2i_atts_cmd = if_atts + [if_cond_flag('allow_llvm_ir_as_input'
                                          in pnacl_sz_atts), '--command']

# Base command for running pnacl-sz
pnacl_sz_cmd = [os.path.join(pydir, 'run-pnacl-sz.py'),
                '--pnacl-sz', pnacl_sz_tool,
                '--llvm-bin-path', llvmbinpath,
                '--binutils-bin-path', binutilsbinpath]

# 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(pnacl_sz_cmd)))
config.substitutions.append(('%l2i', ' '.join(ifl2i_atts_cmd + pnacl_sz_cmd
                                              + ['--llvm'])))
config.substitutions.append(('%lc2i', ' '.join(iflc2i_atts_cmd + pnacl_sz_cmd
                                               + ['--llvm-source'])))

config.substitutions.append(('%pnacl_sz', pnacl_sz_tool))

llvmbintools = [r"\bFileCheck\b",
                r"\bllvm-as\b",
                r"\bllvm-mc\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))

binutilsbintools = [r"\ble32-nacl-objdump\b",]

for tool in binutilsbintools:
  # The re.sub() line is adapted from one of LLVM's lit.cfg files.
  # Similar to the llvmbintools.
  substitution = re.sub(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_]+)\\b\W*$",
                        r"\2" + binutilsbinpath + "/" + 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('binutilsbinpath = %s' % binutilsbinpath)
dbg("Build attributes = %s" % pnacl_sz_atts)
