Esempio n. 1
0
    def _parse_hunk_line(self, string):
        ''' Parse hunk line like '@@ -428,7 +428,7 @@ DEFINE_...'. The text after
            the second '@@' is a 'hunk note'.
        '''

        self.spec = string
        string = ut.normalize_string(string, False)

        (_, old, new, tail) = string.split(' ', 3)
        if (tail == '@@'):  # no hunk note
            self.note = ''
        else:
            self.note = tail.split(' ')[1]

        parts = old[1:].split(',')
        self.old_start = int(parts[0])
        if (',' in old):  # old has line count
            self.old_count = int(parts[1])
        else:
            self.old_count = 1

        parts = new[1:].split(',')
        self.new_start = int(parts[0])
        if (',' in new):  # new has line count
            self.new_count = int(parts[1])
        else:
            self.new_count = 1
Esempio n. 2
0
    def _parse_hunk_line(self, string):
        ''' Parse hunk line like '@@ -428,7 +428,7 @@ DEFINE_...'. The text after
            the second '@@' is a 'hunk note'.
        '''

        self.spec = string
        string = ut.normalize_string(string, False)
        
        (_, old, new, tail) = string.split(' ', 3)
        if (tail == '@@'): # no hunk note
            self.note = ''
        else:
            self.note = tail.split(' ')[1]
        
        parts = old[1:].split(',')
        self.old_start = int(parts[0])
        if (',' in old): # old has line count
            self.old_count = int(parts[1])
        else:
            self.old_count = 1
        
        parts = new[1:].split(',')
        self.new_start = int(parts[0])
        if (',' in new): # new has line count
            self.new_count = int(parts[1])
        else:
            self.new_count = 1
Esempio n. 3
0
    def _find_line(self, text, strings):
        ''' Try to find text in the source strings.
        
            Both text and strings are normalized to eliminate mismatches on varying whitespace.
            
            Source strings may contain items such as author name, etc. with unicode characters
            that can't be converted to ascii or latin-1, so we must not convert the strings to
            Python 2.x str objects.
        '''
        text = ut.normalize_string(text, True)
        matches = []
        for index in range(len(strings)):
            string = ut.normalize_string(strings[index], True)
            if (text == string):
                matches += [index]

        return matches
Esempio n. 4
0
 def _find_line(self, text, strings):
     ''' Try to find text in the source strings.
     
         Both text and strings are normalized to eliminate mismatches on varying whitespace.
         
         Source strings may contain items such as author name, etc. with unicode characters
         that can't be converted to ascii or latin-1, so we must not convert the strings to
         Python 2.x str objects.
     '''
     text = ut.normalize_string(text, True)
     matches = []
     for index in range(len(strings)):
         string = ut.normalize_string(strings[index], True)
         if (text == string):
             matches += [index]
     
     return matches
Esempio n. 5
0
 def _parse_diff_line(self, string):
     ''' Extract old and new paths from diff line, which has a format like:
             'diff --git a/<path_to_file> b/<path_to_file>'
         We extract the paths and strip the leading 'a/' or 'b/'.
     '''
     self.spec = string
     string = ut.normalize_string(string, False)
     parts  = string.split(' ')
     self.a_path = parts[2][2:] # strip 'a/'
     self.b_path = parts[3][2:] # strip 'b/'
     
     # On rare occasions the diff line is corrupted
     if (self.a_path.endswith('/')):
         self.a_path = self.b_path
Esempio n. 6
0
    def _parse_diff_line(self, string):
        ''' Extract old and new paths from diff line, which has a format like:
                'diff --git a/<path_to_file> b/<path_to_file>'
            We extract the paths and strip the leading 'a/' or 'b/'.
        '''
        self.spec = string
        string = ut.normalize_string(string, False)
        parts = string.split(' ')
        self.a_path = parts[2][2:]  # strip 'a/'
        self.b_path = parts[3][2:]  # strip 'b/'

        # On rare occasions the diff line is corrupted
        if (self.a_path.endswith('/')):
            self.a_path = self.b_path
