# Copyright 2002-2005 Vladimir Prus.
# Copyright 2002-2003 Dave Abrahams.
# Copyright 2006 Rene Rivera.
# Distributed under the Boost Software License, Version 1.0.
#    (See accompanying file LICENSE_1_0.txt or copy at
#         http://www.boost.org/LICENSE_1_0.txt)

import TestCmd
import copy
import fnmatch
import glob
import math
import os
import re
import shutil
import string
import StringIO
import sys
import tempfile
import time
import traceback
import tree
import types

from xml.sax.saxutils import escape


annotations = []


def print_annotation(name, value, xml):
    """Writes some named bits of information about test run.
    """
    if xml:      
        print escape(name) + " {{{"
        print escape(value)
        print "}}}"
    else:
        print name + " {{{"
        print value
        print "}}}"
        
def flush_annotations(xml=0):
    global annotations
    for ann in annotations:
        print_annotation(ann[0], ann[1], xml)
    annotations = []


defer_annotations = 0


def set_defer_annotations(n):
    global defer_annotations
    defer_annotations = n


def annotation(name, value):
    """Records an annotation about the test run.
    """
    annotations.append((name, value))
    if not defer_annotations:
        flush_annotations()


def get_toolset():
    toolset = None;
    for arg in sys.argv[1:]:
        if not arg.startswith('-'):
            toolset = arg
    return toolset or 'gcc'


# Detect the host OS.
windows = False
if os.environ.get('OS', '').lower().startswith('windows') or \
       os.__dict__.has_key('uname') and \
       os.uname()[0].lower().startswith('cygwin'):
    windows = True


suffixes = {}


# Prepare the map of suffixes
def prepare_suffix_map(toolset):
    global windows
    global suffixes
    suffixes = {'.exe': '', '.dll': '.so', '.lib': '.a', '.obj': '.o'}
    suffixes['.implib'] = '.no_implib_files_on_this_platform'
    if windows:
        suffixes = {}
        if toolset in ["gcc"]:
            suffixes['.lib'] = '.a' # static libs have '.a' suffix with mingw...
            suffixes['.obj'] = '.o'
        suffixes['.implib'] = '.lib'
    if os.__dict__.has_key('uname') and (os.uname()[0] == 'Darwin'):
        suffixes['.dll'] = '.dylib'


def re_remove(sequence, regex):
    me = re.compile(regex)
    result = filter(lambda x: me.match(x), sequence)
    if 0 == len(result):
        raise ValueError()
    for r in result:
        sequence.remove(r)


def glob_remove(sequence, pattern):
    result = fnmatch.filter(sequence, pattern)
    if 0 == len(result):
        raise ValueError()
    for r in result:
        sequence.remove(r)


# Configuration stating whether Boost Build is expected to automatically prepend
# prefixes to built library targets.
lib_prefix = True
dll_prefix = True
if windows:
    dll_prefix = False


#
# FIXME: this is copy-pasted from TestSCons.py
# Should be moved to TestCmd.py?
#
if os.name == 'posix':
    def _failed(self, status=0):
        if self.status is None:
            return None
        return _status(self) != status
    def _status(self):
        if os.WIFEXITED(self.status):
            return os.WEXITSTATUS(self.status)
        else:
            return -1
elif os.name == 'nt':
    def _failed(self, status=0):
        return not self.status is None and self.status != status
    def _status(self):
        return self.status


class Tester(TestCmd.TestCmd):
    """Main tester class for Boost Build.

    Optional arguments:

    `arguments`                   - Arguments passed to the run executable.
    `executable`                  - Name of the executable to invoke.
    `match`                       - Function to use for compating actual and
                                    expected file contents.
    `boost_build_path`            - Boost build path to be passed to the run
                                    executable.
    `translate_suffixes`          - Whether to update suffixes on the the file
                                    names passed from the test script so they
                                    match those actually created by the current
                                    toolset. For example, static library files
                                    are specified by using the .lib suffix but
                                    when the 'gcc' toolset is used it actually
                                    creates them using the .a suffix.
    `pass_toolset`                - Whether the test system should pass the
                                    specified toolset to the run executable.
    `use_test_config`             - Whether the test system should tell the run
                                    executable to read in the test_config.jam
                                    configuration file.
    `ignore_toolset_requirements` - Whether the test system should tell the run
                                    executable to ignore toolset requirements.
    `workdir`                     - indicates an absolute directory where the
                                    test will be run from.

    Optional arguments inherited from the base class:

    `description`                 - Test description string displayed in case of
                                    a failed test.
    `subdir'                      - List of subdirectories to automatically
                                    create under the working directory. Each
                                    subdirectory needs to be specified
                                    separately parent coming before its child.
    `verbose`                     - Flag that may be used to enable more verbose
                                    test system output. Note that it does not
                                    also enable more verbose build system
                                    output like the --verbose command line
                                    option does.
    """
    def __init__(self, arguments="", executable="bjam",
        match=TestCmd.match_exact, boost_build_path=None,
        translate_suffixes=True, pass_toolset=True, use_test_config=True,
        ignore_toolset_requirements=True, workdir="", **keywords):

        self.original_workdir = os.getcwd()
        if workdir != '' and not os.path.isabs(workdir):
            raise "Parameter workdir <"+workdir+"> must point to an absolute directory: "

        self.last_build_time_start = 0
        self.last_build_time_finish = 0
        self.translate_suffixes = translate_suffixes
        self.use_test_config = use_test_config

        self.toolset = get_toolset()
        self.pass_toolset = pass_toolset
        self.ignore_toolset_requirements = ignore_toolset_requirements

        prepare_suffix_map(pass_toolset and self.toolset or 'gcc')

        if not '--default-bjam' in sys.argv:
            jam_build_dir = ""
            if os.name == 'nt':
                jam_build_dir = "bin.ntx86"
            elif (os.name == 'posix') and os.__dict__.has_key('uname'):
                if os.uname()[0].lower().startswith('cygwin'):
                    jam_build_dir = "bin.cygwinx86"
                    if 'TMP' in os.environ and os.environ['TMP'].find('~') != -1:
                        print 'Setting $TMP to /tmp to get around problem with short path names'
                        os.environ['TMP'] = '/tmp'
                elif os.uname()[0] == 'Linux':
                    cpu = os.uname()[4]
                    if re.match("i.86", cpu):
                        jam_build_dir = "bin.linuxx86";
                    else:
                        jam_build_dir = "bin.linux" + os.uname()[4]
                elif os.uname()[0] == 'SunOS':
                    jam_build_dir = "bin.solaris"
                elif os.uname()[0] == 'Darwin':
                    if os.uname()[4] == 'i386':
                        jam_build_dir = "bin.macosxx86"
                    else:
                        jam_build_dir = "bin.macosxppc"
                elif os.uname()[0] == "AIX":
                    jam_build_dir = "bin.aix"
                elif os.uname()[0] == "IRIX64":
                    jam_build_dir = "bin.irix"
                elif os.uname()[0] == "FreeBSD":
                    jam_build_dir = "bin.freebsd"
                elif os.uname()[0] == "OSF1":
                    jam_build_dir = "bin.osf"
                else:
                    raise "Don't know directory where Jam is built for this system: " + os.name + "/" + os.uname()[0]
            else:
                raise "Don't know directory where Jam is built for this system: " + os.name

            # Find where jam_src is located. Try for the debug version if it is
            # lying around.
            dirs = [os.path.join('../engine/src', jam_build_dir + '.debug'),
                    os.path.join('../engine/src', jam_build_dir),
                    os.path.join('../../jam_src', jam_build_dir + '.debug'),
                    os.path.join('../../jam_src', jam_build_dir),
                    os.path.join('../jam_src', jam_build_dir + '.debug'),
                    os.path.join('../jam_src', jam_build_dir)]
            for d in dirs:
                if os.path.exists(d):
                    jam_build_dir = d
                    break
            else:
                print "Cannot find built Boost.Jam"
                sys.exit(1)

        verbosity = ['-d0', '--quiet']
        if '--verbose' in sys.argv:
            keywords['verbose'] = True
            verbosity = ['-d+2']

        if boost_build_path is None:
            boost_build_path = self.original_workdir

        program_list = []

        if '--default-bjam' in sys.argv:
            program_list.append(executable)
            inpath_bjam = True
        else:
            program_list.append(os.path.join(jam_build_dir, executable))
            inpath_bjam = None
        program_list.append('-sBOOST_BUILD_PATH="' + boost_build_path + '"')
        if verbosity:
            program_list += verbosity
        if arguments:
            program_list += arguments.split(" ")

        TestCmd.TestCmd.__init__(
            self
            , program=program_list
            , match=match
            , workdir=workdir
            , inpath=inpath_bjam
            , **keywords)

        os.chdir(self.workdir)

    def cleanup(self):
        try:
            TestCmd.TestCmd.cleanup(self)
            os.chdir(self.original_workdir)
        except AttributeError:
            # When this is called during TestCmd.TestCmd.__del__ we can have
            # both 'TestCmd' and 'os' unavailable in our scope. Do nothing in
            # this case.
            pass

    #
    # Methods that change the working directory's content.
    #
    def set_tree(self, tree_location):
        # It is not possible to remove the current directory.
        d = os.getcwd()
        os.chdir(os.path.dirname(self.workdir))
        shutil.rmtree(self.workdir, ignore_errors=False)

        if not os.path.isabs(tree_location):
            tree_location = os.path.join(self.original_workdir, tree_location)
        shutil.copytree(tree_location, self.workdir)

        os.chdir(d)

        def make_writable(unused, dir, entries):
            for e in entries:
                name = os.path.join(dir, e)
                os.chmod(name, os.stat(name)[0] | 0222)

        os.path.walk(".", make_writable, None)

    def write(self, file, content):
        self.wait_for_time_change_since_last_build()
        nfile = self.native_file_name(file)
        try:
            os.makedirs(os.path.dirname(nfile))
        except Exception, e:
            pass
        open(nfile, "wb").write(content)

    def rename(self, old, new):
        try:
            os.makedirs(os.path.dirname(new))
        except:
            pass

        try:
            os.remove(new)
        except:
            pass

        os.rename(old, new)
        self.touch(new);

    def copy(self, src, dst):
        self.wait_for_time_change_since_last_build()
        try:
            self.write(dst, self.read(src, 1))
        except:
            self.fail_test(1)

    def copy_preserving_timestamp(self, src, dst):
        src_name = self.native_file_name(src)
        dst_name = self.native_file_name(dst)
        stats = os.stat(src_name)
        self.write(dst, self.read(src, 1))
        os.utime(dst_name, (stats.st_atime, stats.st_mtime))

    def touch(self, names):
        self.wait_for_time_change_since_last_build()
        for name in self.adjust_names(names):
            os.utime(self.native_file_name(name), None)

    def rm(self, names):
        self.wait_for_time_change_since_last_build()
        if not type(names) == types.ListType:
            names = [names]

        # Avoid attempts to remove the current directory.
        os.chdir(self.original_workdir)
        for name in names:
            n = self.native_file_name(name)
            n = glob.glob(n)
            if n: n = n[0]
            if not n:
                n = self.glob_file(string.replace(name, "$toolset", self.toolset+"*"))
            if n:
                if os.path.isdir(n):
                    shutil.rmtree(n, ignore_errors=False)
                else:
                    os.unlink(n)

        # Create working dir root again in case we removed it.
        if not os.path.exists(self.workdir):
            os.mkdir(self.workdir)
        os.chdir(self.workdir)

    def expand_toolset(self, name):
        """Expands $toolset in the given file to tested toolset.
        """
        content = self.read(name)
        content = string.replace(content, "$toolset", self.toolset)
        self.write(name, content)

    def dump_stdio(self):
        annotation("STDOUT", self.stdout())
        annotation("STDERR", self.stderr())

    #
    #   FIXME: Large portion copied from TestSCons.py, should be moved?
    #
    def run_build_system(self, extra_args="", subdir="", stdout=None, stderr="",
        status=0, match=None, pass_toolset=None, use_test_config=None,
        ignore_toolset_requirements=None, expected_duration=None, **kw):

        self.last_build_time_start = time.time()

        try:
            if os.path.isabs(subdir):
                if stderr:
                    print "You must pass a relative directory to subdir <"+subdir+">."
                status = 1
                return

            self.previous_tree = tree.build_tree(self.workdir)

            if match is None:
                match = self.match

            if pass_toolset is None:
                pass_toolset = self.pass_toolset

            if use_test_config is None:
                use_test_config = self.use_test_config

            if ignore_toolset_requirements is None:
                ignore_toolset_requirements = self.ignore_toolset_requirements

            try:
                kw['program'] = []
                kw['program'] += self.program
                if extra_args:
                    kw['program'] += extra_args.split(" ")
                if pass_toolset:
                    kw['program'].append("toolset=" + self.toolset)
                if use_test_config:
                    kw['program'].append('--test-config="%s"'
                        % os.path.join(self.original_workdir, "test-config.jam"))
                if ignore_toolset_requirements:
                    kw['program'].append("--ignore-toolset-requirements")
                kw['chdir'] = subdir
                apply(TestCmd.TestCmd.run, [self], kw)
            except:
                self.dump_stdio()
                raise
        finally:
            self.last_build_time_finish = time.time()

        if (status != None) and _failed(self, status):
            expect = ''
            if status != 0:
                expect = " (expected %d)" % status

            annotation("failure", '"%s" returned %d%s'
                % (kw['program'], _status(self), expect))
            
            annotation("reason", "unexpected status returned by bjam")
            self.fail_test(1)

        if not (stdout is None) and not match(self.stdout(), stdout):
            annotation("failure", "Unexpected stdout")
            annotation("Expected STDOUT", stdout)
            annotation("Actual STDOUT", self.stdout())
            stderr = self.stderr()
            if stderr:
                annotation("STDERR", stderr)
            self.maybe_do_diff(self.stdout(), stdout)
            self.fail_test(1, dump_stdio=False)

        # Intel tends to produce some messages to stderr which make tests fail.
        intel_workaround = re.compile("^xi(link|lib): executing.*\n", re.M)
        actual_stderr = re.sub(intel_workaround, "", self.stderr())

        if not (stderr is None) and not match(actual_stderr, stderr):
            annotation("failure", "Unexpected stderr")
            annotation("Expected STDERR", stderr)
            annotation("Actual STDERR", self.stderr())
            annotation("STDOUT", self.stdout())
            self.maybe_do_diff(actual_stderr, stderr)
            self.fail_test(1, dump_stdio=False)

        if not expected_duration is None:
            actual_duration = self.last_build_time_finish - self.last_build_time_start 
            if (actual_duration > expected_duration):
                print "Test run lasted %f seconds while it was expected to " \
                    "finish in under %f seconds." % (actual_duration,
                    expected_duration)
                self.fail_test(1, dump_stdio=False)

        self.tree = tree.build_tree(self.workdir)
        self.difference = tree.trees_difference(self.previous_tree, self.tree)
        self.difference.ignore_directories()
        self.unexpected_difference = copy.deepcopy(self.difference)

    def glob_file(self, name):
        result = None
        if hasattr(self, 'difference'):
            for f in self.difference.added_files+self.difference.modified_files+self.difference.touched_files:
                if fnmatch.fnmatch(f, name):
                    result = self.native_file_name(f)
                    break
        if not result:
            result = glob.glob(self.native_file_name(name))
            if result:
                result = result[0]
        return result

    def read(self, name, binary=False):
        try:
            if self.toolset:
                name = string.replace(name, "$toolset", self.toolset+"*")
            name = self.glob_file(name)
            openMode = "r"
            if binary:
                openMode += "b"
            else:
                openMode += "U"
            return open(name, openMode).read()
        except:
            annotation("failure", "Could not open '%s'" % name)
            self.fail_test(1)
            return ''

    def read_and_strip(self, name):
        lines = open(self.glob_file(name), "rb").readlines()
        result = string.join(map(string.rstrip, lines), "\n")
        if lines and lines[-1][-1] == '\n':
            return result + '\n'
        else:
            return result

    def fail_test(self, condition, dump_stdio=True, *args):
        if not condition:
            return

        if hasattr(self, 'difference'):
            f = StringIO.StringIO()
            self.difference.pprint(f)
            annotation("changes caused by the last build command", f.getvalue())

        if dump_stdio:
            self.dump_stdio()

        if '--preserve' in sys.argv:
            print
            print "*** Copying the state of working dir into 'failed_test' ***"
            print
            path = os.path.join(self.original_workdir, "failed_test")
            if os.path.isdir(path):
                shutil.rmtree(path, ignore_errors=False)
            elif os.path.exists(path):
                raise "Path " + path + " already exists and is not a directory";
            shutil.copytree(self.workdir, path)

        at = TestCmd.caller(traceback.extract_stack(), 0)
        annotation("stacktrace", at)
        sys.exit(1)

    # A number of methods below check expectations with actual difference
    # between directory trees before and after a build. All the 'expect*'
    # methods require exact names to be passed. All the 'ignore*' methods allow
    # wildcards.

    # All names can be lists, which are taken to be directory components.
    def expect_addition(self, names):
        for name in self.adjust_names(names):
            try:
                glob_remove(self.unexpected_difference.added_files, name)
            except:
                annotation("failure", "File %s not added as expected" % name)
                self.fail_test(1)

    def ignore_addition(self, wildcard):
        self.ignore_elements(self.unexpected_difference.added_files, wildcard)

    def expect_removal(self, names):
        for name in self.adjust_names(names):
            try:
                glob_remove(self.unexpected_difference.removed_files, name)
            except:
                annotation("failure", "File %s not removed as expected" % name)
                self.fail_test(1)

    def ignore_removal(self, wildcard):
        self.ignore_elements(self.unexpected_difference.removed_files, wildcard)

    def expect_modification(self, names):
        for name in self.adjust_names(names):
            try:
                glob_remove(self.unexpected_difference.modified_files, name)
            except:
                annotation("failure", "File %s not modified as expected" % name)
                self.fail_test(1)

    def ignore_modification(self, wildcard):
        self.ignore_elements(self.unexpected_difference.modified_files, \
            wildcard)

    def expect_touch(self, names):
        d = self.unexpected_difference
        for name in self.adjust_names(names):
            # We need to check both touched and modified files. The reason is
            # that:
            #   (1) Windows binaries such as obj, exe or dll files have slight
            #       differences even with identical inputs due to Windows PE
            #       format headers containing an internal timestamp.
            #   (2) Intel's compiler for Linux has the same behaviour.
            filesets = [d.modified_files, d.touched_files]

            while filesets:
                try:
                    glob_remove(filesets[-1], name)
                    break
                except ValueError:
                    filesets.pop()

            if not filesets:
                annotation("failure", "File %s not touched as expected" % name)
                self.fail_test(1)

    def ignore_touch(self, wildcard):
        self.ignore_elements(self.unexpected_difference.touched_files, wildcard)

    def ignore(self, wildcard):
        self.ignore_elements(self.unexpected_difference.added_files, wildcard)
        self.ignore_elements(self.unexpected_difference.removed_files, wildcard)
        self.ignore_elements(self.unexpected_difference.modified_files, wildcard)
        self.ignore_elements(self.unexpected_difference.touched_files, wildcard)

    def expect_nothing(self, names):
        for name in self.adjust_names(names):
            if name in self.difference.added_files:
                annotation("failure",
                    "File %s added, but no action was expected" % name)
                self.fail_test(1)
            if name in self.difference.removed_files:
                annotation("failure",
                    "File %s removed, but no action was expected" % name)
                self.fail_test(1)
                pass
            if name in self.difference.modified_files:
                annotation("failure",
                    "File %s modified, but no action was expected" % name)
                self.fail_test(1)
            if name in self.difference.touched_files:
                annotation("failure",
                    "File %s touched, but no action was expected" % name)
                self.fail_test(1)

    def expect_nothing_more(self):
        # Not totally sure about this change, but I do not see a good
        # alternative.
        if windows:
            self.ignore('*.ilk')       # MSVC incremental linking files.
            self.ignore('*.pdb')       # MSVC program database files.
            self.ignore('*.rsp')       # Response files.
            self.ignore('*.tds')       # Borland debug symbols.
            self.ignore('*.manifest')  # MSVC DLL manifests.            

        # Debug builds of bjam built with gcc produce this profiling data.
        self.ignore('gmon.out')
        self.ignore('*/gmon.out')

        self.ignore("bin/config.log")

        if not self.unexpected_difference.empty():
            annotation('failure', 'Unexpected changes found')
            output = StringIO.StringIO()
            self.unexpected_difference.pprint(output)
            annotation("unexpected changes", output.getvalue())
            self.fail_test(1)

    def __expect_line(self, content, expected, expected_to_exist):
        expected = expected.strip()
        lines = content.splitlines()
        found = False
        for line in lines:
            line = line.strip()
            if fnmatch.fnmatch(line, expected):
                found = True
                break

        if expected_to_exist and not found:
            annotation("failure",
                "Did not find expected line:\n%s\nin output:\n%s" %
                (expected, content))
            self.fail_test(1)
        if not expected_to_exist and found:
            annotation("failure",
                "Found an unexpected line:\n%s\nin output:\n%s" %
                (expected, content))
            self.fail_test(1)

    def expect_output_line(self, line, expected_to_exist=True):
        self.__expect_line(self.stdout(), line, expected_to_exist)

    def expect_content_line(self, name, line, expected_to_exist=True):
        content = self.__read_file(name)
        self.__expect_line(content, line, expected_to_exist)

    def __read_file(self, name, exact=False):
        name = self.adjust_names(name)[0]
        result = ""
        try:
            if exact:
                result = self.read(name)
            else:
                result = string.replace(self.read_and_strip(name), "\\", "/")
        except (IOError, IndexError):
            print "Note: could not open file", name
            self.fail_test(1)
        return result

    def expect_content(self, name, content, exact=False):
        actual = self.__read_file(name, exact)
        content = string.replace(content, "$toolset", self.toolset+"*")

        matched = False
        if exact:
            matched = fnmatch.fnmatch(actual, content)
        else:
            def sorted_(x):
                x.sort()
                return x
            actual_ = map(lambda x: sorted_(x.split()), actual.splitlines())
            content_ = map(lambda x: sorted_(x.split()), content.splitlines())
            if len(actual_) == len(content_):
                matched = map(
                    lambda x, y: map(lambda n, p: fnmatch.fnmatch(n, p), x, y),
                    actual_, content_)
                matched = reduce(
                    lambda x, y: x and reduce(
                        lambda a, b: a and b,
                    y),
                    matched)

        if not matched:
            print "Expected:\n"
            print content
            print "Got:\n"
            print actual
            self.fail_test(1)

    def maybe_do_diff(self, actual, expected):
        if os.environ.has_key("DO_DIFF") and os.environ["DO_DIFF"] != '':
            e = tempfile.mktemp("expected")
            a = tempfile.mktemp("actual")
            open(e, "w").write(expected)
            open(a, "w").write(actual)
            print "DIFFERENCE"
            if os.system("diff -u " + e + " " + a):
                print "Unable to compute difference: diff -u %s %s" % (e, a)
            os.unlink(e)
            os.unlink(a)
        else:
            print "Set environmental variable 'DO_DIFF' to examine difference."

    # Helpers.
    def mul(self, *arguments):
        if len(arguments) == 0:
            return None

        here = arguments[0]
        if type(here) == type(''):
            here = [here]

        if len(arguments) > 1:
            there = apply(self.mul, arguments[1:])
            result = []
            for i in here:
                for j in there:
                    result.append(i + j)
            return result

        return here

    # Internal methods.
    def ignore_elements(self, list, wildcard):
        """Removes in-place, element of 'list' that match the given wildcard.
        """
        list[:] = filter(lambda x, w=wildcard: not fnmatch.fnmatch(x, w), list)

    def adjust_lib_name(self, name):
        global lib_prefix
        result = name

        pos = string.rfind(name, ".")
        if pos != -1:
            suffix = name[pos:]
            if suffix == ".lib":
                (head, tail) = os.path.split(name)
                if lib_prefix:
                    tail = "lib" + tail
                    result = os.path.join(head, tail)
            elif suffix == ".dll":
                (head, tail) = os.path.split(name)
                if dll_prefix:
                    tail = "lib" + tail
                    result = os.path.join(head, tail)
        # If we want to use this name in a Jamfile, we better convert \ to /, as
        # otherwise we would have to quote \.
        result = string.replace(result, "\\", "/")
        return result

    def adjust_suffix(self, name):
        if not self.translate_suffixes:
            return name

        pos = string.rfind(name, ".")
        if pos != -1:
            suffix = name[pos:]
            name = name[:pos]

            if suffixes.has_key(suffix):
                suffix = suffixes[suffix]
        else:
            suffix = ''

        return name + suffix

    # Acceps either a string or a list of strings and returns a list of strings.
    # Adjusts suffixes on all names.
    def adjust_names(self, names):
        if type(names) == types.StringType:
            names = [names]
        r = map(self.adjust_lib_name, names)
        r = map(self.adjust_suffix, r)
        r = map(lambda x, t=self.toolset: string.replace(x, "$toolset", t+"*"), r)
        return r

    def native_file_name(self, name):
        name = self.adjust_names(name)[0]
        elements = string.split(name, "/")
        return os.path.normpath(apply(os.path.join, [self.workdir]+elements))

    # Wait while time is no longer equal to the time last "run_build_system"
    # call finished. Used to avoid subsequent builds treating existing files as
    # 'current'.
    def wait_for_time_change_since_last_build(self):
        while 1:
            # In fact, I'm not sure why "+ 2" as opposed to "+ 1" is needed but
            # empirically, "+ 1" sometimes causes 'touch' and other functions
            # not to bump the file time enough for a rebuild to happen.
            if math.floor(time.time()) < math.floor(self.last_build_time_finish) + 2:
                time.sleep(0.1)
            else:
                break


class List:

    def __init__(self, s=""):
        elements = []
        if isinstance(s, type("")):
            # Have to handle espaced spaces correctly.
            s = string.replace(s, "\ ", '\001')
            elements = string.split(s)
        else:
            elements = s;

        self.l = []
        for e in elements:
            self.l.append(string.replace(e, '\001', ' '))

    def __len__(self):
        return len(self.l)

    def __getitem__(self, key):
        return self.l[key]

    def __setitem__(self, key, value):
        self.l[key] = value

    def __delitem__(self, key):
        del self.l[key]

    def __str__(self):
        return str(self.l)

    def __repr__(self):
        return (self.__module__ + '.List('
                 + repr(string.join(self.l, ' '))
                 + ')')

    def __mul__(self, other):
        result = List()
        if not isinstance(other, List):
            other = List(other)
        for f in self:
            for s in other:
                result.l.append(f + s)
        return result

    def __rmul__(self, other):
        if not isinstance(other, List):
            other = List(other)
        return List.__mul__(other, self)

    def __add__(self, other):
        result = List()
        result.l = self.l[:] + other.l[:]
        return result

# Quickie tests. Should use doctest instead.
if __name__ == '__main__':
    assert str(List("foo bar") * "/baz") == "['foo/baz', 'bar/baz']"
    assert repr("foo/" * List("bar baz")) == "__main__.List('foo/bar foo/baz')"
    print 'tests passed'
