-- Copyright (C) 2009 Petr Rockai---- Permission is hereby granted, free of charge, to any person-- obtaining a copy of this software and associated documentation-- files (the "Software"), to deal in the Software without-- restriction, including without limitation the rights to use, copy,-- modify, merge, publish, distribute, sublicense, and/or sell copies-- of the Software, and to permit persons to whom the Software is-- furnished to do so, subject to the following conditions:---- The above copyright notice and this permission notice shall be-- included in all copies or substantial portions of the Software.---- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,-- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF-- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND-- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS-- BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN-- ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN-- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE-- SOFTWARE.moduleDarcs.Diff(treeDiff)whereimportDarcs.Witnesses.Ordered(FL(..),(+>+))importDarcs.Repository.Prefs(FileType(..))importDarcs.Patch(Prim,hunk,canonize,binary,addfile,rmfile,adddir,rmdir,invert)importStorage.Hashed.Tree(diffTrees,zipTrees,TreeItem(..),Tree,readBlob,emptyBlob)importStorage.Hashed.AnchoredPath(AnchoredPath,anchorPath)importqualifiedData.ByteString.Lazy.Char8asBLCimportqualifiedData.ByteStringasBSimportqualifiedData.ByteString.LazyasBLimportByteStringUtils(is_funky)#include "gadts.h"treeDiff::(FilePath->FileType)->TreeIO->TreeIO->IO(FLPrimC(xy))#ifdef GADT_WITNESSEStreeDiff=undefined-- Sigh.#elsetreeDiffftt1t2=do(from,to)<-diffTreest1t2diffs<-sequence$zipTreesdifffromtoreturn$foldr(+>+)NilFLdiffswherediff::AnchoredPath->Maybe(TreeItemIO)->Maybe(TreeItemIO)->IO(FLPrim)diff_(Just(SubTree_))(Just(SubTree_))=returnNilFLdiffp(Just(SubTree_))Nothing=return$rmdir(anchorPath""p):>:NilFLdiffpNothing(Just(SubTree_))=return$adddir(anchorPath""p):>:NilFLdiffpNothingb'@(Just(File_))=dodiff'<-diffp(Just(FileemptyBlob))b'return$addfile(anchorPath""p):>:diff'diffpa'@(Just(File_))Nothing=dodiff'<-diffpa'(Just(FileemptyBlob))return$diff'+>+(rmfile(anchorPath""p):>:NilFL)diffp(Just(Filea'))(Just(Fileb'))=doa<-readBloba'b<-readBlobb'letpath=anchorPath""pcaseftpathofTextFile|no_bina&&no_binb->return$text_diffpathab_->return$ifa/=bthenbinarypath(stricta)(strictb):>:NilFLelseNilFLdiffp__=fail$"Missing case at path "++showptext_diffpab|BL.nulla&&BL.nullb=NilFL|BL.nulla=diff_from_emptypb|BL.nullb=diff_to_emptypa|otherwise=line_diffp(linesBa)(linesBb)line_diffpab=canonize(hunkp1ab)diff_to_emptypx|BLC.lastx=='\n'=line_diffp(init$linesBx)[]|otherwise=line_diffp(linesBx)[BS.empty]diff_from_emptypx=invert(diff_to_emptypx)no_bin=not.is_funky.strict.BL.take4096linesB=mapstrict.BLC.split'\n'strict=BS.concat.BL.toChunks#endif