11#! /usr/bin/env lua
22
3- local PF ,CT ,M ,S = " I2I4I8" ,{},0xFFFFFFFF ," set"
3+ local PF ,CT ,M ,S , CL = " I2I4I8" ,{},0xFFFFFFFF ," set" , tonumber ( os.getenv ( " DIFF_CONTEXT " )) or 3
44local function diff_u (fn1 ,fn2 )
55 local function open (fn )local f ,e = io.open (fn ," rb" )if not f then print (e )os.exit (1 )end
66 local function crc32 (s )local c = M for i = 1 ,# s do local byte = s :byte (i )c = (c >> 8 )~CT [(c ~byte )&0xFF ]end return (~c )&M end
@@ -9,50 +9,32 @@ local function diff_u(fn1,fn2)
99 local function eol ()if c == ' \r ' then local d = f :read (1 )if not d then return true end f :seek (" cur" ,- 1 )return d ~= ' \n ' end return c == ' \n ' end
1010 o = o + 1 table.insert (l ,c )if eol ()then break end end
1111 if # l == 0 then break end l = table.concat (l )local ln ,c =# l ,crc32 (l )p = p .. string.pack (PF ,ln ,c ,ls )end f :close ()return p end
12- local f1 ,f2 ,ps ,i ,j ,la ,fh ,h ,w ,m ,u = open (fn1 ),open (fn2 ),string.packsize (PF ),1 , 1
12+ local f1 ,f2 ,ps ,co , i ,j ,la ,fh ,h ,w ,m ,u , L = open (fn1 ),open (fn2 ),string.packsize (PF ),{}
1313 local function cmp (x ,y )
1414 local l1 ,c1 ,o1 ,l2 ,c2 ,o2 ,b1 ,e ,b2 ,f = string.unpack (PF ,f1 ,(x - 1 )* ps + 1 )l2 ,c2 ,o2 = string.unpack (PF ,f2 ,(y - 1 )* ps + 1 )if l1 ~= l2 or c1 ~= c2 then return false end
1515 local function li (fn ,o ,l )f ,e = io.open (fn ," rb" )if not f then return nil ,e end f :seek (S ,o )local g = f :read (l )f :close ()return g end
1616 b1 ,e ,b2 = li (fn1 ,o1 ,l1 )if not b1 then error (e )end b2 ,e = li (fn2 ,o2 ,l2 )if not b2 then error (e )end return b1 == b2 end
17- h ,w ,m =# f1 // ps ,# f2 // ps ,{}
18- local ly ,l ,n = 1
19- for x = 1 ,h do
20- local b = {}
21- local function inList (v )for k ,p in ipairs (b )do if v == p then return k end end end
22- for y = ly ,w do if cmp (x ,y )then table.insert (b ,y )end end
23- if # b > 0 then
24- if # m > 0 then
25- l = m [# m ]
26- if l .x + l .l == x then
27- n = inList (l .y + l .l )
28- if n then l .l = l .l + 1 end
29- else
30- -- TODO: calculate how far ahead we should be from last and current x and y
31- n = inList (l .y + l .l )
32- if n then table.insert (m ,{y = b [n ],x = x ,l = 1 }) end
33- end
34- else
35- table.insert (m ,{y = b [1 ],x = x ,l = 1 })
36- end
37- end
38- end
17+ h ,w ,la ,m ,L =# f1 // ps ,# f2 // ps ,1 ,{},{} for x = 0 ,h do L [x ]= {}for y = 0 ,w do if x == 0 or y == 0 then L [x ][y ]= 0
18+ elseif cmp (x ,y )then L [x ][y ]= L [x - 1 ][y - 1 ]+ 1
19+ else L [x ][y ]= (L [x - 1 ][y ]> L [x ][y - 1 ])and L [x - 1 ][y ]or L [x ][y - 1 ]end end end
20+ i ,j = h ,w while i > 0 and j > 0 do
21+ if cmp (i ,j )then table.insert (m ,1 ,{x = i ,y = j ,l = 1 })i ,j = i - 1 ,j - 1
22+ elseif L [i - 1 ][j ]>= L [i ][j - 1 ]then i = i - 1 else j = j - 1 end end
23+ for _ ,p in ipairs (m )do local t = co [# co ] if t and t .x + t .l == p .x and t .y + t .l == p .y then t .l = t .l + 1 else co [# co + 1 ]= {x = p .x ,y = p .y ,l = p .l }end end
24+ m ,la ,i ,j = co ,nil ,1 ,1
3925 local function get (fn ,p ,x )local l ,_ ,o ,f ,r = string.unpack (PF ,p ,(x - 1 )* ps + 1 )f = assert (io.open (fn ," rb" ))f :seek (S ,o )r = f :read (l )f :close ()return r end
4026 local function pfl (p ,s )return (p .. s :gsub (' \n $' ,' ' ):gsub (' \r $' ,' ' ))end
41- local function flush ()if # u .l > 0 then if u .e >= 4 then table.remove (u .l )u .o .l ,u .n .l = u .o .l - 1 ,u .n .l - 1 end
27+ local function flush ()if # u .l > 0 then if u .e > CL then table.remove (u .l )u .o .l ,u .n .l = u .o .l - 1 ,u .n .l - 1 end
4228 table.insert (u .l ,1 ," @@ -" .. u .o .s .. (u .o .l == 1 and " " or " ," .. u .o .l ).. " +" .. u .n .s .. (u .n .l == 1 and " " or " ," .. u .n .l ).. " @@" )
4329 if not fh then local function fn (s )return string.match (s ," %s" )and ' "' .. s .. ' "' or s end table.insert (u .l ,1 ," +++ " .. fn (fn2 ))table.insert (u .l ,1 ," --- " .. fn (fn1 ))fh = true end
4430 for _ ,v in ipairs (u .l )do print (v )end end u = nil end
4531 local function init ()if not u then local k ,l = math.max (i - 3 ,1 ),math.max (j - 3 ,1 )u = {e = 0 ,l = {},o = {s = k ,l = 0 },n = {s = l ,l = 0 }}
4632 for z = k ,i - 1 do table.insert (u .l ,pfl (" " ,get (fn1 ,f1 ,z )))u .o .l ,u .n .l = u .o .l + 1 ,u .n .l + 1 end end end
47- -- TODO: Select correct y grid on each compare table
48- print (" x" ," y" ," l" )
4933 for _ ,p in ipairs (m )do
50- -- Temporary debug code
51- print (p .x , p .y , p .l )--[[
5234 while i < p .x do init ()table.insert (u .l ,pfl (" -" ,get (fn1 ,f1 ,i )))i ,u .o .l ,u .e = i + 1 ,u .o .l + 1 ,0 end
5335 while j < p .y do init ()table.insert (u .l ,pfl (" +" ,get (fn2 ,f2 ,j )))j ,u .n .l ,u .e = j + 1 ,u .n .l + 1 ,0 end
54- if u then if u.e<4 then table.insert(u.l,pfl(" ",get(fn1,f1,i)))u.e,u.o.l,u.n.l=u.e+1,u.o.l+1,u.n.l+1 else flush()end end i,j=i+1,j+1 end
55- --]] end os.exit ( 1 )
36+ if u then local c = p . l > CL + 2 and CL + 1 or p . l while u .e < c and i <= h and j <= w do table.insert (u .l ,pfl (" " ,get (fn1 ,f1 ,i )))i , j , u .e ,u .o .l ,u .n .l = i + 1 , j + 1 , u .e + 1 ,u .o .l + 1 ,u .n .l + 1 end if p . l > 5 then flush () end end
37+ i , j = p . x + p . l , p . y + p . l end
5638 local function nlc ()if la then la = la :sub (- 1 )if la ~= ' \n ' and la ~= ' \r ' then table.insert (u .l ," \\ No newline at end of file" )end end end
5739 while i <= h do init ()la = get (fn1 ,f1 ,i ,ps )table.insert (u .l ,pfl (" -" ,la ))i ,u .o .l ,u .e = i + 1 ,u .o .l + 1 ,0 end nlc ()
5840 while j <= w do init ()la = get (fn2 ,f2 ,j ,ps )table.insert (u .l ,pfl (" +" ,la ))j ,u .n .l ,u .e = j + 1 ,u .n .l + 1 ,0 end nlc ()
0 commit comments