Esempio n. 7
0
    def _check_hunk_edits(self, filepath, edits, start, count, note, lines):
        """ Check edits against the "a" file. Report errors when lines to be deleted
            or merged are missing, and when lines to be added are present. Note that
            patch lines and source lines may have the same text, but differ in leading
            whitespace. We strip and normalize the strings before testing them. 
            In 'find' mode, try to find missing lines.
        """
        errors = warnings = 0
        current = start
        mismatches = []

        #index表示修改内容在该行中的index
        for (index, edit1, edit2) in self._get_edits(edits):

            op, text1 = edit1[0], edit1[1:]
            norm1 = ut.normalize_string(text1)
            line = lines[current - 1]  # patch line numbers are 1-based
            norm3 = ut.normalize_string(line)

            #(edit1,edit2)表示变更(-,+),即先减后加
            if (edit2 is not None):  # change request
                text2 = edit2[1:]
                norm2 = ut.normalize_string(text2)
                if (norm2 == norm3):  # Change already applied
                    self._ok_msg(
                        '"after"  line found at %d: "%s"' % (current, text2),
                        3)
                elif (norm1 == norm3):  # Change not yet applied
                    self._info_msg(
                        '"after"  line not found at %d: "%s"' %
                        (current, text2), 3)
                else:
                    self._error_msg(
                        '"before"  line not found at %d: "%s"' %
                        (current, text1), 3)
                current += 1  # advance to next edit line

            elif (op == '-'):  # delete line
                # A line to be deleted by the patch should be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for it.
                # Doing so may return multiple matches.
                if (norm1 != norm3):
                    self._error_msg(
                        '"delete" line not found at %d: "%s"' %
                        (current, text1), 3)
                    mismatches += [(index, '-')]
                else:
                    if (self.mode == 'complete'):
                        self._ok_msg(
                            '"delete" line found at %d: "%s"' %
                            (current, text1), 3)
                current += 1  # advance to next edit line

            elif (op == '+'):  # insert line
                # A line to be inserted by the patch should not be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for
                # significant "add" lines below. Doing so may return multiple matches.
                if (norm1 == norm3):
                    self._error_msg(
                        '"add"    line found at %d: "%s"' % (current, text1),
                        3)
                    errors += 1
                else:
                    if (self.mode == 'complete'):
                        self._info_msg(
                            '"add"    line not found at next line: "%s"' %
                            text1, 3)
                    mismatches += [(index, '+')]

            else:  # (op == ' '): # merge line
                # a line to be merged by the patch should be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for it.
                # Doing so may return multiple matches.
                if (norm1 != norm3):
                    self._warn_msg(
                        '"merge"  line not found at %d: "%s"' %
                        (current, text1), 3)
                    warnings += 1
                    mismatches += [(index, ' ')]
                elif (self.mode == 'complete'):
                    self._ok_msg(
                        '"merge"  line found at %d: "%s"' % (current, text1),
                        3)
                current += 1  # advance to next edit line

        if ((len(mismatches) > 0) and self.find):
            self._match(filepath, edits, lines, mismatches)
            return 1
        else:
            return 0
