#!/usr/bin/env python2.7

"""Check CFC - Check Compile Flow Consistency

This is a compiler wrapper for testing that code generation is consistent with
different compilation processes. It checks that code is not unduly affected by
compiler options or other changes which should not have side effects.

To use:
-Ensure that the compiler under test (i.e. clang, clang++) is on the PATH
-On Linux copy this script to the name of the compiler
   e.g. cp check_cfc.py clang && cp check_cfc.py clang++
-On Windows use setup.py to generate check_cfc.exe and copy that to clang.exe
 and clang++.exe
-Enable the desired checks in check_cfc.cfg (in the same directory as the
 wrapper)
   e.g.
[Checks]
dash_g_no_change = true
dash_s_no_change = false

-The wrapper can be run using its absolute path or added to PATH before the
 compiler under test
   e.g. export PATH=<path to check_cfc>:$PATH
-Compile as normal. The wrapper intercepts normal -c compiles and will return
 non-zero if the check fails.
   e.g.
$ clang -c test.cpp
Code difference detected with -g
--- /tmp/tmp5nv893.o
+++ /tmp/tmp6Vwjnc.o
@@ -1 +1 @@
-   0:       48 8b 05 51 0b 20 00    mov    0x200b51(%rip),%rax
+   0:       48 39 3d 51 0b 20 00    cmp    %rdi,0x200b51(%rip)

-To run LNT with Check CFC specify the absolute path to the wrapper to the --cc
 and --cxx options
   e.g.
   lnt runtest nt --cc <path to check_cfc>/clang \\
           --cxx <path to check_cfc>/clang++ ...

To add a new check:
-Create a new subclass of WrapperCheck
-Implement the perform_check() method. This should perform the alternate compile
 and do the comparison.
-Add the new check to check_cfc.cfg. The check has the same name as the
 subclass.
"""

from __future__ import print_function

import imp
import os
import platform
import shutil
import subprocess
import sys
import tempfile
import ConfigParser
import io

import obj_diff

def is_windows():
    """Returns True if running on Windows."""
    return platform.system() == 'Windows'

class WrapperStepException(Exception):
    """Exception type to be used when a step other than the original compile
    fails."""
    def __init__(self, msg, stdout, stderr):
        self.msg = msg
        self.stdout = stdout
        self.stderr = stderr

class WrapperCheckException(Exception):
    """Exception type to be used when a comparison check fails."""
    def __init__(self, msg):
        self.msg = msg

def main_is_frozen():
    """Returns True when running as a py2exe executable."""
    return (hasattr(sys, "frozen") or # new py2exe
            hasattr(sys, "importers") or # old py2exe
            imp.is_frozen("__main__")) # tools/freeze

def get_main_dir():
    """Get the directory that the script or executable is located in."""
    if main_is_frozen():
        return os.path.dirname(sys.executable)
    return os.path.dirname(sys.argv[0])

def remove_dir_from_path(path_var, directory):
    """Remove the specified directory from path_var, a string representing
    PATH"""
    pathlist = path_var.split(os.pathsep)
    norm_directory = os.path.normpath(os.path.normcase(directory))
    pathlist = filter(lambda x: os.path.normpath(
        os.path.normcase(x)) != norm_directory, pathlist)
    return os.pathsep.join(pathlist)

def path_without_wrapper():
    """Returns the PATH variable modified to remove the path to this program."""
    scriptdir = get_main_dir()
    path = os.environ['PATH']
    return remove_dir_from_path(path, scriptdir)

def flip_dash_g(args):
    """Search for -g in args. If it exists then return args without. If not then
    add it."""
    if '-g' in args:
        # Return args without any -g
        return [x for x in args if x != '-g']
    else:
        # No -g, add one
        return args + ['-g']

def derive_output_file(args):
    """Derive output file from the input file (if just one) or None
    otherwise."""
    infile = get_input_file(args)
    if infile is None:
        return None
    else:
        return '{}.o'.format(os.path.splitext(infile)[0])

def get_output_file(args):
    """Return the output file specified by this command or None if not
    specified."""
    grabnext = False
    for arg in args:
        if grabnext:
            return arg
        if arg == '-o':
            # Specified as a separate arg
            grabnext = True
        elif arg.startswith('-o'):
            # Specified conjoined with -o
            return arg[2:]
    assert grabnext == False

    return None

