From: <sv...@ww...> - 2004-06-06 01:46:47
|
Author: mkrose Date: 2004-06-05 18:46:40 -0700 (Sat, 05 Jun 2004) New Revision: 995 Added: trunk/CSP/tools/undiff Modified: trunk/CSP/base/app.py Log: Add a tool for splitting a diff file into two files that resemble the orignal files used to create the diff. Also minor tweaks to app.py: print a blank line after usage, and add a fatal(msg) method that prints to stderr and terminates the program. Modified: trunk/CSP/base/app.py =================================================================== --- trunk/CSP/base/app.py 2004-06-05 23:39:52 UTC (rev 994) +++ trunk/CSP/base/app.py 2004-06-06 01:46:40 UTC (rev 995) @@ -85,7 +85,13 @@ def usage(): """Print usage to stdout.""" opt.print_help() + print +def fatal(msg): + """Print an error message to stderr and terminate with exit code 1.""" + print >>sys.stderr, msg + sys.exit(1) + def programPath(): """Return the absolute path of the application program.""" return os.path.abspath(sys.argv[0]) Added: trunk/CSP/tools/undiff =================================================================== --- trunk/CSP/tools/undiff 2004-06-05 23:39:52 UTC (rev 994) +++ trunk/CSP/tools/undiff 2004-06-06 01:46:40 UTC (rev 995) @@ -0,0 +1,130 @@ +#!/usr/bin/python +# +# Copyright 2004 Mark Rose <mk...@us...> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +""" +%(prog)s: A tool for splitting a unified diffs. + +Takes a unified diff as input and produces two output files that approximate +the files used to create the diff. Regions between diff hunks are padded by +blank lines. Useful for graphical diff tools that require two input files. + +Usage: %(prog)s [options] diff + +The output files are either written to the paths specified by the --output1 +and --output2 flags, or the output filenames will be generated from contents +of the diff and placed in the directory specified by --outdir. In the latter +case, the names of the output files are printed to stdout in the format +"output1 output2". +""" + +import sys +import os + +import bootstrap +from CSP.base import app + + +app.addOption('--output1', metavar='PATH', default='', help='output path for original file') +app.addOption('--output2', metavar='PATH', default='', help='output path for modified file') +app.addOption('--outdir', metavar='DIR', default='', help='output directory') +app.addOption('-f', '--force', action='store_true', default=False, help='overwrite existing output files') + + +def main(args): + if len(args) != 1: + app.usage() + return 1 + diff = args[0] + undiff(diff) + return 0 + + +def output(name): + if app.options.output1 or app.options.output2: + out1 = app.options.output1 + out2 = app.options.output2 + if not out1 or not out2: + app.fatal('Must specify both --output1 and --output2') + if app.options.outdir: + app.fatal('Cannot use the --outdir flag with --output1 and --output2') + else: + path = app.options.outdir + if not path: + app.fatal('Must either specify --outdir, or --output1 and --output2.') + if not os.path.exists(path) or not os.path.isdir(path): + app.fatal('The path specified by --outdir must be a valid directory.') + if not name: name = 'diff' + name = name.replace(os.sep, '~') + out = os.path.join(path, name) + out1 = out + '.1' + out2 = out + '.2' + print '%s %s' % (out1, out2) + if not app.options.force: + for outpath in (out1, out2): + if os.path.exists(outpath): + app.fatal('Output path "%s" exists (use --force to overwrite); aborting.' % outpath) + return open(out1, 'w'), open(out2, 'w') + + +def undiff(diff): + count1 = 0 + count2 = 0 + skip = 2 + for i, line in enumerate(open(diff).readlines()): + if i == 0: + if line.startswith('Index: '): + out1, out2 = output(line.split()[1]) + skip += 1 + continue + else: + out1, out2 = output('') + if i == 1 and line.startswith('================================='): + skip += 1 + continue + if i < skip: + assert line.startswith('--- ') or line.startswith('+++ ') + continue + if line.startswith('@@ '): + parts = line.split() + block1, block2 = parts[1:3] + line1 = int(block1.split(',')[0][1:]) + line2 = int(block2.split(',')[0][1:]) + for n in range(count1, line1): out1.write('\n') + for n in range(count2, line2): out2.write('\n') + count1 = line1 + count2 = line2 + continue + if line.startswith('-'): + out1.write(line[1:]) + count1 += 1 + continue + if line.startswith('+'): + out2.write(line[1:]) + count2 += 1 + continue + out1.write(line[1:]) + count1 += 1 + out2.write(line[1:]) + count2 += 1 + out1.close() + out2.close() + + +app.start() + Property changes on: trunk/CSP/tools/undiff ___________________________________________________________________ Name: svn:executable + * |