1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
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
|