Last active
August 29, 2015 14:01
-
-
Save courtc/75c0585e3943a2bf1150 to your computer and use it in GitHub Desktop.
Error file to patch line, with fuzzing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
import fileinput; | |
import sys; | |
import re; | |
import os; | |
def shortpath(name): | |
cwd = os.getcwd() | |
if name.startswith(cwd): | |
return name[len(cwd) + 1:] | |
return name | |
class Target: | |
def __init__(self): | |
self.start = 0 | |
self.name = None | |
self.length = 0 | |
self.xlate = 0 | |
self.messages = [] | |
def add(self, offset, message): | |
self.messages.append((offset, message)) | |
def items(self): | |
for off, msg in self.messages: | |
yield "%d: %s" % (self.xlate + off, msg) | |
def fuzz(self, actual): | |
self.xlate += self.start - actual.start | |
class Patch: | |
def __init__(self, file): | |
self.filename = file | |
self.file = open(file, "r") | |
lineno = 1 | |
target = None | |
targets = [] | |
for line in self.file: | |
parts = line.strip('\r\n').split(' ') | |
if parts[0] == 'diff': | |
pass | |
elif parts[0] == "+++": | |
if target is not None: | |
targets.append(target) | |
target = Target() | |
target.name = parts[1] | |
elif parts[0] == '@@': | |
target.start = int(parts[2].split(',')[0][1:]) | |
target.length = int(parts[2].split(',')[1]) | |
target.xlate = lineno + 1 | |
lineno += 1 | |
if target is not None: | |
targets.append(target) | |
targets = sorted(targets, key=lambda x: x.start) | |
self.targets = sorted(targets, key=lambda x: x.name) | |
def parse(self, line): | |
if not re.match("[^\s:]+:[0-9]+:.*$", line): | |
return | |
file, lineno, message = line.split(':', 2) | |
lineno = int(lineno) | |
if re.match("[0-9]+:.*", message): | |
message = message.split(':', 1)[1].strip() | |
target = self.which(file, lineno) | |
if target is None: | |
return | |
target.add(lineno - target.start, message) | |
def which(self, file, lineno): | |
file = shortpath(file) | |
for target in self.targets: | |
#print "%s:%d <=> %s:%d::%d" % (file, lineno, target.name, target.start, target.start + target.length) | |
if "b/%s" % file != target.name: | |
continue | |
if lineno < target.start: | |
continue | |
if lineno >= target.start + target.length: | |
continue | |
return target | |
return None | |
def write(self): | |
for target in self.targets: | |
for msg in target.items(): | |
print "%s:%s" % (shortpath(self.filename), msg) | |
def fuzz(self, actual): | |
for target, act in zip(self.targets, actual.targets): | |
target.fuzz(act) | |
def usage(name): | |
print "USAGE: %s <original-patch> [actual-patch]" % name | |
if __name__ == "__main__": | |
if len(sys.argv) < 2 or len(sys.argv) > 3: | |
usage(sys.argv[0]) | |
sys.exit(1) | |
patch = Patch(sys.argv[1]) | |
if len(sys.argv) == 3: | |
actual = Patch(sys.argv[2]) | |
patch.fuzz(actual) | |
for line in sys.stdin.readlines(): | |
line = line.strip('\n\r') | |
patch.parse(line) | |
print line | |
patch.write() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment