# Path: diffoscope/tools.py
# def tool_required(command):
#     """
#     Decorator that checks if the specified tool is installed
#     """
#     if not hasattr(tool_required, 'all'):
#         tool_required.all = set()
#     tool_required.all.add(command)
#     def wrapper(original_function):
#         if find_executable(command):
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 with profile('command', command):
#                     return original_function(*args, **kwargs)
#         else:
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 from .exc import RequiredToolNotFound
#                 raise RequiredToolNotFound(command)
#         return tool_check
#     return wrapper
# 
# Path: diffoscope/config.py
# class Config(object):
#     max_diff_block_lines = 256
#     max_diff_block_lines_parent = 50
#     max_diff_block_lines_saved = float("inf")
#     # html-dir output uses ratio * max-diff-block-lines as its limit
#     max_diff_block_lines_html_dir_ratio = 4
#     # GNU diff cannot process arbitrary large files :(
#     max_diff_input_lines = 2 ** 20
#     max_report_size = 2000 * 2 ** 10 # 2000 kB
#     max_text_report_size = 0
#     max_report_child_size = 500 * 2 ** 10
#     new_file = False
#     fuzzy_threshold = 60
#     enforce_constraints = True
#     excludes = ()
# 
#     _singleton = {}
# 
#     def __init__(self):
#         self.__dict__ = self._singleton
# 
#     def __setattr__(self, k, v):
#         super(Config, self).__setattr__(k, v)
# 
#         if self.enforce_constraints:
#             self.check_constraints()
# 
#     def check_constraints(self):
#         if self.max_diff_block_lines < self.max_diff_block_lines_parent:  # noqa
#             raise ValueError("max_diff_block_lines ({0.max_diff_block_lines}) "
#                 "cannot be smaller than max_diff_block_lines_parent "
#                 "({0.max_diff_block_lines_parent})".format(self),
#             )
# 
#         max_ = self.max_diff_block_lines_html_dir_ratio * \
#             self.max_diff_block_lines
#         if self.max_diff_block_lines_saved < max_:  # noqa
#             raise ValueError("max_diff_block_lines_saved "
#                 "({0.max_diff_block_lines_saved}) cannot be smaller than "
#                 "{0.max_diff_block_lines_html_dir_ratio} * "
#                 "max_diff_block_lines ({1})".format(self, max_),
#             )


import re
import io
import os
import errno
import fcntl
import hashlib
import logging
import threading
import subprocess
from multiprocessing.dummy import Queue
from diffoscope.tempfiles import get_temporary_directory
from .tools import tool_required
from .config import Config
            if self._end_nl is None:
                end_nl1 = self._end_nl_q1.get()
                end_nl2 = self._end_nl_q2.get()
                self._end_nl = end_nl1 and end_nl2
            if not self._end_nl:
                return self.read_hunk
        elif self._remaining_hunk_lines == 0:
            return self.read_headers(line)
        else:
            raise ValueError('Unable to parse diff hunk: %r' % line)

        self._diff.write(line)

        if line[0] in ('-', '+'):
            if line[0] == self._direction:
                self._block_len += 1
            else:
                self._block_len = 1
                self._direction = line[0]

            if self._block_len >= self._max_lines:
                return self.skip_block
        else:
            self._block_len = 1
            self._direction = line[0]

        return self.read_hunk

    def skip_block(self, line):
        if self._remaining_hunk_lines == 0 or line[0] != self._direction:

# Path: diffoscope/tools.py
# def tool_required(command):
#     """
#     Decorator that checks if the specified tool is installed
#     """
#     if not hasattr(tool_required, 'all'):
#         tool_required.all = set()
#     tool_required.all.add(command)
#     def wrapper(original_function):
#         if find_executable(command):
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 with profile('command', command):
#                     return original_function(*args, **kwargs)
#         else:
#             @functools.wraps(original_function)
#             def tool_check(*args, **kwargs):
#                 from .exc import RequiredToolNotFound
#                 raise RequiredToolNotFound(command)
#         return tool_check
#     return wrapper
# 
# Path: diffoscope/config.py
# class Config(object):
#     max_diff_block_lines = 256
#     max_diff_block_lines_parent = 50
#     max_diff_block_lines_saved = float("inf")
#     # html-dir output uses ratio * max-diff-block-lines as its limit
#     max_diff_block_lines_html_dir_ratio = 4
#     # GNU diff cannot process arbitrary large files :(
#     max_diff_input_lines = 2 ** 20
#     max_report_size = 2000 * 2 ** 10 # 2000 kB
#     max_text_report_size = 0
#     max_report_child_size = 500 * 2 ** 10
#     new_file = False
#     fuzzy_threshold = 60
#     enforce_constraints = True
#     excludes = ()
# 
#     _singleton = {}
# 
#     def __init__(self):
#         self.__dict__ = self._singleton
# 
#     def __setattr__(self, k, v):
#         super(Config, self).__setattr__(k, v)
# 
#         if self.enforce_constraints:
#             self.check_constraints()
# 
#     def check_constraints(self):
#         if self.max_diff_block_lines < self.max_diff_block_lines_parent:  # noqa
#             raise ValueError("max_diff_block_lines ({0.max_diff_block_lines}) "
#                 "cannot be smaller than max_diff_block_lines_parent "
#                 "({0.max_diff_block_lines_parent})".format(self),
#             )
# 
#         max_ = self.max_diff_block_lines_html_dir_ratio * \
#             self.max_diff_block_lines
#         if self.max_diff_block_lines_saved < max_:  # noqa
#             raise ValueError("max_diff_block_lines_saved "
#                 "({0.max_diff_block_lines_saved}) cannot be smaller than "
#                 "{0.max_diff_block_lines_html_dir_ratio} * "
#                 "max_diff_block_lines ({1})".format(self, max_),
#             )


# Path: diffoscope/diff.py
import re
import io
import os
import errno
import fcntl
import hashlib
import logging
import threading
import subprocess
from multiprocessing.dummy import Queue
from diffoscope.tempfiles import get_temporary_directory
from .tools import tool_required
from .config import Config

            if self._end_nl is None:
                end_nl1 = self._end_nl_q1.get()
                end_nl2 = self._end_nl_q2.get()
                self._end_nl = end_nl1 and end_nl2
            if not self._end_nl:
                return self.read_hunk
        elif self._remaining_hunk_lines == 0:
            return self.read_headers(line)
        else:
            raise ValueError('Unable to parse diff hunk: %r' % line)

        self._diff.write(line)

        if line[0] in ('-', '+'):
            if line[0] == self._direction:
                self._block_len += 1
            else:
                self._block_len = 1
                self._direction = line[0]

            if self._block_len >= self._max_lines:
                return self.skip_block
        else:
            self._block_len = 1
            self._direction = line[0]

        return self.read_hunk

    def skip_block(self, line):
        if self._remaining_hunk_lines == 0 or line[0] != self._direction:

            removed = self._block_len - Config().max_diff_block_lines_saved