|
1 "{ Package: 'stx:libtool' }" |
|
2 |
|
3 Object subclass:#DiffListUtility |
|
4 instanceVariableNames:'' |
|
5 classVariableNames:'DiffCommandTemplate' |
|
6 poolDictionaries:'' |
|
7 category:'Views-Text' |
|
8 ! |
|
9 |
|
10 !DiffListUtility class methodsFor:'documentation'! |
|
11 |
|
12 documentation |
|
13 " |
|
14 a utility to encapsulate access to the diff command |
|
15 (may be a facede to a smalltalk-diff algorithm, eventually) |
|
16 |
|
17 [author:] |
|
18 cg (cg@CG-PC) |
|
19 |
|
20 [instance variables:] |
|
21 |
|
22 [class variables:] |
|
23 |
|
24 [see also:] |
|
25 |
|
26 " |
|
27 ! ! |
|
28 |
|
29 !DiffListUtility class methodsFor:'defaults'! |
|
30 |
|
31 diffCommand |
|
32 "return the diff-command (with argument placeHolders)" |
|
33 |
|
34 DiffCommandTemplate notNil ifTrue:[ ^ DiffCommandTemplate ]. |
|
35 |
|
36 OperatingSystem isMSDOSlike ifTrue:[ |
|
37 (OperatingSystem canExecuteCommand:'diff') ifFalse:[ |
|
38 'DiffTextView [warning]: no diff command found (please download and unzip "UnxUtils.zip" from "unxutils.sourceforge.net")' infoPrintCR. |
|
39 ^ nil |
|
40 ]. |
|
41 ^ 'diff %1 %2' |
|
42 ]. |
|
43 ^ 'diff -b %1 %2' |
|
44 |
|
45 "Modified: / 30.1.1998 / 12:12:49 / cg" |
|
46 ! |
|
47 |
|
48 diffCommandTemplate:aCommandTemplateString |
|
49 "set the diff-command template" |
|
50 |
|
51 DiffCommandTemplate := aCommandTemplateString |
|
52 ! ! |
|
53 |
|
54 !DiffListUtility class methodsFor:'private'! |
|
55 |
|
56 saveForDiff:text as:filename |
|
57 |stream| |
|
58 |
|
59 [ |
|
60 stream := filename writeStream. |
|
61 text do:[:line | |
|
62 |lOut i| |
|
63 |
|
64 line notEmptyOrNil ifTrue:[ |
|
65 lOut := line. |
|
66 (line includes:Character return) ifTrue: [ |
|
67 (line endsWith:Character return) ifTrue:[ |
|
68 lOut := line copyWithoutLast:1. |
|
69 ] ifFalse:[ |
|
70 i := line indexOf:Character return. |
|
71 (line at:i+1) == Character nl ifTrue:[ |
|
72 "/ crnl endings |
|
73 lOut := line copyReplaceString:(String crlf) withString:(String lf). |
|
74 ] ifFalse:[ |
|
75 "/ cr endings |
|
76 lOut := line copyReplaceAll:Character return with:Character nl. |
|
77 ]. |
|
78 ] |
|
79 ]. |
|
80 lOut bitsPerCharacter > 8 ifTrue:[ |
|
81 (lOut first = (Character value:16rFEFF)) ifTrue:[ |
|
82 lOut := (lOut copyFrom:2) asSingleByteStringIfPossible. |
|
83 ]. |
|
84 lOut bitsPerCharacter > 8 ifTrue:[ |
|
85 lOut := lOut collect:[:ch | ch bitsPerCharacter > 8 |
|
86 ifTrue:[ Character value:16rFF ] |
|
87 ifFalse:[ ch ]]. |
|
88 lOut := lOut asSingleByteStringIfPossible. |
|
89 ]. |
|
90 ]. |
|
91 stream nextPutAll:lOut. |
|
92 ]. |
|
93 stream cr |
|
94 ]. |
|
95 ] ensure:[ |
|
96 stream close. |
|
97 ]. |
|
98 |
|
99 "Modified: / 22-10-2008 / 17:52:52 / cg" |
|
100 ! ! |
|
101 |
|
102 !DiffListUtility class methodsFor:'utilities'! |
|
103 |
|
104 diffListFor:text1 and:text2 |
|
105 "execute DiffCommand to get a list of diffs." |
|
106 |
|
107 " |
|
108 The returned list is in raw-diff output format, such as: |
|
109 1 : '1c1' |
|
110 2 : '< hello world' |
|
111 3 : '---' |
|
112 4 : '> Hello World' |
|
113 5 : '2a3' |
|
114 6 : '> line2' |
|
115 7 : '4d4' |
|
116 8 : '< line4' |
|
117 " |
|
118 |
|
119 |tmpFile1 tmpFile2 stream line |
|
120 diffList diffTemplate diffCmd| |
|
121 |
|
122 diffTemplate := self diffCommand. |
|
123 diffTemplate isNil ifTrue:[ |
|
124 "/ self warn:'no diff command available'. |
|
125 ^ nil |
|
126 ]. |
|
127 |
|
128 text1 = text2 ifTrue:[ |
|
129 "no diff" |
|
130 ^ #() |
|
131 ]. |
|
132 |
|
133 " |
|
134 save them texts in two temporary files ... |
|
135 " |
|
136 [ |
|
137 self saveForDiff:text1 as:(tmpFile1 := Filename newTemporary). |
|
138 self saveForDiff:text2 as:(tmpFile2 := Filename newTemporary). |
|
139 |
|
140 " |
|
141 start diff on it ... |
|
142 " |
|
143 diffCmd := diffTemplate |
|
144 bindWith:tmpFile1 asString |
|
145 with:tmpFile2 asString. |
|
146 |
|
147 stream := PipeStream readingFrom:diffCmd. |
|
148 stream isNil ifTrue:[ |
|
149 stream := PipeStream readingFrom:('support' , Filename separator , diffCmd). |
|
150 stream isNil ifTrue:[ |
|
151 self error:'cannot execute diff' mayProceed:true. |
|
152 ^ nil. |
|
153 ] |
|
154 ]. |
|
155 |
|
156 diffList := OrderedCollection new. |
|
157 (stream readWaitWithTimeout:10) ifTrue:[ |
|
158 "/ timeout |
|
159 stream close. |
|
160 self error:'cannot execute diff (timeout)' mayProceed:true. |
|
161 ^ nil. |
|
162 ]. |
|
163 |
|
164 [stream atEnd] whileFalse:[ |
|
165 line := stream nextLine. |
|
166 line notNil ifTrue:[diffList add:line] |
|
167 ]. |
|
168 stream close. |
|
169 ] ensure:[ |
|
170 tmpFile1 notNil ifTrue:[ tmpFile1 delete ]. |
|
171 tmpFile2 notNil ifTrue:[ tmpFile2 delete ]. |
|
172 ]. |
|
173 ^ diffList |
|
174 |
|
175 " |
|
176 self |
|
177 diffListFor:#( |
|
178 'hello world' |
|
179 'line1' |
|
180 'line3' |
|
181 'line4' |
|
182 ) |
|
183 and: #( |
|
184 'Hello World' |
|
185 'line1' |
|
186 'line2' |
|
187 'line3' |
|
188 ) |
|
189 " |
|
190 ! ! |
|
191 |
|
192 !DiffListUtility class methodsFor:'documentation'! |
|
193 |
|
194 version_CVS |
|
195 ^ '$Header: /cvs/stx/stx/libtool/DiffListUtility.st,v 1.1 2009-10-10 10:08:51 cg Exp $' |
|
196 ! ! |