def is_output_specified(args):
    """Return true is output file is specified in args."""
    return get_output_file(args) is not None

def replace_output_file(args, new_name):
    """Replaces the specified name of an output file with the specified name.
    Assumes that the output file name is specified in the command line args."""
    replaceidx = None
    attached = False
    for idx, val in enumerate(args):
        if val == '-o':
            replaceidx = idx + 1
            attached = False
        elif val.startswith('-o'):
            replaceidx = idx
            attached = True

    if replaceidx is None:
        raise Exception
    replacement = new_name
    if attached == True:
        replacement = '-o' + new_name
    args[replaceidx] = replacement
    return args

def add_output_file(args, output_file):
    """Append an output file to args, presuming not already specified."""
    return args + ['-o', output_file]

def set_output_file(args, output_file):
    """Set the output file within the arguments. Appends or replaces as
    appropriate."""
    if is_output_specified(args):
        args = replace_output_file(args, output_file)
    else:
        args = add_output_file(args, output_file)
    return args

gSrcFileSuffixes = ('.c', '.cpp', '.cxx', '.c++', '.cp', '.cc')

def get_input_file(args):
    """Return the input file string if it can be found (and there is only
    one)."""
    inputFiles = list()
    for arg in args:
        testarg = arg
        quotes = ('"', "'")
        while testarg.endswith(quotes):
            testarg = testarg[:-1]
        testarg = os.path.normcase(testarg)

        # Test if it is a source file
        if testarg.endswith(gSrcFileSuffixes):
            inputFiles.append(arg)
    if len(inputFiles) == 1:
        return inputFiles[0]
    else:
        return None

def set_input_file(args, input_file):
    """Replaces the input file with that specified."""
    infile = get_input_file(args)
    if infile:
        infile_idx = args.index(infile)
        args[infile_idx] = input_file
        return args
    else:
        # Could not find input file
        assert False

def is_normal_compile(args):
    """Check if this is a normal compile which will output an object file rather
    than a preprocess or link. args is a list of command line arguments."""
    compile_step = '-c' in args
    # Bitcode cannot be disassembled in the same way
    bitcode = '-flto' in args or '-emit-llvm' in args
    # Version and help are queries of the compiler and override -c if specified
    query = '--version' in args or '--help' in args
    # Options to output dependency files for make
    dependency = '-M' in args or '-MM' in args
    # Check if the input is recognised as a source file (this may be too
    # strong a restriction)
    input_is_valid = bool(get_input_file(args))
    return compile_step and not bitcode and not query and not dependency and input_is_valid

def run_step(command, my_env, error_on_failure):
    """Runs a step of the compilation. Reports failure as exception."""
    # Need to use shell=True on Windows as Popen won't use PATH otherwise.
    p = subprocess.Popen(command, stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE, env=my_env, shell=is_windows())
    (stdout, stderr) = p.communicate()
    if p.returncode != 0:
        raise WrapperStepException(error_on_failure, stdout, stderr)

def get_temp_file_name(suffix):
    """Get a temporary file name with a particular suffix. Let the caller be
    reponsible for deleting it."""
    tf = tempfile.NamedTemporaryFile(suffix=suffix, delete=False)
    tf.close()
    return tf.name

class WrapperCheck(object):
    """Base class for a check. Subclass this to add a check."""
    def __init__(self, output_file_a):
        """Record the base output file that will be compared against."""
        self._output_file_a = output_file_a

    def perform_check(self, arguments, my_env):
        """Override this to perform the modified compilation and required
        checks."""
        raise NotImplementedError("Please Implement this method")

class dash_g_no_change(WrapperCheck):
    def perform_check(self, arguments, my_env):
        """Check if different code is generated with/without the -g flag."""
        output_file_b = get_temp_file_name('.o')

        alternate_command = list(arguments)
        alternate_command = flip_dash_g(alternate_command)
        alternate_command = set_output_file(alternate_command, output_file_b)
        run_step(alternate_command, my_env, "Error compiling with -g")

        # Compare disassembly (returns first diff if differs)
        difference = obj_diff.compare_object_files(self._output_file_a,
                                                   output_file_b)
        if difference:
            raise WrapperCheckException(
                "Code difference detected with -g\n{}".format(difference))

        # Clean up temp file if comparison okay
        os.remove(output_file_b)

