~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/patches.py

  • Committer: Andrew Bennetts
  • Date: 2010-01-12 03:53:21 UTC
  • mfrom: (4948 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4964.
  • Revision ID: andrew.bennetts@canonical.com-20100112035321-hofpz5p10224ryj3
Merge lp:bzr, resolving conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
13
13
#
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
17
import re
 
18
 
 
19
 
 
20
binary_files_re = 'Binary files (.*) and (.*) differ\n'
 
21
 
 
22
 
 
23
class BinaryFiles(Exception):
 
24
 
 
25
    def __init__(self, orig_name, mod_name):
 
26
        self.orig_name = orig_name
 
27
        self.mod_name = mod_name
 
28
        Exception.__init__(self, 'Binary files section encountered.')
17
29
 
18
30
 
19
31
class PatchSyntax(Exception):
57
69
def get_patch_names(iter_lines):
58
70
    try:
59
71
        line = iter_lines.next()
 
72
        match = re.match(binary_files_re, line)
 
73
        if match is not None:
 
74
            raise BinaryFiles(match.group(1), match.group(2))
60
75
        if not line.startswith("--- "):
61
76
            raise MalformedPatchHeader("No orig name", line)
62
77
        else:
92
107
    range = int(range)
93
108
    return (pos, range)
94
109
 
95
 
 
 
110
 
96
111
def hunk_from_header(line):
97
112
    import re
98
113
    matches = re.match(r'\@\@ ([^@]*) \@\@( (.*))?\n', line)
164
179
        return InsertLine(line[1:])
165
180
    elif line.startswith("-"):
166
181
        return RemoveLine(line[1:])
167
 
    elif line == NO_NL:
168
 
        return NO_NL
169
182
    else:
170
183
        raise MalformedLine("Unknown line type", line)
171
184
__pychecker__=""
261
274
        yield hunk
262
275
 
263
276
 
264
 
class Patch:
 
277
class BinaryPatch(object):
265
278
    def __init__(self, oldname, newname):
266
279
        self.oldname = oldname
267
280
        self.newname = newname
 
281
 
 
282
    def __str__(self):
 
283
        return 'Binary files %s and %s differ\n' % (self.oldname, self.newname)
 
284
 
 
285
 
 
286
class Patch(BinaryPatch):
 
287
 
 
288
    def __init__(self, oldname, newname):
 
289
        BinaryPatch.__init__(self, oldname, newname)
268
290
        self.hunks = []
269
291
 
270
292
    def __str__(self):
271
 
        ret = self.get_header() 
 
293
        ret = self.get_header()
272
294
        ret += "".join([str(h) for h in self.hunks])
273
295
        return ret
274
296
 
300
322
                return None
301
323
            newpos += shift
302
324
        return newpos
303
 
            
 
325
 
304
326
    def iter_inserted(self):
305
327
        """Iteraties through inserted lines
306
 
        
 
328
 
307
329
        :return: Pair of line number, line
308
330
        :rtype: iterator of (int, InsertLine)
309
331
        """
318
340
 
319
341
 
320
342
def parse_patch(iter_lines):
321
 
    (orig_name, mod_name) = get_patch_names(iter_lines)
322
 
    patch = Patch(orig_name, mod_name)
323
 
    for hunk in iter_hunks(iter_lines):
324
 
        patch.hunks.append(hunk)
325
 
    return patch
 
343
    iter_lines = iter_lines_handle_nl(iter_lines)
 
344
    try:
 
345
        (orig_name, mod_name) = get_patch_names(iter_lines)
 
346
    except BinaryFiles, e:
 
347
        return BinaryPatch(e.orig_name, e.mod_name)
 
348
    else:
 
349
        patch = Patch(orig_name, mod_name)
 
350
        for hunk in iter_hunks(iter_lines):
 
351
            patch.hunks.append(hunk)
 
352
        return patch
326
353
 
327
354
 
328
355
def iter_file_patch(iter_lines):
 
356
    regex = re.compile(binary_files_re)
329
357
    saved_lines = []
330
358
    orig_range = 0
331
359
    for line in iter_lines:
336
364
        elif orig_range > 0:
337
365
            if line.startswith('-') or line.startswith(' '):
338
366
                orig_range -= 1
339
 
        elif line.startswith('--- '):
 
367
        elif line.startswith('--- ') or regex.match(line):
340
368
            if len(saved_lines) > 0:
341
369
                yield saved_lines
342
370
            saved_lines = []
370
398
 
371
399
 
372
400
def parse_patches(iter_lines):
373
 
    iter_lines = iter_lines_handle_nl(iter_lines)
374
401
    return [parse_patch(f.__iter__()) for f in iter_file_patch(iter_lines)]
375
402
 
376
403