view mercurial/mdiff.py @ 209:63af1db35611

Beginning of new command parsing interface -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Beginning of new command parsing interface This adds commands.py, with a primary interface dispatch(args) Dispatch searches a table of known commands, handles switches, sets up a repo object if appropriate, and dispatches the command. It also handles KeyboardInterrupt and can handle similar exceptions in the future. If the command is unknown, it falls through to the current command handler. Commands currently handled by the new scheme: help, init, and annotate manifest hash: 134cd032c880985e3f92f82efb8b629dd862ba4c -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCnXEGywK+sNU5EO8RAuDAAJ9q7K4w7qGVWv1NWjCPFGO/UJc6VQCdEhMQ sBBlSRzah9QPy8K94catZyg= =wuRf -----END PGP SIGNATURE-----
author mpm@selenic.com
date Wed, 01 Jun 2005 00:25:42 -0800
parents 697f05bfe976
children 75840796e8e2 afe895fcc0d0
line wrap: on
line source

#!/usr/bin/python
import difflib, struct, mmap
from mercurial.mpatch import *

def unidiff(a, ad, b, bd, fn):
    if not a and not b: return ""
    a = a.splitlines(1)
    b = b.splitlines(1)
    l = list(difflib.unified_diff(a, b, "a/" + fn, "b/" + fn, ad, bd))

    for ln in xrange(len(l)):
        if l[ln][-1] != '\n':
            l[ln] += "\n\ No newline at end of file\n"

    return "".join(l)

def textdiff(a, b):
    return diff(a.splitlines(1), b.splitlines(1))

def sortdiff(a, b):
    la = lb = 0
    lena = len(a)
    lenb = len(b)
    while 1:
        am, bm, = la, lb
        while lb < lenb and la < len and a[la] == b[lb] :
            la += 1
            lb += 1
        if la>am: yield (am, bm, la-am)
        while lb < lenb and b[lb] < a[la]: lb += 1
        if lb>=lenb: break
        while la < lena and b[lb] > a[la]: la += 1
        if la>=lena: break
    yield (lena, lenb, 0)

def diff(a, b, sorted=0):
    if not a:
        s = "".join(b)
        return s and (struct.pack(">lll", 0, 0, len(s)) + s)

    bin = []
    p = [0]
    for i in a: p.append(p[-1] + len(i))

    if sorted:
        d = sortdiff(a, b)
    else:
        d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
    la = 0
    lb = 0
    for am, bm, size in d:
        s = "".join(b[lb:bm])
        if am > la or s:
            bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
        la = am + size
        lb = bm + size
    
    return "".join(bin)

def patchtext(bin):
    pos = 0
    t = []
    while pos < len(bin):
        p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
        pos += 12
        t.append(bin[pos:pos + l])
        pos += l
    return "".join(t)

def patch(a, bin):
    return patches(a, [bin])