class dash_s_no_change(WrapperCheck):
    def perform_check(self, arguments, my_env):
        """Check if compiling to asm then assembling in separate steps results
        in different code than compiling to object directly."""
        output_file_b = get_temp_file_name('.o')

        alternate_command = arguments + ['-via-file-asm']
        alternate_command = set_output_file(alternate_command, output_file_b)
        run_step(alternate_command, my_env,
                 "Error compiling with -via-file-asm")

        # Compare if object files are exactly the same
        exactly_equal = obj_diff.compare_exact(self._output_file_a, output_file_b)
        if not exactly_equal:
            # Compare disassembly (returns first diff if differs)
            difference = obj_diff.compare_object_files(self._output_file_a,
                                                       output_file_b)
            if difference:
                raise WrapperCheckException(
                    "Code difference detected with -S\n{}".format(difference))

            # Code is identical, compare debug info
            dbgdifference = obj_diff.compare_debug_info(self._output_file_a,
                                                        output_file_b)
            if dbgdifference:
                raise WrapperCheckException(
                    "Debug info difference detected with -S\n{}".format(dbgdifference))

            raise WrapperCheckException("Object files not identical with -S\n")

        # Clean up temp file if comparison okay
        os.remove(output_file_b)

if __name__ == '__main__':
    # Create configuration defaults from list of checks
    default_config = """
[Checks]
"""

    # Find all subclasses of WrapperCheck
    checks = [cls.__name__ for cls in vars()['WrapperCheck'].__subclasses__()]

    for c in checks:
        default_config += "{} = false\n".format(c)

    config = ConfigParser.RawConfigParser()
    config.readfp(io.BytesIO(default_config))
    scriptdir = get_main_dir()
    config_path = os.path.join(scriptdir, 'check_cfc.cfg')
    try:
        config.read(os.path.join(config_path))
    except:
        print("Could not read config from {}, "
              "using defaults.".format(config_path))

    my_env = os.environ.copy()
    my_env['PATH'] = path_without_wrapper()

    arguments_a = list(sys.argv)

    # Prevent infinite loop if called with absolute path.
    arguments_a[0] = os.path.basename(arguments_a[0])

    # Sanity check
    enabled_checks = [check_name
                      for check_name in checks
                      if config.getboolean('Checks', check_name)]
    checks_comma_separated = ', '.join(enabled_checks)
    print("Check CFC, checking: {}".format(checks_comma_separated))

    # A - original compilation
    output_file_orig = get_output_file(arguments_a)
    if output_file_orig is None:
        output_file_orig = derive_output_file(arguments_a)

    p = subprocess.Popen(arguments_a, env=my_env, shell=is_windows())
    p.communicate()
    if p.returncode != 0:
        sys.exit(p.returncode)

    if not is_normal_compile(arguments_a) or output_file_orig is None:
        # Bail out here if we can't apply checks in this case.
        # Does not indicate an error.
        # Maybe not straight compilation (e.g. -S or --version or -flto)
        # or maybe > 1 input files.
        sys.exit(0)

    # Sometimes we generate files which have very long names which can't be
    # read/disassembled. This will exit early if we can't find the file we
    # expected to be output.
    if not os.path.isfile(output_file_orig):
        sys.exit(0)

    # Copy output file to a temp file
    temp_output_file_orig = get_temp_file_name('.o')
    shutil.copyfile(output_file_orig, temp_output_file_orig)

    # Run checks, if they are enabled in config and if they are appropriate for
    # this command line.
    current_module = sys.modules[__name__]
    for check_name in checks:
        if config.getboolean('Checks', check_name):
            class_ = getattr(current_module, check_name)
            checker = class_(temp_output_file_orig)
            try:
                checker.perform_check(arguments_a, my_env)
            except WrapperCheckException as e:
                # Check failure
                print("{} {}".format(get_input_file(arguments_a), e.msg), file=sys.stderr)

                # Remove file to comply with build system expectations (no
                # output file if failed)
                os.remove(output_file_orig)
                sys.exit(1)

            except WrapperStepException as e:
                # Compile step failure
                print(e.msg, file=sys.stderr)
                print("*** stdout ***", file=sys.stderr)
                print(e.stdout, file=sys.stderr)
                print("*** stderr ***", file=sys.stderr)
                print(e.stderr, file=sys.stderr)

                # Remove file to comply with build system expectations (no
                # output file if failed)
                os.remove(output_file_orig)
                sys.exit(1)
