blob: 8991bdcf685b4e98fd155ca337f8a18b64d5f395 (
plain) (
tree)
|
|
to diff :file1 :file2 :output
local "caseignoredp
make "caseignoredp "false
openread :file1
openread :file2
if not emptyp :output [openwrite :output]
setwrite :output
print [DIFF results:]
print sentence [< File 1 =] :file1
print sentence [> File 2 =] :file2
diff.same (makefile 1 :file1) (makefile 2 :file2)
print "==========
setread []
setwrite []
close :file1
close :file2
if not emptyp :output [close :output]
end
;; Skip over identical lines in the two files.
to diff.same :fib1 :fib2
local [line1 line2]
do.while [make "line1 getline :fib1
make "line2 getline :fib2
if and listp :line1 listp :line2 [stop] ; Both files ended.
] [equalp :line1 :line2]
addline :fib1 :line1 ; Difference found.
addline :fib2 :line2
diff.differ :fib1 :fib2
end
;; Remember differing lines while looking for ones that match.
to diff.differ :fib1 :fib2
local "line
make "line readline :fib1
addline :fib1 :line
ifelse memberp :line lines :fib2 ~
[diff.found :fib1 :fib2] ~
[diff.differ :fib2 :fib1]
end
to diff.found :fib1 :fib2
local "lines
make "lines member2 (last butlast lines :fib1) ~
(last lines :fib1) ~
(lines :fib2)
ifelse emptyp :lines ~
[diff.differ :fib2 :fib1] ~
[report :fib1 :fib2 (butlast butlast lines :fib1)
(firstn (lines :fib2) (count lines :fib2)-(count :lines))]
end
to member2 :line1 :line2 :lines
if emptyp butfirst :lines [output []]
if and equalp :line1 first :lines equalp :line2 first butfirst :lines ~
[output :lines]
output member2 :line1 :line2 butfirst :lines
end
to firstn :stuff :number
if :number = 0 [output []]
output fput (first :stuff) (firstn butfirst :stuff :number-1)
end
;; Read from file or from saved lines.
to getline :fib
nextlinenum :fib
output readline :fib
end
to readline :fib
if savedp :fib [output popsaved :fib]
setread filename :fib
output readword
end
;; Matching lines found, now report the differences.
to report :fib1 :fib2 :lines1 :lines2
local [end1 end2 dashes]
if equalp (which :fib1) 2 [report :fib2 :fib1 :lines2 :lines1 stop]
print "==========
make "end1 (linenum :fib1)+(count :lines1)-1
make "end2 (linenum :fib2)+(count :lines2)-1
make "dashes "false
ifelse :end1 < (linenum :fib1) [
print (sentence "INSERT :end1+1 (word (linenum :fib2) "- :end2))
] [ifelse :end2 < (linenum :fib2) [
print (sentence "DELETE (word (linenum :fib1) "- :end1) :end2+1)
] [
print (sentence "CHANGE (word (linenum :fib1) "- :end1)
(word (linenum :fib2) "- :end2))
make "dashes "true
]]
process :fib1 "|< | :lines1 :end1
if :dashes [print "-----]
process :fib2 "|> | :lines2 :end2
diff.same :fib1 :fib2
end
to process :fib :prompt :lines :end
foreach :lines [type :prompt print ?]
savelines :fib butfirst butfirst chop :lines (lines :fib)
setlines :fib []
setlinenum :fib :end+2
end
to chop :counter :stuff
if emptyp :counter [output :stuff]
output chop butfirst :counter butfirst :stuff
end
;; Constructor, selectors, and mutators for File Information Block (FIB)
;; Five elements: file number, file name, line number,
;; differing lines, and saved lines for re-reading.
to makefile :number :name
local "file
make "file array 5 ; Items 4 and 5 will be empty lists.
setitem 1 :file :number
setitem 2 :file :name
setitem 3 :file 0
output :file
end
to which :fib
output item 1 :fib
end
to filename :fib
output item 2 :fib
end
to linenum :fib
output item 3 :fib
end
to nextlinenum :fib
setitem 3 :fib (item 3 :fib)+1
end
to setlinenum :fib :value
setitem 3 :fib :value
end
to addline :fib :line
setitem 4 :fib (lput :line item 4 :fib)
end
to setlines :fib :value
setitem 4 :fib :value
end
to lines :fib
output item 4 :fib
end
to savelines :fib :value
setitem 5 :fib (sentence :value item 5 :fib)
end
to savedp :fib
output not emptyp item 5 :fib
end
to popsaved :fib
local "result
make "result first item 5 :fib
setitem 5 :fib (butfirst item 5 :fib)
output :result
end
|