#!/usr/bin/env python
# line-directive.py - Transform line numbers in error messages -*- python -*-
#
# This source file is part of the Swift.org open source project
#
# Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
# Licensed under Apache License v2.0 with Runtime Library Exception
#
# See https://swift.org/LICENSE.txt for license information
# See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
#
# ----------------------------------------------------------------------------
#
# Converts line numbers in error messages according to "line directive"
# comments.
#
# ----------------------------------------------------------------------------

from __future__ import print_function

import bisect
import os
import re
import subprocess
import sys

line_pattern = re.compile(
    r'^// ###sourceLocation\(file:\s*"([^"]+)",\s*line:\s*([0-9]+)\s*\)')


def _make_line_map(target_filename, stream=None):
    """
    >>> from StringIO import StringIO
    >>> _make_line_map('box',
    ... StringIO('''// ###sourceLocation(file: "foo.bar", line: 3)
    ... line 2
    ... line 3
    ... line 4
    ... // ###sourceLocation(file: "baz.txt", line: 20)
    ... line 6
    ... line 7
    ... '''))
    [(0, 'box', 1), (1, 'foo.bar', 3), (5, 'baz.txt', 20)]
    """
    result = [(0, target_filename, 1)]
    input = stream or open(target_filename)
    for i, l in enumerate(input.readlines()):
        m = line_pattern.match(l)
        if m:
            result.append((i + 1, m.group(1), int(m.group(2))))
    return result


_line_maps = {}


def fline_map(target_filename):
    map = _line_maps.get(target_filename)
    if map is None:
        map = _make_line_map(target_filename)
        _line_maps[target_filename] = map
    return map


def map_line_to_source_file(target_filename, target_line_num):
    """
    >>> from tempfile import *
    >>> # On Windows, the name of a NamedTemporaryFile cannot be used to open
    >>> # the file for a second time if delete=True. Therefore, we have to
    >>> # manually handle closing and deleting this file to allow us to open
    >>> # the file by its name across all platforms.
    >>> t = NamedTemporaryFile(delete=False)
    >>> t.write('''line 1
    ... line 2
    ... // ###sourceLocation(file: "foo.bar", line: 20)
    ... line 4
    ... line 5
    ... // ###sourceLocation(file: "baz.txt", line: 5)
    ... line 7
    ... line 8
    ... ''')
    >>> t.flush()
    >>> (t2, l) = map_line_to_source_file(t.name, 1)
    >>> t2 == t.name, l
    (True, 1)
    >>> (t2, l) = map_line_to_source_file(t.name, 2)
    >>> t2 == t.name, l
    (True, 2)
    >>> (t2, l) = map_line_to_source_file(t.name, 3)
    >>> t2 == t.name, l
    (True, 3)
    >>> map_line_to_source_file(t.name, 4)
    ('foo.bar', 20)
    >>> map_line_to_source_file(t.name, 5)
    ('foo.bar', 21)
    >>> map_line_to_source_file(t.name, 6)
    ('foo.bar', 22)
    >>> map_line_to_source_file(t.name, 7)
    ('baz.txt', 5)
    >>> map_line_to_source_file(t.name, 8)
    ('baz.txt', 6)
    >>> map_line_to_source_file(t.name, 42)
    ('baz.txt', 40)
    >>> t.close()
    >>> os.remove(t.name)
    """
    assert(target_line_num > 0)
    map = fline_map(target_filename)
    index = bisect.bisect_left(map, (target_line_num, '', 0))
    base = map[index - 1]
    return base[1], base[2] + (target_line_num - base[0] - 1)


