| 2 | |
| 3 | |
| 4 | class PatchParser(): |
| 5 | |
| 6 | def __init__(self): |
| 7 | self.re_chunk_header = re.compile("""\@\@\s* |
| 8 | \-(?P<old_start_line>\d+)(,(?P<old_num_lines>\d+))?\s* |
| 9 | \+(?P<new_start_line>\d+)(,(?P<new_num_lines>\d+))?\s* |
| 10 | \@\@ |
| 11 | """, re.VERBOSE) |
| 12 | |
| 13 | def clean(self): |
| 14 | self.additions = [] |
| 15 | self.deletions = [] |
| 16 | self.in_add, self.in_del = False, False |
| 17 | self.in_chunk = False |
| 18 | |
| 19 | self.add_start, self.del_start = None, None |
| 20 | self.add_num_lines = None |
| 21 | self.cur = None |
| 22 | |
| 23 | def start_add(self): |
| 24 | self.in_add = True |
| 25 | self.add_start = self.cur - 1 |
| 26 | self.add_num_lines = 1 |
| 27 | |
| 28 | def start_del(self): |
| 29 | self.in_del = True |
| 30 | self.del_start = self.cur |
| 31 | |
| 32 | def finish_add(self): |
| 33 | self.in_add = False |
| 34 | self.additions.append([self.add_start, self.add_num_lines]) |
| 35 | |
| 36 | def finish_del(self): |
| 37 | self.in_del = False |
| 38 | self.deletions.append([self.del_start, self.cur - 1]) |
| 39 | |
| 40 | def parse(self, text): |
| 41 | self.clean() |
| 42 | for line in text.split('\n'): |
| 43 | line = line.strip() |
| 44 | if not self.in_chunk: |
| 45 | if line.startswith('@@'): |
| 46 | self.in_chunk = True |
| 47 | else: |
| 48 | continue |
| 49 | |
| 50 | if line.startswith('@@'): |
| 51 | m = self.re_chunk_header.search(line) |
| 52 | self.cur = max(int(m.groups()[0]), 1) |
| 53 | elif line.startswith('-'): |
| 54 | # print("in minus") |
| 55 | if self.in_add: |
| 56 | self.finish_add() |
| 57 | self.start_del() |
| 58 | elif self.in_del: |
| 59 | pass |
| 60 | else: |
| 61 | self.start_del() |
no outgoing calls