Esempio n. 8
0
    def _change_hunk_edits(self, filepath, edits, start, count, note, lines):

        errors = warnings = 0
        current = start
        new_edits = []
        #-m,n中的m
        new_start = start
        context_start = start
        #+m,n中的n
        new_count = 0
        #-m,n中的n
        context_count = 0

        oldToNew = {}

        #index表示在edits中的下标
        for (index, edit1, edit2) in self._get_edits(edits):

            op, text1 = edit1[0], edit1[1:]
            norm1 = ut.normalize_string(text1)
            print "lines: " + str(len(lines)) + "," + str(current)
            print "index: " + str(len(edits)) + "," + str(index)
            if (current > len(lines)):
                break
            line = lines[current - 1]  # patch line numbers are 1-based
            norm3 = ut.normalize_string(line)
            print "begin changing for edit now"

            #(edit1,edit2)表示变更(-,+),即先减后加
            if (edit2 is not None):  # change request
                print "    (-,+)"
                text2 = edit2[1:]
                norm2 = ut.normalize_string(text2)
                if (norm2 == norm3):  # Change already applied
                    self._ok_msg(
                        '"after"  line found at %d: "%s"' % (current, text2),
                        3)
                    oldToNew[current] = -1
                elif (norm1 == norm3):  # Change not yet applied
                    self._info_msg(
                        '"after"  line not found at %d: "%s"' %
                        (current, text2), 3)
                    oldToNew[current] = current
                    new_edits.append(edit1)
                    new_edits.append(edit2)
                    new_count += 2
                    context_count += 1
                else:
                    self._error_msg(
                        '"before"  line not found at %d: "%s"' %
                        (current, text1), 3)
                    if (self._match2(filepath, edits, lines, index, current,
                                     oldToNew, new_edits, new_count,
                                     context_count)):
                        new_edits.append(edit2)
                        new_count += 1
                        context_count += 1
                current += 1  # advance to next edit line

            elif (op == '-'):  # delete line
                # A line to be deleted by the patch should be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for it.
                # Doing so may return multiple matches.
                print "    -"
                if (norm1 != norm3):
                    self._error_msg(
                        '"delete" line not found at %d: "%s"' %
                        (current, text1), 3)
                    self._match2(filepath, edits, lines, index, current,
                                 oldToNew, new_edits, new_count, context_count)
                else:
                    if (self.mode == 'complete'):
                        self._ok_msg(
                            '"delete" line found at %d: "%s"' %
                            (current, text1), 3)
                    oldToNew[current] = current
                    new_edits.append(edit1)
                    new_count += 1
                    context_count -= 1
                current += 1  # advance to next edit line

            elif (op == '+'):  # insert line
                # A line to be inserted by the patch should not be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for
                # significant "add" lines below. Doing so may return multiple matches.
                print "    +"
                if (norm1 == norm3):
                    self._error_msg(
                        '"add"    line found at %d: "%s"' % (current, text1),
                        3)
                    oldToNew[current] = -1
                    errors += 1
                else:
                    if (self.mode == 'complete'):
                        self._info_msg(
                            '"add"    line not found at next line: "%s"' %
                            text1, 3)
                    #查找上家的新位置,并+1作为自己的新位置

                    #current表示在lines中的位置,即实际的多少行
                    up = current - 1
                    #index表示在edits中的下标
                    up_index = index - 1
                    #查找上家的新位置
                    print "    looking for new up"
                    #如果当前已经是头了,则直接查找当前行的新位置
                    if (up <= 0):
                        self._match2(filepath, edits, lines, index, current,
                                     oldToNew, new_edits, new_count,
                                     context_count)
                    #如果还未到头,且
                    #上家尚未查找过新位置,或者上家的新位置没有找到(上家在新文件中已被删除)
                    #那么查找上家的新位置,或者查找上家的上家
                    elif (not (oldToNew.has_key(up)) or oldToNew[up] == -1):
                        #如果当前上家没找到新位置,则继续往上找
                        while (oldToNew.has_key(up) and oldToNew[up] == -1):
                            up = up - 1
                            up_index = up_index - 1
                        #查找当前上家的新位置,若没有,则继续往上找
                        print "    begin 2nd while"
                        while (up > 0 and up_index > 0):
                            edit_text = edits[up_index]
                            text = edit_text[1:]
                            print "text got"
                            if (text.strip() == 'bool'):
                                print "    pass"
                                pass
                            if (self._is_landmark(filepath, text)):
                                matches = self._find_line(text, lines)
                                print "    find matched for edit in old"
                                if (matches):
                                    min = sys.maxint
                                    #若有多个match,选择其中离current最近的
                                    for match in matches:
                                        if (abs(match - current) < min):
                                            min = match - current
                                    #记录找到的该行的新位置
                                    oldToNew[up] = (min + current) + 1
                                    print "    matched: " + str(
                                        up) + "," + str(up_index)
                                    break
                                else:
                                    print "    not matched: " + str(
                                        up) + "," + str(up_index)
                            up = up - 1
                            up_index = up_index - 1
                        #将找到的上家新位置+1,作为自己的新位置,并将当前行加入到new_edits中
                        if (not (oldToNew.has_key(up))):
                            errors += 1
                        else:
                            oldToNew[current] = oldToNew[up] + 1
                            new_edits.append(edit1)
                            new_count += 1
                            context_count += 1
                    print "    finding out up: " + str(up)
                current += 1
            else:  # (op == ' '): # merge line
                # a line to be merged by the patch should be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for it.
                # Doing so may return multiple matches.
                print "    merge"
                if (norm1 != norm3):
                    self._match2(filepath, edits, lines, index, current,
                                 oldToNew, new_edits, new_count, context_count)
                elif (self.mode == 'complete'):
                    self._ok_msg(
                        '"merge"  line found at %d: "%s"' % (current, text1),
                        3)
                elif (norm1 == norm3):
                    oldToNew[current] = current
                    new_edits.append(edit1)
                    new_count += 1
                    context_count += 1
                current += 1  # advance to next edit line
        #记录新的起始位置
        new_start = start
        while ((oldToNew.has_key(new_start)) and oldToNew[new_start] == -1):
            new_start += 1
        #待修改
        for edit in edits:
            op, text = edit[0], edit[1:]
            if (op == ' '):
                context_start = new_start
                break

        return new_edits, new_start, context_start, new_count, context_count
Esempio n. 9
0
    def _patch_hunk_edits(self, filepath, edits, start, count, note, lines):
        """ Check edits against the "a" file. Report errors when lines to be deleted
            or merged are missing, and when lines to be added are present. Note that
            patch lines and source lines may have the same text, but differ in leading
            whitespace. We strip and normalize the strings before testing them. 
            In 'find' mode, try to find missing lines.
        """
        errors = warnings = 0

        current = start

        #[修改类型,该行修改前新位置,该行修改后新位置]
        new_place = []

        mismatches = []

        log = ""

        #index:记录在当前hunk中是第几行edit
        for (index, edit1, edit2) in self._get_edits(edits):

            op, text1 = edit1[0], edit1[1:]
            norm1 = ut.normalize_string(text1)
            if (current < len(lines)):
                line = lines[current - 1]  # patch line numbers are 1-based
                norm3 = ut.normalize_string(line)
            else:
                break
            #(edit1,edit2)表示变更(-,+),即先减后加
            if (edit2 is not None):  # change request
                text2 = edit2[1:]
                norm2 = ut.normalize_string(text2)
                log += " change edit:\n"
                if (norm2 == norm3):  # Change already applied
                    self._ok_msg(
                        '"after"  line found at %d: "%s"' % (current, text2),
                        3)
                    #此时change已经被应用,该两条连续edit可以被删除
                    log += "  change is applied,delete this edit\n"
                elif (norm1 == norm3):  # Change not yet applied
                    self._info_msg(
                        '"after"  line not found at %d: "%s"' %
                        (current, text2), 3)
                    #此时change尚未被应用,该两条连续edit需要被添加进来
                    new_line_current = current
                    new_line_edited = current
                    new_place.append((edit1, new_line_current, -1))
                    new_place.append((edit2, -1, new_line_edited))
                    log += "  change is not applied,added to new_place\n"
                else:
                    self._error_msg(
                        '"before"  line not found at %d: "%s"' %
                        (current, text1), 3)
                    #此时edit1的内容不在原位,找到new中修改前的位置
                    new_line_current = self._find_new_place(
                        text1, lines, current, filepath)
                    #如果在new中能找到该行
                    log += "  change line is not in place,try to find it in new\n"
                    if (new_line_current != -1):
                        #在new中修改后的位置为-1(被删除)
                        new_line_edited = current
                        #记录下该行edit的信息
                        new_place.append((edit1, new_line_current, -1))
                        new_place.append((edit2, -1, new_line_edited))
                        log += "   find it,added to new_place\n"
                    #若new中不存在该行,则删除之
                    else:
                        log += "   not found, delete this edit\n"
                        pass
                current += 1  # advance to next edit line

            elif (op == '-'):  # delete line
                # A line to be deleted by the patch should be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for it.
                # Doing so may return multiple matches.
                log += " - edit:\n"
                if (norm1 != norm3):
                    self._error_msg(
                        '"delete" line not found at %d: "%s"' %
                        (current, text1), 3)
                    mismatches += [(index, '-')]
                    log += "  delete line is not in place,try to find it in new\n"
                    #找到new中修改前的位置
                    new_line_current = self._find_new_place(
                        text1, lines, current, filepath)
                    if (filepath.find("ASTConverter") != -1):
                        log += "ASTConverter:\n"
                        print("ASTConverter:")
                        log += "delete line:" + text + " \n new place: " + str(
                            new_line_current) + "\n"
                        print("delete line:" + text + " \n new place: " +
                              str(new_line_current))
                    #如果在new中能找到该行
                    if (new_line_current != -1):
                        #在new中修改后的位置为-1(被删除)
                        new_line_edited = -1
                        #记录下该行edit的信息
                        new_place.append(
                            (edit1, new_line_current, new_line_edited))
                        log += "   find it,add to new_place\n"
                    #若new中不存在该行,则删除之
                    else:
                        log += "   not found, delete this edit\n"
                        pass
                else:
                    if (self.mode == 'complete'):
                        self._ok_msg(
                            '"delete" line found at %d: "%s"' %
                            (current, text1), 3)
                    #若该行还在原处,添加该行edit的信息,不变即可
                    new_line_current = current
                    new_line_edited = -1
                    new_place.append(
                        (edit1, new_line_current, new_line_edited))
                    log += "  delete line is in place, add it to new_place\n"
                current += 1  # advance to next edit line

            elif (op == '+'):  # insert line
                # A line to be inserted by the patch should not be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for
                # significant "add" lines below. Doing so may return multiple matches.
                log += " + edit:\n"
                if (norm1 == norm3):
                    self._error_msg(
                        '"add"    line found at %d: "%s"' % (current, text1),
                        3)
                    errors += 1
                    log += "  add line is already in place,delete this edit\n"
                    #new中该位置已有该行,该条edit可被删除
                else:
                    if (self.mode == 'complete'):
                        self._info_msg(
                            '"add"    line not found at next line: "%s"' %
                            text1, 3)
                    mismatches += [(index, '+')]
                    new_line_current = self._find_new_place(
                        text1, lines, current, filepath)
                    log += "  try to find add line in new:\n"
                    #若new中已有被添加的行,则删除这条edit
                    #                     if (new_line_current != -1) :
                    #                         print("   add line is already in new,delete this edit")
                    #                         pass
                    #否则:
                    #                     else:
                    if (True):
                        #如果该行不是第一行edit
                        if (len(new_place)):
                            #取出上一条edit
                            (last_edit, last_current,
                             last_edited) = new_place[-1]
                            last_op, last_text = last_edit[0], last_edit[1:]
                            #                             if (last_op == '+' or last_op == ' '):
                            new_line_edited = last_current + 1
                            new_line_current = -1
                        #否则,因为该行edit是+,且该行在new中并没有出现,所以可直接使用start作为修改后的新位置
                        else:
                            new_line_current = -1
                            new_line_edited = start
                        #添加该行edit
                        new_place.append(
                            (edit1, new_line_current, new_line_edited))
                        log += "   add line is not in new,find a new place for this edit,add to new_place\n"
            else:  # (op == ' '): # merge line
                # a line to be merged by the patch should be at the specified location,
                # but may be elsewhere in the file. If self.find is True, we will look for it.
                # Doing so may return multiple matches.
                log += " merge line:\n"
                if (norm1 != norm3):
                    self._warn_msg(
                        '"merge"  line not found at %d: "%s"' %
                        (current, text1), 3)
                    warnings += 1
                    mismatches += [(index, ' ')]
                    log += "  merge line not in place,try to find it in new\n"
                    #找到new中修改前的位置
                    new_line_current = self._find_new_place(
                        text1, lines, current, filepath)
                    #如果在new中能找到该行
                    if (new_line_current != -1):
                        #在new中修改后的位置为相同位置
                        new_line_edited = new_line_current
                        #记录下该行edit的信息
                        new_place.append(
                            (edit1, new_line_current, new_line_edited))
                        log += "   find it,add to new_place\n"
                    #若new中不存在该行,则删除之
                    else:
                        log += "   not in new,delete this edit\n"
                        pass
                elif (self.mode == 'complete'):
                    self._ok_msg(
                        '"merge"  line found at %d: "%s"' % (current, text1),
                        3)
                    #若该行还在原处,添加该行edit的信息,不变即可
                    new_line_current = current
                    new_line_edited = current
                    new_place.append(
                        (edit1, new_line_current, new_line_edited))
                    log += "  merge line in place, add it to new_place\n"
                current += 1  # advance to next edit line

        #查找起始的修改前后新位置
        find_before = False
        find_after = False

        before_start = -1
        after_start = -1

        log += " find start's new place for this hunk,before and after edited\n"
        for (edit, before, after) in new_place:
            if (find_before == False and before != -1):
                before_start = before
                find_before = True
            if (find_after == False and after != -1):
                after_start = after
                find_after = True
            if (find_before and find_after):
                break

        #如果前后两条edit的修改前新位置之间还有中间部分,则将其添加进来作为merge lines
        last_before = 0
        last_after = 0
        log += " find some merge lines missed between two edits,add them\n"
        for i, (edit, before, after) in enumerate(new_place):
            if (i != 0 and before - last_before > 1):
                add = before + 1
                #这里可能会add超过lines范围?
                while (add < last_before and add < len(lines)):
                    add_line = lines[add]
                    add_text = ut.normalize_string(add_line)
                    new_place.insert(add, (" " + add_text, add, add))
                    add += 1
                    log += "   add lines...\n"
            last_before = before
            last_after = after

        #查找结束的修改前后新位置
        find_before = False
        find_after = False

        before_end = -1
        after_end = -1
        log += " find end's new place for this hunk,before and after edited\n"
        for (edit, before, after) in new_place[::-1]:
            if (find_before == False and before != -1):
                before_end = before
                find_before = True
            if (find_after == False and after != -1):
                after_end = after
                find_after = True
            if (find_before and find_after):
                break

        #计算修改前后的行数统计
        before_count = before_end - before_start + 1
        after_count = after_end - after_start + 1

        return (new_place, before_start, before_count, after_start,
                after_count, log)