def map_line_from_source_file(source_filename, source_line_num,
                              target_filename):
    """
    >>> from tempfile import *
    >>> # On Windows, the name of a NamedTemporaryFile cannot be used to open
    >>> # the file for a second time if delete=True. Therefore, we have to
    >>> # manually handle closing and deleting this file to allow us to open
    >>> # the file by its name across all platforms.
    >>> t = NamedTemporaryFile(delete=False)
    >>> t.write('''line 1
    ... line 2
    ... // ###sourceLocation(file: "foo.bar", line: 20)
    ... line 4
    ... line 5
    ... // ###sourceLocation(file: "baz.txt", line: 5)
    ... line 7
    ... line 8
    ... ''')
    >>> t.flush()
    >>> map_line_from_source_file(t.name, 1, t.name)
    1
    >>> map_line_from_source_file(t.name, 2, t.name)
    2
    >>> map_line_from_source_file(t.name, 3, t.name)
    3
    >>> try: map_line_from_source_file(t.name, 4, t.name)
    ... except RuntimeError: pass
    >>> try: map_line_from_source_file('foo.bar', 19, t.name)
    ... except RuntimeError: pass
    >>> map_line_from_source_file('foo.bar', 20, t.name)
    4
    >>> map_line_from_source_file('foo.bar', 21, t.name)
    5
    >>> map_line_from_source_file('foo.bar', 22, t.name)
    6
    >>> try: map_line_from_source_file('foo.bar', 23, t.name)
    ... except RuntimeError: pass
    >>> map_line_from_source_file('baz.txt', 5, t.name)
    7
    >>> map_line_from_source_file('baz.txt', 6, t.name)
    8
    >>> map_line_from_source_file('baz.txt', 33, t.name)
    35
    >>> try: map_line_from_source_file(t.name, 33, t.name)
    ... except RuntimeError: pass
    >>> try: map_line_from_source_file('foo.bar', 2, t.name)
    ... except RuntimeError: pass
    >>> t.close()
    >>> os.remove(t.name)
    """
    assert(source_line_num > 0)
    map = fline_map(target_filename)

    for i, (target_line_num, found_source_filename,
            found_source_line_num) in enumerate(map):
        if found_source_filename != source_filename:
            continue
        if found_source_line_num > source_line_num:
            continue
        result = target_line_num + (source_line_num - found_source_line_num)
        if i + 1 == len(map) or map[i + 1][0] > result:
            return result + 1
    raise RuntimeError("line not found")


def read_response_file(file_path):
    with open(file_path, 'r') as files:
        return filter(None, files.read().split(';'))


def expand_response_files(files):
    expanded_files = []
    for file_path in files:
        # Read a list of files from a response file.
        if file_path[0] == '@':
            expanded_files.extend(read_response_file(file_path[1:]))
        else:
            expanded_files.append(file_path)

    return expanded_files


