Commit 02ef28b9 authored by Guido van Rossum's avatar Guido van Rossum

Tim Peters writes:

I should have waited overnight <wink/sigh>.  Nothing wrong with the one I
sent, but I couldn't resist going on to add new -r1 / -r2 cmdline options
for recreating the original files from ndiff's output.  That's attached, if
you're game!  Us Windows guys don't usually have a sed sitting around
<wink>.
parent a3433e89
#! /usr/bin/env python #! /usr/bin/env python
# Module ndiff version 1.3.0 # Module ndiff version 1.4.0
# Released to the public domain 26-Mar-1999, # Released to the public domain 27-Mar-1999,
# by Tim Peters (tim_one@email.msn.com). # by Tim Peters (tim_one@email.msn.com).
# Provided as-is; use at your own risk; no warranty; no promises; enjoy! # Provided as-is; use at your own risk; no warranty; no promises; enjoy!
"""ndiff [-q] file1 file2 """ndiff [-q] file1 file2
or
ndiff (-r1 | -r2) < ndiff_output > file1_or_file2
Print a human-friendly file difference report to stdout. Both inter- Print a human-friendly file difference report to stdout. Both inter-
and intra-line differences are noted. and intra-line differences are noted. In the second form, recreate file1
(-r1) or file2 (-r2) on stdout, from an ndiff report on stdin.
If -q ("quiet") is not specified, the first two lines of output are In the first form, if -q ("quiet") is not specified, the first two lines
of output are
-: file1 -: file1
+: file2 +: file2
...@@ -24,22 +28,22 @@ Each remaining line begins with a two-letter code: ...@@ -24,22 +28,22 @@ Each remaining line begins with a two-letter code:
"? " line not present in either input file "? " line not present in either input file
Lines beginning with "? " attempt to guide the eye to intraline Lines beginning with "? " attempt to guide the eye to intraline
differences, and were not present in either input file. differences, and were not present in either input file. These lines can
be confusing if the source files contain tab characters.
The first file can be recovered by retaining only lines that begin with The first file can be recovered by retaining only lines that begin with
" " or "- ", and deleting those 2-character prefixes. " " or "- ", and deleting those 2-character prefixes; use ndiff with -r1.
The second file can be recovered similarly, but by retaining only " " The second file can be recovered similarly, but by retaining only " "
and "+ " lines. On Unix, the second file can be recovered by piping the and "+ " lines; use ndiff with -r2; or, on Unix, the second file can be
output through recovered by piping the output through
sed -n '/^[+ ] /s/^..//p' sed -n '/^[+ ] /s/^..//p'
Modifications to recover the first file are left as an exercise for
the reader.
See module comments for details and programmatic interface. See module comments for details and programmatic interface.
""" """
__version__ = 1, 3, 0 __version__ = 1, 4, 0
# SequenceMatcher tries to compute a "human-friendly diff" between # SequenceMatcher tries to compute a "human-friendly diff" between
# two sequences (chiefly picturing a file as a sequence of lines, # two sequences (chiefly picturing a file as a sequence of lines,
...@@ -324,7 +328,7 @@ class SequenceMatcher: ...@@ -324,7 +328,7 @@ class SequenceMatcher:
if k: if k:
if alo < i and blo < j: if alo < i and blo < j:
self.__helper(alo, i, blo, j, answer) self.__helper(alo, i, blo, j, answer)
answer.append( x ) answer.append(x)
if i+k < ahi and j+k < bhi: if i+k < ahi and j+k < bhi:
self.__helper(i+k, ahi, j+k, bhi, answer) self.__helper(i+k, ahi, j+k, bhi, answer)
...@@ -528,14 +532,20 @@ def fancy_helper(a, alo, ahi, b, blo, bhi): ...@@ -528,14 +532,20 @@ def fancy_helper(a, alo, ahi, b, blo, bhi):
elif blo < bhi: elif blo < bhi:
dump('+', b, blo, bhi) dump('+', b, blo, bhi)
def fail(msg):
import sys
out = sys.stderr.write
out(msg + "\n\n")
out(__doc__)
return 0
# open a file & return the file object; gripe and return 0 if it # open a file & return the file object; gripe and return 0 if it
# couldn't be opened # couldn't be opened
def fopen(fname): def fopen(fname):
try: try:
return open(fname, 'r') return open(fname, 'r')
except IOError, detail: except IOError, detail:
print "couldn't open " + fname + ": " + str(detail) return fail("couldn't open " + fname + ": " + str(detail))
return 0
# open two files & spray the diff to stdout; return false iff a problem # open two files & spray the diff to stdout; return false iff a problem
def fcompare(f1name, f2name): def fcompare(f1name, f2name):
...@@ -568,33 +578,52 @@ def fcompare(f1name, f2name): ...@@ -568,33 +578,52 @@ def fcompare(f1name, f2name):
def main(args): def main(args):
import getopt import getopt
try: try:
opts, args = getopt.getopt(args, "q") opts, args = getopt.getopt(args, "qr:")
except getopt.error, detail: except getopt.error, detail:
print str(detail) return fail(str(detail))
print __doc__
return 0
noisy = 1 noisy = 1
qseen = rseen = 0
for opt, val in opts: for opt, val in opts:
if opt == "-q": if opt == "-q":
qseen = 1
noisy = 0 noisy = 0
elif opt == "-r":
rseen = 1
whichfile = val
if qseen and rseen:
return fail("can't specify both -q and -r")
if rseen:
if args:
return fail("no args allowed with -r option")
if whichfile in "12":
restore(whichfile)
return 1
return fail("-r value must be 1 or 2")
if len(args) != 2: if len(args) != 2:
print 'need 2 args' return fail("need 2 filename args")
print __doc__
return 0
f1name, f2name = args f1name, f2name = args
if noisy: if noisy:
print '-:', f1name print '-:', f1name
print '+:', f2name print '+:', f2name
return fcompare(f1name, f2name) return fcompare(f1name, f2name)
def restore(which):
import sys
tag = {"1": "- ", "2": "+ "}[which]
prefixes = (" ", tag)
for line in sys.stdin.readlines():
if line[:2] in prefixes:
print line[2:],
if __name__ == '__main__': if __name__ == '__main__':
import sys import sys
args = sys.argv[1:] args = sys.argv[1:]
if 1: if "-profile" in args:
main(args)
else:
import profile, pstats import profile, pstats
args.remove("-profile")
statf = "ndiff.pro" statf = "ndiff.pro"
profile.run("main(args)", statf) profile.run("main(args)", statf)
stats = pstats.Stats(statf) stats = pstats.Stats(statf)
stats.strip_dirs().sort_stats('time').print_stats() stats.strip_dirs().sort_stats('time').print_stats()
else:
main(args)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment