[Python-checkins] r80780 - sandbox/trunk/untabify/untabify.py
antoine.pitrou
python-checkins at python.org
Wed May 5 14:58:30 CEST 2010
Author: antoine.pitrou
Date: Wed May 5 14:58:30 2010
New Revision: 80780
Log:
Add an option to rewrite patches
Modified:
sandbox/trunk/untabify/untabify.py
Modified: sandbox/trunk/untabify/untabify.py
==============================================================================
--- sandbox/trunk/untabify/untabify.py (original)
+++ sandbox/trunk/untabify/untabify.py Wed May 5 14:58:30 2010
@@ -36,6 +36,9 @@
$ svn revert Modules/_cursesmodule.c
# Done!
+You can also rewrite your old patches with the -p option; if there are
+still conflicts when applying, use `patch -l`.
+
"""
import os
@@ -48,8 +51,8 @@
def untabify(lines, write):
- last_indent = 0
- last_outdent = 0
+ last_indent = -1
+ last_outdent = -1
last_outline = ""
for line in lines:
cr = line.find('\r')
@@ -84,7 +87,7 @@
inpos = (inpos // 8 + 1) * 8
outpos += 4
# Continuation line?
- if (inpos > last_indent + 8
+ if (last_indent >= 0 and inpos > last_indent + 8
# labels and end-of-comments can't be continued
and not last_outline.endswith(':')
and not last_outline.endswith('*/')):
@@ -114,8 +117,7 @@
last_indent = indent
last_outdent = outdent
last_outline = outline
- write(outline)
- write(eol)
+ write(outline + eol)
def replace_tabs(lines, write):
"""Simply replace tabs with 8-spaces without attempting to fix/change
@@ -146,8 +148,64 @@
outpos = inpos
output.append(chunks[-1])
outline = "".join(output).rstrip()
- write(outline)
- write(eol)
+ write(outline + eol)
+
+def passthrough(lines, write):
+ for l in lines:
+ write(l)
+
+def untabify_hunk(lines, write, transform_func):
+ if not lines:
+ return
+ chars, lines = zip(*((l[:1], l[1:]) for l in lines))
+ outlines = []
+ transform_func(lines, outlines.append)
+ for c, l in zip(chars, outlines):
+ write(c + l)
+
+def untabify_patch_fragment(lines, write, transform_func):
+ lines = list(lines)
+ if '\t' not in ''.join(lines):
+ passthrough(lines, write)
+ return
+ hunk_chars = ' +-'
+ hunk_lines = []
+ for line in lines:
+ c = line[:1]
+ if c not in hunk_chars:
+ untabify_hunk(hunk_lines, write, transform_func)
+ hunk_lines = []
+ write(line)
+ continue
+ hunk_lines.append(line)
+ untabify_hunk(hunk_lines, write, transform_func)
+
+def untabify_patch(lines, write, transform_func):
+ patch_chars = ' +-<>!@'
+ lines = iter(lines)
+ line = next(lines)
+ while True:
+ patch_transform_func = passthrough
+ for line in itertools.chain([line], lines):
+ c = line[:1]
+ if line[:4] in ('--- ', '+++ '):
+ filepath = line.split()[1]
+ if is_c_file(filepath):
+ patch_transform_func = transform_func
+ elif c in patch_chars:
+ break
+ write(line)
+ else:
+ break
+ fragment_lines = []
+ for line in itertools.chain([line], lines):
+ c = line[:1]
+ if c not in patch_chars:
+ break
+ fragment_lines.append(line)
+ untabify_patch_fragment(fragment_lines, write, transform_func)
+ if c in patch_chars:
+ break
def needs_untabifying(filepath):
@@ -160,13 +218,16 @@
finally:
f.close()
+def is_c_file(filepath):
+ return filepath.endswith('.h') or filepath.endswith('.c')
+
def walk_c_files(paths):
for p in paths:
if os.path.isfile(p):
yield p
for dirpath, dirnames, filenames in os.walk(p):
for fn in sorted(filenames):
- if fn.endswith('.h') or fn.endswith('.c'):
+ if is_c_file(fn):
yield os.path.join(dirpath, fn)
@contextlib.contextmanager
@@ -195,6 +256,9 @@
parser.add_option("-u", "--untabify", dest="do_untab",
action="store_true", default=False,
help="untabify stdin to stdout")
+ parser.add_option("-p", "--untabify-patch", dest="do_untab_patch",
+ action="store_true", default=False,
+ help="untabify patch (stdin to stdout)")
parser.add_option("-b", "--batch", dest="do_batch",
action="store_true", default=False,
help="untabify specified files and dirs")
@@ -203,8 +267,9 @@
help="simply replace tabs with 8-spaces (for files with mixed 4-spaces and tabs)")
options, args = parser.parse_args()
if (options.do_list_true + options.do_list_false +
- options.do_untab + options.do_batch + options.do_replace != 1):
- parser.error("you must specify exactly one of -l, -n, -b and -u")
+ options.do_untab + options.do_untab_patch +
+ options.do_batch + options.do_replace != 1):
+ parser.error("you must specify exactly one of -l, -n, -b, -u and -p")
if options.do_list_true or options.do_list_false:
if not args:
@@ -236,6 +301,9 @@
if options.do_untab:
untabify(sys.stdin, sys.stdout.write)
+
+ if options.do_untab_patch:
+ untabify_patch(sys.stdin, sys.stdout.write, untabify)
if __name__ == '__main__':
main()
More information about the Python-checkins
mailing list