def run():
    """Simulate a couple of gyb-generated files

    >>> from tempfile import *
    >>> # On Windows, the name of a NamedTemporaryFile cannot be used to open
    >>> # the file for a second time if delete=True. Therefore, we have to
    >>> # manually handle closing and deleting this file to allow us to open
    >>> # the file by its name across all platforms.
    >>> target1 = NamedTemporaryFile(delete=False)
    >>> target1.write('''line 1
    ... line 2
    ... // ###sourceLocation(file: "foo.bar", line: 20)
    ... line 4
    ... line 5
    ... // ###sourceLocation(file: "baz.txt", line: 5)
    ... line 7
    ... line 8
    ... ''')
    >>> target1.flush()
    >>> # On Windows, the name of a NamedTemporaryFile cannot be used to open
    >>> # the file for a second time if delete=True. Therefore, we have to
    >>> # manually handle closing and deleting this file to allow us to open
    >>> # the file by its name across all platforms.
    >>> target2 = NamedTemporaryFile(delete=False)
    >>> target2.write('''// ###sourceLocation(file: "foo.bar", line: 7)
    ... line 2
    ... line 3
    ... // ###sourceLocation(file: "fox.box", line: 11)
    ... line 5
    ... line 6
    ... ''')
    >>> target2.flush()

    Simulate the raw output of compilation

    >>> # On Windows, the name of a NamedTemporaryFile cannot be used to open
    >>> # the file for a second time if delete=True. Therefore, we have to
    >>> # manually handle closing and deleting this file to allow us to open
    >>> # the file by its name across all platforms.
    >>> raw_output = NamedTemporaryFile(delete=False)
    >>> target1_name, target2_name = target1.name, target2.name
    >>> raw_output.write('''A
    ... %(target1_name)s:2:111: error one
    ... B
    ... %(target1_name)s:4:222: error two
    ... C
    ... %(target1_name)s:8:333: error three
    ... D
    ... glitch in file %(target2_name)s:1 assert one
    ... E
    ... glitch in file %(target2_name)s, line 2 assert two
    ... glitch at %(target2_name)s, line 3 assert three
    ... glitch at %(target2_name)s:4 assert four
    ... glitch in [%(target2_name)s, line 5 assert five
    ... glitch in [%(target2_name)s:22 assert six
    ... ''' % locals())
    >>> raw_output.flush()

    Run this tool on the two targets, using a portable version of Unix 'cat' to
    dump the output file.

    >>> import subprocess
    >>> output = subprocess.check_output([sys.executable,
    ...    __file__, target1.name, target2.name, '--',
    ...    sys.executable, '-c',
    ...   'import sys;sys.stdout.write(open(sys.argv[1]).read())',
    ...   raw_output.name], universal_newlines=True)

    Replace temporary filenames and check it.

    >>> print(output.replace(target1.name,'TARGET1-NAME')
    ...             .replace(target2.name,'TARGET2-NAME') + 'EOF')
    A
    TARGET1-NAME:2:111: error one
    B
    foo.bar:20:222: error two
    C
    baz.txt:6:333: error three
    D
    glitch in file TARGET2-NAME:1 assert one
    E
    glitch in file foo.bar, line 7 assert two
    glitch at foo.bar, line 8 assert three
    glitch at foo.bar:9 assert four
    glitch in [fox.box, line 11 assert five
    glitch in [fox.box:28 assert six
    EOF
    >>> print(subprocess.check_output([sys.executable, __file__, 'foo.bar',
    ...                                '21', target1.name],
    ...                               universal_newlines=True), end='')
    5
    >>> print(subprocess.check_output([sys.executable, __file__, 'foo.bar',
    ...                                '8', target2.name],
    ...                               universal_newlines=True), end='')
    3

    Simulate errors on different line numbers
    >>> # On Windows, the name of a NamedTemporaryFile cannot be used to open
    >>> # the file for a second time if delete=True. Therefore, we have to
    >>> # manually handle closing and deleting this file to allow us to open
    >>> # the file by its name across all platforms.
    >>> long_output = NamedTemporaryFile(delete=False)
    >>> long_output.write('''
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 1)
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 1)
    ... //===--- Map.swift.gyb - Lazily map over a Sequence -----------*- swif
    ... //
    ... // This source file is part of the Swift.org open source project
    ... //
    ... // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
    ... // Licensed under Apache License v2.0 with Runtime Library Exception
    ... //
    ... // See https://swift.org/LICENSE.txt for license information
    ... // See https://swift.org/CONTRIBUTORS.txt for the list of Swift projec
    ... //
    ... //===-----------------------------------------------------------------
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 20)
    ...
    ... /// The `IteratorProtocol` used by `MapSequence` and `MapCollection`.
    ... /// Produces each element by passing the output of the `Base`
    ... /// `IteratorProtocol` through a transform function returning
    ... @_fixed_layout
    ... public struct LazyMapIterator<
    ...   Base : IteratorProtocol, Element
    ... > : IteratorProtocol, Sequence {
    ...   /// Advances to the next element and returns it, or `nil` if no
    ...   /// exists.
    ...   ///
    ...   /// Once `nil` has been returned, all subsequent calls return `nil`.
    ...   ///
    ...   /// - Precondition: `next()` has not been applied to a copy.
    ...   ///   since the copy was made.
    ...   @_inlineable
    ...   public mutating func next() -> Element? {
    ...     return _base.next().map(_transform)
    ...   }
    ...
    ...   @_inlineable
    ...   public var base: Base { return _base }
    ...
    ...   @_versioned
    ...   internal var _base: Base
    ...   @_versioned
    ...   internal let _transform: (Base.Element) -> Element
    ...
    ...   @_inlineable
    ...   @_versioned
    ...   internal init(_base: Base, _transform: @escaping (Base.Element)
    ...     self._base = _base
    ...     self._transform = _transform
    ...   }
    ... }
    ...
    ... /// A `Sequence` whose elements consist of those in a `Base`
    ... /// `Sequence` passed through a transform function returning.
    ... /// These elements are computed lazily, each time they're read, by
    ... /// calling the transform function on a base element.
    ... @_fixed_layout
    ... public struct LazyMapSequence<Base : Sequence, Element>
    ...   : LazySequenceProtocol {
    ...
    ...   public typealias Elements = LazyMapSequence
    ...
    ...   /// Returns an iterator over the elements of this sequence.
    ...   ///
    ...   /// - Complexity: O(1).
    ...   @_inlineable
    ...   public func makeIterator() -> LazyMapIterator<Base.Iterator, Element
    ...     return LazyMapIterator(_base: _base.makeIterator(), _transform: _t
    ...   }
    ...
    ...   /// Returns a value less than or equal to the number of elements in
    ...   /// `self`, **nondestructively**.
    ...   ///
    ...   /// - Complexity: O(*n*)
    ...   @_inlineable
    ...   public var underestimatedCount: Int {
    ...     return _base.underestimatedCount
    ...   }
    ...
    ...   /// Creates an instance with elements `transform(x)` for each elemen
    ...   /// `x` of base.
    ...   @_inlineable
    ...   @_versioned
    ...   internal init(_base: Base, transform: @escaping (Base.Iterator.Eleme
    ...     self._base = _base
    ...     self._transform = transform
    ...   }
    ...
    ...   @_versioned
    ...   internal var _base: Base
    ...   @_versioned
    ...   internal let _transform: (Base.Iterator.Element) -> Element
    ... }
    ...
    ... //===--- Collections -------------------------------------------------
    ...
    ... // FIXME(ABI)#45 (Conditional Conformance): `LazyMap*Collection` types
    ... // collapsed into one `LazyMapCollection` using conditional conformanc
    ... // Maybe even combined with `LazyMapSequence`.
    ... // rdar://problem/17144340
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 108)
    ...
    ... /// A `Collection` whose elements consist of those in a `Base`
    ... /// `Collection` passed through a transform function returning `Elemen
    ... /// These elements are computed lazily, each time they're read, by
    ... /// calling the transform function on a base element.
    ... @_fixed_layout
    ... public struct LazyMapCollection<
    ...   Base : Collection, Element
    ... > : LazyCollectionProtocol,
    ...     _CollectionWrapper
    ... {
    ...   public typealias Base = Base_
    ...   public typealias Index = Base.Index
    ...   public typealias _Element = Base._Element
    ...   public typealias SubSequence = Base.SubSequence
    ...   typealias Indices = Base.Indices
    ...
    ...   @_inlineable
    ...   public subscript(position: Base.Index) -> Element {
    ...     return _transform(_base[position])
    ...   }
    ...
    ...   /// Create an instance with elements `transform(x)` for each element
    ...   /// `x` of base.
    ...   @_inlineable
    ...   @_versioned
    ...   internal init(_base: Base, transform: @escaping (Base.Iterator.Eleme
    ...     self._base = _base
    ...     self._transform = transform
    ...   }
    ...
    ...   @_versioned
    ...   internal var _base: Base
    ...   @_versioned
    ...   internal let _transform: (Base.Iterator.Element) -> Element
    ... }
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 108)
    ...
    ... /// A `Collection` whose elements consist of those in a `Base`
    ... /// `Collection` passed through a transform function returning `Elemen
    ... /// These elements are computed lazily, each time they're read, by
    ... /// calling the transform function on a base element.
    ... @_fixed_layout
    ... public struct LazyMapBidirectionalCollection<
    ...   Base : BidirectionalCollection, Element
    ... > : LazyCollectionProtocol,
    ...     _BidirectionalCollectionWrapper
    ... {
    ...   public typealias Base = Base_
    ...   public typealias Index = Base.Index
    ...   public typealias _Element = Base._Element
    ...   public typealias SubSequence = Base.SubSequence
    ...   typealias Indices = Base.Indices
    ...
    ...   @_inlineable
    ...   public subscript(position: Base.Index) -> Element {
    ...     return _transform(_base[position])
    ...   }
    ...
    ...   /// Create an instance with elements `transform(x)` for each element
    ...   /// `x` of base.
    ...   @_inlineable
    ...   @_versioned
    ...   internal init(_base: Base, transform: @escaping (Base.Iterator.Eleme
    ...     self._base = _base
    ...     self._transform = transform
    ...   }
    ...
    ...   @_versioned
    ...   internal var _base: Base
    ...   @_versioned
    ...   internal let _transform: (Base.Iterator.Element) -> Element
    ... }
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 108)
    ...
    ... /// A `Collection` whose elements consist of those in a `Base`
    ... /// `Collection` passed through a transform function returning `Elemen
    ... /// These elements are computed lazily, each time they're read, by
    ... /// calling the transform function on a base element.
    ... @_fixed_layout
    ... public struct LazyMapRandomAccessCollection<
    ...   Base : RandomAccessCollection, Element
    ... > : LazyCollectionProtocol,
    ...     _RandomAccessCollectionWrapper
    ... {
    ...   public typealias Base = Base_
    ...   public typealias Index = Base.Index
    ...   public typealias _Element = Base._Element
    ...   public typealias SubSequence = Base.SubSequence
    ...   typealias Indices = Base.Indices
    ...
    ...   @_inlineable
    ...   public subscript(position: Base.Index) -> Element {
    ...     return _transform(_base[position])
    ...   }
    ...
    ...   /// Create an instance with elements `transform(x)` for each element
    ...   /// `x` of base.
    ...   @_inlineable
    ...   @_versioned
    ...   internal init(_base: Base, transform: @escaping (Base.Iterator.Eleme
    ...     self._base = _base
    ...     self._transform = transform
    ...   }
    ...
    ...   @_versioned
    ...   internal var _base: Base
    ...   @_versioned
    ...   internal let _transform: (Base.Iterator.Element) -> Element
    ... }
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 146)
    ...
    ... //===--- Support for s.lazy ------------------------------------------
    ...
    ... extension LazySequenceProtocol {
    ...   /// Returns a `LazyMapSequence` over this `Sequence`.  The elements
    ...   /// the result are computed lazily, each time they are read, by
    ...   /// calling `transform` function on a base element.
    ...   @_inlineable
    ...   public func map<U>(
    ...     _ transform: @escaping (Elements.Iterator.Element) -> U
    ...   ) -> LazyMapSequence<Self.Elements, U> {
    ...     return LazyMapSequence(_base: self.elements, transform: transform)
    ...   }
    ... }
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 162)
    ...
    ... extension LazyCollectionProtocol
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 169)
    ... {
    ...   /// Returns a `LazyMapCollection` over this `Collection`.  The eleme
    ...   /// the result are computed lazily, each time they are read, by
    ...   /// calling `transform` function on a base element.
    ...   @_inlineable
    ...   public func map<U>(
    ...     _ transform: @escaping (Elements.Iterator.Element) -> U
    ...   ) -> LazyMapCollection<Self.Elements, U> {
    ...     return LazyMapCollection(
    ...       _base: self.elements,
    ...       transform: transform)
    ...   }
    ... }
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 162)
    ...
    ... extension LazyCollectionProtocol
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 165)
    ...   where
    ...   Self : BidirectionalCollection,
    ...   Elements : BidirectionalCollection
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 169)
    ... {
    ...   /// Returns a `LazyMapCollection` over this `Collection`.  The eleme
    ...   /// the result are computed lazily, each time they are read, by
    ...   /// calling `transform` function on a base element.
    ...   @_inlineable
    ...   public func map<U>(
    ...     _ transform: @escaping (Elements.Iterator.Element) -> U
    ...   ) -> LazyMapBidirectionalCollection<Self.Elements, U> {
    ...     return LazyMapBidirectionalCollection(
    ...       _base: self.elements,
    ...       transform: transform)
    ...   }
    ... }
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 162)
    ...
    ... extension LazyCollectionProtocol
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 165)
    ...   where
    ...   Self : RandomAccessCollection,
    ...   Elements : RandomAccessCollection
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 169)
    ... {
    ...   /// Returns a `LazyMapCollection` over this `Collection`.  The eleme
    ...   /// the result are computed lazily, each time they are read, by
    ...   /// calling `transform` function on a base element.
    ...   @_inlineable
    ...   public func map<U>(
    ...     _ transform: @escaping (Elements.Iterator.Element) -> U
    ...   ) -> LazyMapRandomAccessCollection<Self.Elements, U> {
    ...     return LazyMapRandomAccessCollection(
    ...       _base: self.elements,
    ...       transform: transform)
    ...   }
    ... }
    ...
    ... // ###sourceLocation(file: "/public/core/Map.swift.gyb", line: 184)
    ...
    ... @available(*, unavailable, renamed: "LazyMapIterator")
    ... public struct LazyMapGenerator<Base : IteratorProtocol, Element> {}
    ...
    ... extension LazyMapSequence {
    ...   @available(*, unavailable, message: "use '.lazy.map' on the sequence
    ...   public init(_ base: Base, transform: (Base.Iterator.Element) -> Elem
    ...     Builtin.unreachable()
    ...   }
    ... }
    ...
    ... extension LazyMapCollection {
    ...   @available(*, unavailable, message: "use '.lazy.map' on the collecti
    ...   public init(_ base: Base, transform: (Base.Iterator.Element) -> Elem
    ...     Builtin.unreachable()
    ...   }
    ... }
    ...
    ... // Local Variables:
    ... // eval: (read-only-mode 1)
    ... // End:
    ... ''')
    >>> long_output.flush()
    >>> long_output_result = subprocess.check_output(sys.executable + ' ' +
    ...    __file__ + ' ' + long_output.name + ' -- ' + "echo '" +
    ...    long_output.name + ":112:27: error:'",
    ...    shell=True).rstrip()
    >>> print(long_output_result)
    /public/core/Map.swift.gyb:117:27: error:
    >>> target1.close()
    >>> os.remove(target1.name)
    >>> target2.close()
    >>> os.remove(target2.name)
    >>> raw_output.close()
    >>> os.remove(raw_output.name)

    Lint this file.
    >>> import python_lint
    >>> python_lint.lint([os.path.realpath(__file__)], verbose=False)
    0
    """
    if len(sys.argv) <= 1:
        import doctest
        failure_count, _ = doctest.testmod()
        sys.exit(failure_count)
    elif '--' not in sys.argv:
        source_file = sys.argv[1]
        source_line = int(sys.argv[2])
        target_file = sys.argv[3]
        print(map_line_from_source_file(source_file, source_line, target_file))
    else:
        dashes = sys.argv.index('--')
        sources = expand_response_files(sys.argv[1:dashes])

        # The first argument of command_args is the process to open.
        # subprocess.Popen doesn't normalize arguments. This means that trying
        # to open a non-normalized file (e.g. C:/swift/./bin/swiftc.exe) on
        # Windows results in file/directory not found errors, as Popen
        # delegates to the Win32 CreateProcess API. Unix systems handle
        # non-normalized paths, so don't have this problem.
        # Arguments passed to the process are normalized by the process.
        command_args = expand_response_files(sys.argv[dashes + 1:])
        command_args[0] = os.path.normpath(command_args[0])

        command = subprocess.Popen(
            command_args,
            stderr=subprocess.STDOUT,
            stdout=subprocess.PIPE,
            universal_newlines=True
        )

        sources = '(?P<file>' + '|'.join(re.escape(s) for s in sources) + ')'

        error_pattern = re.compile(
            '^' + sources +
            ':(?P<line>[0-9]+):(?P<column>[0-9]+):(?P<tail>.*?)\n?$')

        assertion_pattern = re.compile(
            '^(?P<head>.*( file | at |#[0-9]+: |[[]))' +
            sources +
            '(?P<middle>, line |:)(?P<line>[0-9]+)(?P<tail>.*?)\n?$')

        while True:
            input = command.stdout.readline()
            if input == '':
                break
            output = input

            def decode_match(p, l):
                m = p.match(l)
                if m is None:
                    return ()
                file, line_num = map_line_to_source_file(
                    m.group('file'), int(m.group('line')))
                return ((m, file, line_num),)

            for (m, file, line_num) in decode_match(error_pattern, input):
                output = '%s:%s:%s:%s\n' % (
                    file, line_num, int(m.group(3)), m.group(4))
                break
            else:
                for (m, file, line_num) in decode_match(assertion_pattern,
                                                        input):
                    output = '%s%s%s%s%s\n' % (
                        m.group('head'), file, m.group('middle'), line_num,
                        m.group('tail'))
            sys.stdout.write(output)

        sys.exit(command.wait())


if __name__ == '__main__':
    run()