Esempio n. 10
0
 def _check_hunk_edits(self, filepath, edits, start, count, note, lines):
     """ Check edits against the "a" file. Report errors when lines to be deleted
         or merged are missing, and when lines to be added are present. Note that
         patch lines and source lines may have the same text, but differ in leading
         whitespace. We strip and normalize the strings before testing them. 
         In 'find' mode, try to find missing lines.
     """
     errors = warnings = 0
     current = start
     mismatches = []
     
     for (index, edit1, edit2) in self._get_edits(edits):
         
         op, text1 = edit1[0], edit1[1:]
         norm1 = ut.normalize_string(text1)
         line  = lines[current - 1] # patch line numbers are 1-based
         norm3 = ut.normalize_string(line)
         
         if (edit2 is not None): # change request
             text2 = edit2[1:]
             norm2 = ut.normalize_string(text2)
             if (norm2 == norm3): # Change already applied
                 self._ok_msg('"after"  line found at %d: "%s"' % (current, text2), 3)
             elif (norm1 == norm3): # Change not yet applied
                 self._info_msg('"after"  line not found at %d: "%s"' % (current, text2), 3)
             else:
                 self._error_msg('"before"  line not found at %d: "%s"' % (current, text1), 3)
             current += 1 # advance to next edit line
                 
         elif (op == '-'): # delete line
             # A line to be deleted by the patch should be at the specified location,
             # but may be elsewhere in the file. If self.find is True, we will look for it.
             # Doing so may return multiple matches.
             if (norm1 != norm3):
                 self._error_msg('"delete" line not found at %d: "%s"' % (current, text1), 3)
                 mismatches += [(index, '-')]
             else:
                 if (self.mode == 'complete'):
                     self._ok_msg('"delete" line found at %d: "%s"' % (current, text1), 3)
             current += 1 # advance to next edit line
         
         elif (op == '+'): # insert line
             # A line to be inserted by the patch should not be at the specified location,
             # but may be elsewhere in the file. If self.find is True, we will look for
             # significant "add" lines below. Doing so may return multiple matches.
             if (norm1 == norm3):
                 self._error_msg('"add"    line found at %d: "%s"' % (current, text1), 3)
                 errors += 1
             else: 
                 if (self.mode == 'complete'):
                     self._info_msg('"add"    line not found at next line: "%s"' % text1, 3)
                 mismatches += [(index, '+')]
                              
         else: # (op == ' '): # merge line
             # a line to be merged by the patch should be at the specified location,
             # but may be elsewhere in the file. If self.find is True, we will look for it.
             # Doing so may return multiple matches.
             if (norm1 != norm3):
                 self._warn_msg('"merge"  line not found at %d: "%s"' % (current, text1), 3)
                 warnings += 1
                 mismatches += [(index, ' ')]
             elif (self.mode == 'complete'):
                 self._ok_msg('"merge"  line found at %d: "%s"' % (current, text1), 3)
             current += 1 # advance to next edit line                                 
     
     if ((len(mismatches) > 0) and self.find):   
         self._match(filepath, edits, lines, mismatches)
         return 1
     else:
         return 0