def compare(self): """ example: 深圳市福田区华富路1018号 vs 深川市福田区华富路1018号 :return: """ # 全部转换为全角字符 self.file = [ l.replace(' ', '').replace(',', ',').replace(';', ';').replace( ':', ':').replace('(', '(').replace(')', ')') for l in self.file ] self.to_file = [ l.replace(' ', '').replace(',', ',').replace(';', ';').replace( ':', ':').replace('(', '(').replace(')', ')') for l in self.to_file if l ] self.diff = difflib._mdiff(self.file, self.to_file, charjunk=is_char_junk) differences = {'changes': [], 'adds': [], 'subs': []} same_lines = [] diff_lines = [] for (_, line_a), (_, line_b), is_different in self.diff: # 拆包直接拆出需要的文字段落 if not is_different: same_lines.append(line_b) self.chars_counter.update_appear_time(line_b) else: chgs, adds, subs, line_a, line_b = self.char_diffs( line_a, line_b) if (not chgs) and (not adds) and (not subs): same_lines.append(line_b) self.chars_counter.update_appear_time(line_b) continue differences['changes'] += chgs differences['adds'] += adds differences['subs'] += subs diff_lines.append((line_a, line_b)) self.chars_counter.update_appear_time(line_b) self.chars_counter.update_miss(chgs, adds, subs) differences = {k: Counter(v) for k, v in differences.items()} self.chars_counter.summarize() s_no = len(same_lines) t_no = s_no + len(diff_lines) count_dict = { 'number of same lines:': s_no, 'number of total lines:': t_no, 'ratio of same:': round(s_no / t_no, 4) } self.diff_lines = diff_lines self.count_dict = count_dict self.differences = differences
def make_table(table_id, header, fromlines, tolines, context=None, versions=['old', 'new']): diff = list(difflib._mdiff(fromlines, tolines, context)) if not diff: return None same = lambda c, l, r: (c, l[0], r[0], 'l', format_line(l[1])) add = lambda c, l, r: (c, '', r[0], 'r', format_line(r[1])) sub = lambda c, l, r: (c, l[0], '', 'l', format_line(l[1])) html = TABLE_HEADER % tuple([table_id, header] + versions) for type, start, end in group_types(diff): if type == 'same': html += '<tbody>%s</tbody>\n' % \ merge_group(diff[start:end], same) elif type == 'add': html += '<tbody class="add">%s</tbody>\n' % \ merge_group(diff[start:end], add) elif type == 'del': html += '<tbody class="rem">%s</tbody>\n' % \ merge_group(diff[start:end], sub) elif type == 'mod': html += '<tbody class="mod">%s%s</tbody>\n' % \ (merge_group(diff[start:end], sub, end=False), merge_group(diff[start:end], add, start=False)) elif type == 'skipped': html += '<tbody class="skipped"><tr><th>...</th><th>...</th><td> </td></tr></tbody>\n' html += TABLE_FOOTER return html
def diff(self): if not self.field: return False if self.field.choices: # if a field is a choice field e.g. chars or ints used to represent a list of choices, # then its value is just that database, non-bilingual char/int value # fortunately model instances provide a hook for this func_name = f"get_{self.field.name}_display" last_original = getattr(self.last_original, func_name)() original = getattr(self.original, func_name)() else: last_original = getattr(self.last_original, self.field.name) original = getattr(self.original, self.field.name) if last_original is None: last_original = "empty" if original is None: original = "empty" # if isinstance(self.field,fields.MarkdownField): # return ( # escape(last_original), # escape(original) # ) mdiff = next( difflib._mdiff([escape(last_original)], [escape(original)])) return ( Diff.replace_diff_tags_with_html(mdiff[0][1]), Diff.replace_diff_tags_with_html(mdiff[1][1]), )
def html_diff_table(la, lb, context=None): all_changes = difflib._mdiff(la, lb) if context is None: changes = (format_changeset(*c) for c in all_changes) else: changes = [] q = deque() after_change = False for changeset in all_changes: q.append(changeset) if changeset[2]: after_change = True if not after_change: changes.append((0, '-----', 0, '-----', False)) changes.extend(format_changeset(*c) for c in q) q.clear() else: if len(q) == context and after_change: changes.extend(format_changeset(*c) for c in q) q.clear() after_change = False elif len(q) > context: q.popleft() return render_to_string("wiki/diff_table.html", { "changes": changes, })
def make_file(self, lhs, rhs): rows = [] for left, right, changed in difflib._mdiff( lhs, rhs, charjunk=difflib.IS_CHARACTER_JUNK): lno, ltxt = left rno, rtxt = right ltxt = self._stop_wasting_space(ltxt) rtxt = self._stop_wasting_space(rtxt) ltxt = self._trunc(ltxt, changed).replace(" ", " ") rtxt = self._trunc(rtxt, changed).replace(" ", " ") row = self._row_template % (str(lno), ltxt, str(rno), rtxt) rows.append(row) all_the_rows = "\n".join(rows) all_the_rows = all_the_rows.replace( "\x00+", '<span class="diff_add">').replace( "\x00-", '<span class="diff_sub">').replace( "\x00^", '<span class="diff_chg">').replace( "\x01", '</span>').replace("\t", 4 * " ") res = self._html_template % { "style": self._style, "rows": all_the_rows } return res
def getDiffDetails(self, fromdesc='', todesc='', context=False, numlines=5, tabSize=8): # change tabs to spaces before it gets more difficult after we insert # markkup def expand_tabs(line): # hide real spaces line = line.replace(' ','\0') # expand tabs into spaces line = line.expandtabs(tabSize) # replace spaces from expanded tabs back into tab characters # (we'll replace them with markup after we do differencing) line = line.replace(' ','\t') return line.replace('\0',' ').rstrip('\n') self.fromlines = [expand_tabs(line) for line in self.fromlines] self.tolines = [expand_tabs(line) for line in self.tolines] # create diffs iterator which generates side by side from/to data if context: context_lines = numlines else: context_lines = None diffs = difflib._mdiff(self.fromlines, self.tolines, context_lines, linejunk=None, charjunk=difflib.IS_CHARACTER_JUNK) return list(diffs)
def getDiffDetails(self, fromdesc='', todesc='', context=False, numlines=5, tabSize=8): # change tabs to spaces before it gets more difficult after we insert # markkup def expand_tabs(line): # hide real spaces line = line.replace(' ', '\0') # expand tabs into spaces line = line.expandtabs(tabSize) # replace spaces from expanded tabs back into tab characters # (we'll replace them with markup after we do differencing) line = line.replace(' ', '\t') return line.replace('\0', ' ').rstrip('\n') self.fromlines = [expand_tabs(line) for line in self.fromlines] self.tolines = [expand_tabs(line) for line in self.tolines] # create diffs iterator which generates side by side from/to data if context: context_lines = numlines else: context_lines = None diffs = difflib._mdiff(self.fromlines, self.tolines, context_lines, linejunk=None, charjunk=difflib.IS_CHARACTER_JUNK) return list(diffs)
def getDiffDetails( self, fromdesc='', todesc='', context=False, numlines=5, tabSize=8, ): def expand_tabs(line): line = line.replace(' ', '\0') line = line.expandtabs(tabSize) line = line.replace(' ', '\t') return line.replace('\0', ' ').rstrip('\n') self.fromlines = [expand_tabs(line) for line in self.fromlines] self.tolines = [expand_tabs(line) for line in self.tolines] # create diffs iterator which generates side by side from/to data if context: context_lines = numlines else: context_lines = None diffs = difflib._mdiff(self.fromlines, self.tolines, context_lines, linejunk=None, charjunk=difflib.IS_CHARACTER_JUNK) return list(diffs)
def sidebyside(fromlines, tolines, context): """Generate side by side diff""" # for some reason mdiff chokes on \n's in input lines def _stripnl(line): return line.rstrip("\n") fromlines = list(map(_stripnl, fromlines)) tolines = list(map(_stripnl, tolines)) had_changes = 0 gap = False for fromdata, todata, flag in difflib._mdiff(fromlines, tolines, context): if fromdata is None and todata is None and flag is None: gap = True else: from_item = _mdiff_split(flag, fromdata) to_item = _mdiff_split(flag, todata) had_changes = 1 yield _item(gap=ezt.boolean(gap), columns=(from_item, to_item), type="intraline") gap = False if not had_changes: yield _item(type=_RCSDIFF_NO_CHANGES)
def aligner(lines1, lines2): diffs = difflib._mdiff(lines1, lines2) fromlist, tolist, flaglist = [], [], [] # pull from/to data and flags from mdiff style iterator itercount = 0 for fromdata, todata, flag in diffs: try: # pad lists with "None" at empty lines to align both sides if todata[1].startswith('\0+') and fromdata[1].strip() == "": fromlist.append( None ) # if todata has an extra line, stuff fromlist with None else: fromlist.append(fromdata[1]) # otherwise append line if fromdata[1].startswith('\0-') and todata[1].strip() == "": tolist.append( None ) # if fromdata has an extra line, stuff tolist with None else: tolist.append(todata[1]) # otherwise append line except TypeError: # exceptions occur for lines where context separators go fromlist.append(None) tolist.append(None) flaglist.append(flag) #for l in fromlist: # print([l]) return fromlist, tolist, flaglist
def gen_diff_counts(text1, text2): htmldiffer = difflib.HtmlDiff() htmldiffer._make_prefix() text1, text2 = htmldiffer._tab_newline_replace(text1, text2) diffs = difflib._mdiff(fromlines=text1, tolines=text2) add_count = 0 beginwithadd = False endwithadd = False delete_count = 0 beginwithdelete = False endwithdelete = False change_count = 0 beginwithchange = False endwithchange = False for diff in diffs: print(diff) # print(diff[2])s if diff[2]: from_line = diff[0][1] to_line = diff[1][1] beg = "" if len(from_line) > 3: for i in range(1, len(from_line)): # delete if from_line[i - 1] == "\x00" and from_line[i] == "-": beg = from_line[i] if i == 1: beginwithdelete = True if from_line[i] == "\x01" and beg == "-": if not endwithdelete or not beginwithdelete: delete_count += 1 else: endwithdelete = False beg = "" if i == len(from_line) - 1: endwithdelete = True beg = "" if len(to_line) > 3: for i in range(1, len(to_line)): # add change if to_line[i - 1] == "\x00" and to_line[ i] == "+" or to_line[i] == "^": beg = to_line[i] if i == 1: if beg == "+": beginwithadd = True if beg == "^": beginwithchange = True if to_line[i] == "\x01": if beg == "^": if not endwithchange or not beginwithchange: change_count += 1 if i == len(to_line) - 1: endwithchange = True if beg == "+": if not beginwithadd or not endwithadd: add_count += 1 if i == len(to_line) - 1: endwithadd = True return {"add": add_count, "delete": delete_count, "change": change_count}
def count_diff(text1, text2): htmldiffer = difflib.HtmlDiff() htmldiffer._make_prefix() text1, text2 = htmldiffer._tab_newline_replace(text1, text2) diffs = difflib._mdiff(fromlines=text1, tolines=text2) # fromlist, tolist, flaglist = htmldiffer._collect_lines(diffs) # fromlist, tolist, flaglist, next_href, next_id = htmldiffer._convert_flags( # fromlist, tolist, flaglist, context=False,numlines=5) # print(fromlist) # print(tolist) # for i in range(len(fromlist)): # doc1 = pq(fromlist[i]) # print(doc1.text()) # for i in range(len(tolist)): # doc2 = pq(tolist[i]) # print(doc2.text()) # print(flaglist) # print(next_href) # print(next_id) flags = [] types = [] for diff in diffs: print(diff) # print(diff[2]) if diff[2]: f_line = diff[0][1] t_line = diff[1][1] if "\x00^" in f_line: flags.append("^") if "\x00-" in f_line: # print("-") flags.append("-") if "\x00+" in t_line: # print("+") flags.append("+") else: flags.append("&") add_count = 0 delete_count = 0 change_count = 0 pre_flag = flags[0] if pre_flag == "+": add_count += 1 elif pre_flag == "-": delete_count += 1 elif pre_flag == "^": change_count += 1 for i in range(1, len(flags)): now_page = flags[i] if now_page == "+" and now_page != pre_flag: add_count += 1 elif now_page == "-" and now_page != pre_flag: delete_count += 1 elif now_page == "^" and now_page != pre_flag: change_count += 1 pre_flag = now_page return {"add": add_count, "delete": delete_count, "change": change_count}
def get_diffs(a, b): fromlines = a.splitlines(keepends=False) tolines = b.splitlines(keepends=False) context_lines = None diffs = difflib._mdiff(fromlines, tolines, context_lines, linejunk=None, charjunk=difflib.IS_CHARACTER_JUNK) return list(diffs)
def diff_string_content_file(self): diff = difflib._mdiff(self.left_contents_lines, self.right_contents_lines) diff = list(diff) json = ContentDiffResultBuilder( self.file_name, self.left_file_object.file_path, self.right_file_object.file_path, self.left_file_object.modification_time, self.right_file_object.modification_time, diff).get_data() self.save_diff_json(json) return json.get(COMPARE_RESULT_HAS_CHANGES)
def make_table(self, fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5): """Generates table of side by side comparison with change highlights Arguments: fromlines -- list of "from" lines tolines -- list of "to" lines fromdesc -- "from" file column header string todesc -- "to" file column header string context -- set to True for contextual differences (defaults to False which shows full differences). numlines -- number of context lines. When context is set True, controls number of lines displayed before and after the change. When context is False, controls the number of lines to place the "next" link anchors before the next change (so click of "next" link jumps to just before the change). """ if context: context_lines = numlines else: context_lines = None # change tabs to spaces before it gets more difficult after we insert # markup fromlines, tolines = self._tab_newline_replace(fromlines, tolines) if self.strip_trailing_cr or (self._all_cr_nl(fromlines) and self._all_cr_nl(tolines)): fromlines = self._strip_trailing_cr(fromlines) tolines = self._strip_trailing_cr(tolines) # create diffs iterator which generates side by side from/to data diffs = difflib._mdiff(fromlines, tolines, context_lines, linejunk=self._linejunk, charjunk=self._charjunk) # set up iterator to wrap lines that exceed desired width if self._wrapcolumn: diffs = self._line_wrapper(diffs) diffs = self._collect_lines(diffs) for left, right in self._generate_table(fromdesc, todesc, diffs): yield self.colorize("%s %s" % (self._lpad(left, self.cols // 2 - 1), self._lpad(right, self.cols // 2 - 1)))
def pretty_diff(a, b, cols=None, fromdesc='', todesc='', context_lines=3): cols = terminal_width() if not cols else cols half_col = ( cols // 2) - 3 - 7 # 3 because of center ' | ', 7 because of line numbers a = [line.rstrip('\n') for line in a] b = [line.rstrip('\n') for line in b] table = _make_table(fromdesc, todesc, difflib._mdiff(a, b, context_lines)) for linenum, left, right in table: text = _colorize(f"{_rpad(left, half_col)} | {_rpad(right, half_col)}") yield _add_line_numbers(linenum, text)
def sbsdiff(a, b, linenumberwidth=4): """ Compare two sequences of lines; generate the delta for display side by side. @param a first sequence of lines (list of strings) @param b second sequence of lines (list of strings) @param linenumberwidth width (in characters) of the linenumbers (integer) @return a generator yielding tuples of differences. The tuple is composed of strings as follows. <ul> <li>opcode -- one of e, d, i, r for equal, delete, insert, replace</li> <li>lineno a -- linenumber of sequence a</li> <li>line a -- line of sequence a</li> <li>lineno b -- linenumber of sequence b</li> <li>line b -- line of sequence b</li> </ul> """ def removeMarkers(line): """ Internal function to remove all diff markers. @param line line to work on (string) @return line without diff markers (string) """ return line\ .replace('\0+', "")\ .replace('\0-', "")\ .replace('\0^', "")\ .replace('\1', "") linenumberformat = "{{0:{0:d}d}}".format(linenumberwidth) emptylineno = ' ' * linenumberwidth for (ln1, l1), (ln2, l2), flag in _mdiff(a, b, None, None, IS_CHARACTER_JUNK): if not flag: yield ('e', linenumberformat.format(ln1), l1, linenumberformat.format(ln2), l2) continue if ln2 == "" and l2 == "\n": yield ('d', linenumberformat.format(ln1), removeMarkers(l1), emptylineno, '\n') continue if ln1 == "" and l1 == "\n": yield ('i', emptylineno, '\n', linenumberformat.format(ln2), removeMarkers(l2)) continue yield ('r', linenumberformat.format(ln1), l1, linenumberformat.format(ln2), l2)
def diff_content(self, from_text, to_text, message=u''): """Generate the HTML markup for a diff.""" def infiniter(iterator): """Turn an iterator into an infinite one, padding it with None""" for i in iterator: yield i while True: yield None diff = difflib._mdiff(from_text.split('\n'), to_text.split('\n')) mark_re = re.compile('\0[-+^]([^\1\0]*)\1|([^\0\1])') yield message yield u'<pre class="diff">' for old_line, new_line, changed in diff: old_no, old_text = old_line new_no, new_text = new_line line_no = (new_no or old_no or 1) - 1 if changed: yield u'<div class="change" id="line_%d">' % line_no old_iter = infiniter(mark_re.finditer(old_text)) new_iter = infiniter(mark_re.finditer(new_text)) old = old_iter.next() new = new_iter.next() buff = u'' while old or new: while old and old.group(1): if buff: yield werkzeug.escape(buff) buff = u'' yield u'<del>%s</del>' % werkzeug.escape(old.group(1)) old = old_iter.next() while new and new.group(1): if buff: yield werkzeug.escape(buff) buff = u'' yield u'<ins>%s</ins>' % werkzeug.escape(new.group(1)) new = new_iter.next() if new: buff += new.group(2) old = old_iter.next() new = new_iter.next() if buff: yield werkzeug.escape(buff) yield u'</div>' else: yield u'<div class="orig" id="line_%d">%s</div>' % ( line_no, werkzeug.escape(old_text)) yield u'</pre>'
def gen_html(filename, funcname): offset0 = lookup(filename, funcname, V0_MANIFEST) offset1 = lookup(filename, funcname, V1_MANIFEST) assert offset0 != -1 and offset1 != -1 loc0 = gen_gcc(filename, funcname, V0_CODE, offset0, V0_BUILD, TMP_V0_GCC+EXT1) loc1 = gen_gcc(filename, funcname, V1_CODE, offset1, V1_BUILD, TMP_V1_GCC+EXT1) gum = check_output(['java', '-jar', '/home/wxjin11/gumtree/client/target/gumtree.jar', '-o', 'tag', TMP_V0_GCC, TMP_V1_GCC]) # print gum gum_dict = parse_gum(gum) code0 = extract_code(filename, loc0, V0_CODE) code1 = extract_code(filename, loc1, V1_CODE) diff = list(difflib._mdiff(code0, code1)) # print gum_dict merge_mark(gum_dict, diff, loc0, loc1)
def _make_table(self, a, b): self.setRowCount(0) al, bl = [], [] bn = 1 for ar, br, flag in difflib._mdiff(a.splitlines(keepends=True), b.splitlines(keepends=True), context=2): if flag is None: self.insertRow(self.rowCount()) self.setItem(self.rowCount() - 1, 0, self._table_item()) self.setItem(self.rowCount() - 1, 1, self._table_item('...')) self.setItem(self.rowCount() - 1, 2, self._table_item('...')) self.setItem(self.rowCount() - 1, 3, self._table_item('(생략)', center=False)) else: an, at = ar bn, bt = br if flag: if type(an) is int: al.append([str(an), at]) if type(bn) is int: bl.append([str(bn), bt]) else: self._insert_merged( al, bl) # flag가 True일 때 모아둔 al, bl을 표에 실제 입력 al, bl = [], [] self.insertRow(self.rowCount()) self.setItem(self.rowCount() - 1, 0, self._table_item()) self.setItem(self.rowCount() - 1, 1, self._table_item(str(an))) self.setItem(self.rowCount() - 1, 2, self._table_item(str(bn))) self.setItem( self.rowCount() - 1, 3, self._table_item((lambda x: x[:-1] if x.endswith('\n') else x)(at), center=False)) self._insert_merged(al, bl) if self.rowCount() == 0: self.insertRow(0) self.setItem(0, 3, self._table_item('변경 사항이 없습니다.', False)) elif type(bn) is int and bn < len( b.splitlines()): # 맨 마지막에 생략 표시가 자동으로 안 됨 self.insertRow(self.rowCount()) self.setItem(self.rowCount() - 1, 0, self._table_item()) self.setItem(self.rowCount() - 1, 1, self._table_item('...')) self.setItem(self.rowCount() - 1, 2, self._table_item('...')) self.setItem(self.rowCount() - 1, 3, self._table_item('(생략)', center=False))
def diff_content(self, from_text, to_text, message=''): """Generate the HTML markup for a diff.""" def infiniter(iterator): """Turn an iterator into an infinite one, padding it with None""" for i in iterator: yield i while True: yield None diff = difflib._mdiff(from_text.split('\n'), to_text.split('\n')) mark_re = re.compile('\0[-+^]([^\1\0]*)\1|([^\0\1])') yield message yield '<pre class="diff">' for old_line, new_line, changed in diff: old_no, old_text = old_line new_no, new_text = new_line line_no = (new_no or old_no or 1) - 1 if changed: yield '<div class="change" id="line_%d">' % line_no old_iter = infiniter(mark_re.finditer(old_text)) new_iter = infiniter(mark_re.finditer(new_text)) old = next(old_iter) new = next(new_iter) buff = '' while old or new: while old and old.group(1): if buff: yield werkzeug.escape(buff) buff = '' yield '<del>%s</del>' % werkzeug.escape(old.group(1)) old = next(old_iter) while new and new.group(1): if buff: yield werkzeug.escape(buff) buff = '' yield '<ins>%s</ins>' % werkzeug.escape(new.group(1)) new = next(new_iter) if new: buff += new.group(2) old = next(old_iter) new = next(new_iter) if buff: yield werkzeug.escape(buff) yield '</div>' else: yield '<div class="orig" id="line_%d">%s</div>' % ( line_no, werkzeug.escape(old_text)) yield '</pre>'
def html_diff(from_sequence, to_sequence, linejunk=None, charjunk=None): diffs = _mdiff(from_sequence, to_sequence, linejunk=linejunk, charjunk=charjunk) from_list = [] to_list = [] for from_data, to_data, flag in diffs: from_list.append(_markup(_unescape(from_data[1]))) to_list.append(_markup(_unescape(to_data[1]))) return from_list, to_list
def mdiff(self): r"""The difflib._mdiff() function returns an interator which returns a tuple: (from line tuple, to line tuple, boolean flag) from/to line tuple -- (line num, line text) line num -- integer or None (to indicate a context separation) line text -- original line text with following markers inserted: '\0+' -- marks start of added text '\0-' -- marks start of deleted text '\0^' -- marks start of changed text '\1' -- marks end of added/deleted/changed text boolean flag -- None indicates context separation, True indicates either "from" or "to" line contains a change, otherwise False. """ return difflib._mdiff(self._get_old_text(), self._get_new_text())
def format_diff(self, fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5, *, charset='utf-8'): self._make_prefix() # change tabs to spaces before it gets more difficult after we insert # markup fromlines, tolines = self._tab_newline_replace(fromlines, tolines) # create diffs iterator which generates side by side from/to data if context: context_lines = numlines else: context_lines = None diffs = difflib._mdiff(fromlines, tolines, context_lines, linejunk=self._linejunk, charjunk=self._charjunk) return list(diffs)
def sidebyside(fromlines, tolines, context): """Generate side by side diff""" ### for some reason mdiff chokes on \n's in input lines line_strip = lambda line: line.rstrip("\n") fromlines = map(line_strip, fromlines) tolines = map(line_strip, tolines) gap = False for fromdata, todata, flag in difflib._mdiff(fromlines, tolines, context): if fromdata is None and todata is None and flag is None: gap = True else: from_item = _mdiff_split(flag, fromdata) to_item = _mdiff_split(flag, todata) yield _item(gap=ezt.boolean(gap), columns=(from_item, to_item)) gap = False
def gen_html(filename, funcname, o): S0 = sys.argv[1] S1 = sys.argv[2] #print S0,S1 global V0_CODE, V1_CODE, V0_MANIFEST, V1_MANIFEST V0_CODE = '/tmp/' + S0 + '/' V1_CODE = '/tmp/' + S1 + '/' V0_MANIFEST = '/tmp/V-' + S0 V1_MANIFEST = '/tmp/V-' + S1 V0_BUILD = '/tmp/build-' + S0 + '-allno' V1_BUILD = '/tmp/build-' + S1 + '-allno' TMP_V0_GCC = '/tmp/tmp-' + S0 + '.c' TMP_V1_GCC = '/tmp/tmp-' + S1 + '.c' #print TMP_V0_GCC offset0 = lookup(filename, funcname, V0_MANIFEST) offset1 = lookup(filename, funcname, V1_MANIFEST) #print TMP_V0_GCC,TMP_V1_GCC if offset0 == -1 or offset1 == -1: print 'Your config is wrong!' return assert offset0 != -1 and offset1 != -1 # print("see2"); #print V1_CODE; # print offset1 # print V1_BUILD,TMP_V1_GCC+EXT1 loc0 = gen_gcc(filename, funcname, V0_CODE, offset0, V0_BUILD, TMP_V0_GCC + EXT1) loc1 = gen_gcc(filename, funcname, V1_CODE, offset1, V1_BUILD, TMP_V1_GCC + EXT1) # print ("see3"); gum = check_output([ 'java', '-jar', '/usr/local/share/cg-rtl/lxr/gumtree.jar', '-o', 'tag', TMP_V0_GCC, TMP_V1_GCC ]) # print gum ret_gum = (gum != '-----\n') # print ("see4"); #print ret_gum gum_dict = parse_gum(gum) code0 = extract_code(filename, loc0, V0_CODE) code1 = extract_code(filename, loc1, V1_CODE) # print code0,code1 diff = list(difflib._mdiff(code0, code1)) # print gum_dict ret_diff = merge_mark(gum_dict, diff, loc0, loc1, o) return ret_gum, ret_diff
def make_table(self, a, b, adesc=None, bdesc=None, context=5): """Make html table that displays side-by-side diff Arguments: - a -- list of text lines to be compared to b - b -- list of text lines to be compared to a - adesc -- description of the 'a' lines (e.g. filename) - bdesc -- description of the 'b' lines (e.g. filename) - context -- number of context lines to display Uses difflib._mdiff function to generate diff. """ adesc = adesc or '' bdesc = bdesc or '' diff = difflib._mdiff(a, b, context=context) lines = [self._make_line(d) for d in diff] return self.table_tmpl % (adesc, bdesc, '\n'.join(lines))
def make_table(self, fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5): """Generates table of side by side comparison with change highlights Arguments: fromlines -- list of "from" lines tolines -- list of "to" lines fromdesc -- "from" file column header string todesc -- "to" file column header string context -- set to True for contextual differences (defaults to False which shows full differences). numlines -- number of context lines. When context is set True, controls number of lines displayed before and after the change. When context is False, controls the number of lines to place the "next" link anchors before the next change (so click of "next" link jumps to just before the change). """ if context: context_lines = numlines else: context_lines = None # change tabs to spaces before it gets more difficult after we insert # markup fromlines, tolines = self._tab_newline_replace(fromlines, tolines) if self.strip_trailing_cr or ( self._all_cr_nl(fromlines) and self._all_cr_nl(tolines)): fromlines = self._strip_trailing_cr(fromlines) tolines = self._strip_trailing_cr(tolines) # create diffs iterator which generates side by side from/to data diffs = difflib._mdiff(fromlines, tolines, context_lines, linejunk=self._linejunk, charjunk=self._charjunk) # set up iterator to wrap lines that exceed desired width if self._wrapcolumn: diffs = self._line_wrapper(diffs) diffs = self._collect_lines(diffs) for left, right in self._generate_table(fromdesc, todesc, diffs): yield self.colorize( "%s %s" % (self._lpad(left, self.cols // 2 - 1), self._lpad(right, self.cols // 2 - 1)))
def text_diff(self, text1, text2): """ 文本比对 :param text1: :param text2: :return: """ htmldiffer = difflib.HtmlDiff() htmldiffer._make_prefix() text1, text2 = htmldiffer._tab_newline_replace(text1, text2) diffs = difflib._mdiff(fromlines=text1, tolines=text2) # if self._wrapcolumn: # diffs = htmldiffer._line_wrapper(diffs) # for diff in diffs: # print(diff) # fromlist, tolist, flaglist = htmldiffer._collect_lines(diffs) # print(fromlist) return diffs
def asTable(self): table = Table().addClass('diff-table') headers = Row().addCell(Th()).addCell(Th('Submission')) headers.addCell(Th()).addCell(Th('Solution')) table.addHeader(headers) num_changes = 0 for diff in difflib._mdiff(self.fromlines, self.tolines): fromline, toline, hasChange = diff row = Row() # tag tag = '' if hasChange: num_changes+=1 tag = str(Anchor().setName(num_changes).addClass('diff-anchor')) # from line_num, text = fromline line_num = line_num if len(str(line_num)) > 0 else ' ' row.addCell(Td(Div(tag+str(line_num))) .addClass('diff-cell') .addClass('line-number')) row.addCell(Td(self.prepare(0, text)) .addClass('diff-cell') .addClass('line-text')) # to line_num, text = toline line_num = line_num if len(str(line_num)) > 0 else ' ' row.addCell(Td(Div(line_num)) .addClass('diff-cell') .addClass('line-number')) row.addCell(Td(self.prepare(1, text)) .addClass('diff-cell') .addClass('line-text')) table.addRow(row) return str(table), num_changes
def diff(self): left_diff = self.diff_array[0] right_diff = self.diff_array[1] if left_diff == "": self.left_result = "" self.right_result = RulesetDiffOneSideResultBuilder( right_diff).get_data() elif right_diff == "": self.right_result = "" self.left_result = RulesetDiffOneSideResultBuilder( left_diff).get_data() else: diff = difflib._mdiff(left_diff, right_diff) diff_list = list(diff) left_row_object = RulesetDiffResultBuilder(diff_list, True) right_row_object = RulesetDiffResultBuilder(diff_list, False) self.left_result = left_row_object.get_data() self.right_result = right_row_object.get_data()
def sidebyside(fromlines, tolines, context): """Generate side by side diff""" ### for some reason mdiff chokes on \n's in input lines line_strip = lambda line: line.rstrip("\n") fromlines = map(line_strip, fromlines) tolines = map(line_strip, tolines) had_changes = 0 gap = False for fromdata, todata, flag in difflib._mdiff(fromlines, tolines, context): if fromdata is None and todata is None and flag is None: gap = True else: from_item = _mdiff_split(flag, fromdata) to_item = _mdiff_split(flag, todata) had_changes = 1 yield _item(gap=ezt.boolean(gap), columns=(from_item, to_item), type="intraline") gap = False if not had_changes: yield _item(type=_RCSDIFF_NO_CHANGES)
def get_lines(self): # `readlines` because `difflib._mdiff` can't operate on a generator with open(self.old_filename, 'r') as old_file: old_lines = old_file.readlines() with open(self.new_filename, 'r') as new_file: new_lines = new_file.readlines() yield self._format_file_header() # Determine line number column widths; note: in some cases this is # unnecessarily wide (e.g. if changes only in beginning of a long file) old_ln_width = len(str(len(old_lines))) new_ln_width = len(str(len(new_lines))) mdiff = difflib._mdiff(old_lines, new_lines, context=self.context) # `mdiff` context separators don't have the metadata necessary to generate # git-diff-like hunk headers (`@@ -%d,%d @@` and `@@ +%d,%d @@`), so we # partition `mdiff` into hunks and process each one separately for hunk in self._get_hunks(mdiff): for line in self._format_hunk(hunk, old_ln_width, new_ln_width): yield line
def getdiff(seq1list, seq2list, args, file1=file1, file2=file2, header=False): diff = "" if args.side: w, _ = terminal_size() numline = None if args.context: numline = args.lines diffs = difflib._mdiff(seq1list, seq2list, numline) width = int(w / 2.4) - 2 if header: print(('\n{lside:{width}}{flag:^5}{rside:{width}}').format( lside=file1, rside=file2, width=width, flag=" ")) # print(('\n{:%d.%d}{}{:%d.%d}' % # (width, width, width, width)).format(file1, file2)) for fl, tl, flag in diffs: flag = "!" if flag else " " if fl and tl: lside = str(fl[-1]).strip().replace('\0', "|").replace( '\1', "|").replace("\n", "") rside = str(tl[-1]).strip().replace('\0', "|").replace( '\1', "|").replace("\n", "") if args.color: lside = lside.replace('|+', color.ADD).replace( '|-', color.DEL).replace('|^', color.SUB).replace('|', color.END) rside = rside.replace('|+', color.ADD).replace( '|-', color.DEL).replace('|^', color.SUB).replace('|', color.END) if lside or rside: line2 = ('{lside:{width}}{flag:^5}{rside:{width}}').format( lside=lside, rside=rside, width=width, flag=flag) print(line2)
def count_diff(self, text1, text2): """ 按字比对后统计 :param text1: :param text2: :return: """ htmldiffer = difflib.HtmlDiff() htmldiffer._make_prefix() text1, text2 = htmldiffer._tab_newline_replace(text1, text2) diffs = difflib._mdiff(fromlines=text1, tolines=text2) froms, tos, fsflags, flags = convert_diffs(diffs) flags = fsflags add_count = 0 delete_count = 0 change_count = 0 pre_flag = flags[0] if pre_flag == "+": add_count += 1 elif pre_flag == "-": delete_count += 1 elif pre_flag == "^": change_count += 1 for i in range(1, len(flags)): now_page = flags[i] if now_page == "+" and now_page != pre_flag: add_count += 1 elif now_page == "-" and now_page != pre_flag: delete_count += 1 elif now_page == "^" and now_page != pre_flag: change_count += 1 pre_flag = now_page return { "add": add_count, "delete": delete_count, "change": change_count }
def _get_mdiff(lines): ''' return difflib._mdiff generator ''' old = _get_old(lines) new = _get_new(lines) return difflib._mdiff(old, new)
def test_mdiff_catch_stop_iteration(self): # Issue #33224 self.assertEqual( list(difflib._mdiff(["2"], ["3"], 1)), [((1, '\x00-2\x01'), (1, '\x00+3\x01'), True)], )
def make_table( self, fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5 ): """Returns table of side by side comparison with change highlights Arguments: fromlines -- list of "from" lines tolines -- list of "to" lines fromdesc -- "from" file column header string todesc -- "to" file column header string context -- set to True for contextual differences (defaults to False which shows full differences). numlines -- number of context lines. When context is set True, controls number of lines displayed before and after the change. When context is False, controls the number of lines to place the "next" link anchors before the next change (so click of "next" link jumps to just before the change). """ # change tabs to spaces before it gets more difficult after we insert # markkup fromlines, tolines = self._tab_newline_replace( fromlines, tolines ) # create diffs iterator which generates side by side from/to data if context: context_lines = numlines else: context_lines = None diffs = difflib._mdiff( fromlines, tolines, context_lines, linejunk=self._linejunk, charjunk=self._charjunk ) # set up iterator to wrap lines that exceed desired width if self._wrapcolumn: diffs = self._line_wrapper( diffs ) # collect up from/to lines and flags into lists (also format the lines) fromlist, tolist, flaglist = self._collect_lines( diffs ) # process change flags, generating middle column of next anchors/links fromlist, tolist, flaglist, next_href, next_id = self._convert_flags( fromlist, tolist, flaglist, context, numlines ) s = [] if fromdesc or todesc: s.append( ( fromdesc, todesc ) ) for i in range( len( flaglist ) ): if flaglist[i] is None: # mdiff yields None on separator lines skip the bogus ones # generated for the first line if i > 0: s.append( ( '---', '---' ) ) else: s.append( ( fromlist[i], tolist[i] ) ) table_lines = [] for sides in s: line = [] for side in sides: line.append( self._lpad( side, self.cols / 2 - 1 ) ) table_lines.append( " ".join( line ) ) table_line_string = "\n".join( table_lines ) colorized_table_line_string = self.colorize( table_line_string ) return colorized_table_line_string
def mdiff(old, new): return difflib._mdiff(old, new)
def make_table( self, fromlines, tolines, fromdesc='', todesc='', context=False, numlines=5 ): """Returns HTML table of side by side comparison with change highlights Arguments: fromlines -- list of "from" lines tolines -- list of "to" lines fromdesc -- "from" file column header string todesc -- "to" file column header string context -- set to True for contextual differences (defaults to False which shows full differences). numlines -- number of context lines. When context is set True, controls number of lines displayed before and after the change. When context is False, controls the number of lines to place the "next" link anchors before the next change (so click of "next" link jumps to just before the change). """ # make unique anchor prefixes so that multiple tables may exist # on the same page without conflict. self._make_prefix() # change tabs to spaces before it gets more difficult after we insert # markup fromlines, tolines = self._tab_newline_replace(fromlines, tolines) # create diffs iterator which generates side by side from/to data if context: context_lines = numlines else: context_lines = None diffs = _mdiff( fromlines, tolines, context_lines, linejunk=self._linejunk, charjunk=self._charjunk ) # set up iterator to wrap lines that exceed desired width if self._wrapcolumn: diffs = self._line_wrapper(diffs) # collect up from/to lines and flags into lists (also format the lines) fromlist, tolist, flaglist = self._collect_lines(diffs) # process change flags, generating middle column of next anchors/links fromlist, tolist, flaglist, next_href, next_id = self._convert_flags( fromlist, tolist, flaglist, context, numlines ) s = [] fmt = ' <tr>%s%s</tr>\n' for i in range(len(flaglist)): if flaglist[i] is None: # mdiff yields None on separator lines skip the bogus ones # generated for the first line if i > 0: s.append(' </tbody> \n <tbody>\n') else: s.append(fmt % (fromlist[i], tolist[i])) if fromdesc or todesc: header_row = '<thead><tr>%s%s</tr></thead>' % ( '<th colspan="2" class="diff_header">%s</th>' % fromdesc, '<th colspan="2" class="diff_header">%s</th>' % todesc ) else: header_row = '' table = self._table_template % dict( data_rows=''.join(s), header_row=header_row, prefix=self._prefix[1] ) return ( table.replace('\0+', '<span class="diff_add">').replace( '\0-', '<span class="diff_sub">' ).replace('\0^', '<span class="diff_chg">').replace( '\1', '</span>' ).replace('\t', ' ') )