Rev 6732 | Rev 8383 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6732 | Rev 6746 | ||
---|---|---|---|
1 | //visual text comparer |
1 | //visual text comparer |
2 | //by den po - jdp@bk.ru |
2 | //by den po - jdp@bk.ru |
3 | 3 | ||
4 | #define MEMSIZE 4096 * 60 |
4 | #define MEMSIZE 4096 * 60 |
5 | #include "../lib/io.h" |
5 | #include "../lib/io.h" |
6 | #include "../lib/strings.h" |
6 | #include "../lib/strings.h" |
7 | #include "../lib/obj/console.h" |
7 | #include "../lib/obj/console.h" |
8 | IO io1, io2; |
8 | IO io1, io2; |
9 | 9 | ||
10 | #define MAX_PATH 260 |
10 | #define MAX_PATH 260 |
11 | 11 | ||
12 | #include "32user32.h" |
12 | #include "32user32.h" |
13 | #include "objects.h" |
13 | #include "objects.h" |
14 | #include "vfc_gui.h" |
14 | #include "diff_gui.h" |
15 | 15 | ||
16 | #define mincmpstrings 2 |
16 | #define mincmpstrings 2 |
17 | #define maxcmpstrings 10 |
17 | #define maxcmpstrings 10 |
18 | #define maxcmpoffset 100 |
18 | #define maxcmpoffset 100 |
19 | 19 | ||
20 | char window_title[] = "Visual Text Comparer (Diff tool)"; |
20 | char window_title[] = "Kolibri Diff tool (Visual Text Comparer)"; |
21 | 21 | ||
22 | char* srcfilename; |
22 | char* srcfilename; |
23 | char* dstfilename; |
23 | char* dstfilename; |
24 | dword srcfile; |
24 | dword srcfile; |
25 | dword dstfile; |
25 | dword dstfile; |
26 | dword srcfilesize; |
26 | dword srcfilesize; |
27 | dword dstfilesize; |
27 | dword dstfilesize; |
28 | TCollection srcfilelines; //file lines |
28 | TCollection srcfilelines; //file lines |
29 | TCollection dstfilelines; |
29 | TCollection dstfilelines; |
30 | TCollection srcfilenums; //lines numbers |
30 | TCollection srcfilenums; //lines numbers |
31 | TCollection dstfilenums; |
31 | TCollection dstfilenums; |
32 | 32 | ||
33 | struct TSimpleCollection:TSortedCollection |
33 | struct TSimpleCollection:TSortedCollection |
34 | { |
34 | { |
35 | TSimpleCollection(); |
35 | TSimpleCollection(); |
36 | int Compare( int Key1, Key2 ); |
36 | int Compare( int Key1, Key2 ); |
37 | }; |
37 | }; |
38 | int TSimpleCollection::Compare( int Key1, Key2 ){ |
38 | int TSimpleCollection::Compare( int Key1, Key2 ){ |
39 | return Key1-Key2; |
39 | return Key1-Key2; |
40 | } |
40 | } |
41 | TSimpleCollection::TSimpleCollection():TSortedCollection(1000,1000); |
41 | TSimpleCollection::TSimpleCollection():TSortedCollection(1000,1000); |
42 | { |
42 | { |
43 | comparemethod=#Compare; |
43 | comparemethod=#Compare; |
44 | } |
44 | } |
45 | 45 | ||
46 | TSimpleCollection diffs; //list of differing strings |
46 | TSimpleCollection diffs; //list of differing strings |
47 | dword srcfilelinks; //pointer to the previos line with the same first symbol |
47 | dword srcfilelinks; //pointer to the previos line with the same first symbol |
48 | dword dstfilelinks; // |
48 | dword dstfilelinks; // |
49 | 49 | ||
50 | getstrings(dword srcfile,srcfilesize,srcfilelines){ |
50 | getstrings(dword srcfile,srcfilesize,srcfilelines){ |
51 | ECX=srcfilesize; |
51 | ECX=srcfilesize; |
52 | ESI=srcfile; |
52 | ESI=srcfile; |
53 | WHILE(ECX){ |
53 | WHILE(ECX){ |
54 | $push ECX,ESI |
54 | $push ECX,ESI |
55 | EAX=srcfilelines; |
55 | EAX=srcfilelines; |
56 | EAX.TCollection.Insert(ESI); |
56 | EAX.TCollection.Insert(ESI); |
57 | $pop ESI,ECX |
57 | $pop ESI,ECX |
58 | WHILE(ECX){ |
58 | WHILE(ECX){ |
59 | $cld $lodsb ECX--; |
59 | $cld $lodsb ECX--; |
60 | if(AL==0x0D)||(AL==0x0A)DSBYTE[ESI-1]=0; |
60 | if(AL==0x0D)||(AL==0x0A)DSBYTE[ESI-1]=0; |
61 | if(AL==0x0D)&&(DSBYTE[ESI]==0x0A){$lodsb;ECX--;} |
61 | if(AL==0x0D)&&(DSBYTE[ESI]==0x0A){$lodsb;ECX--;} |
62 | if(AL==0x0D)||(AL==0x0A)BREAK; |
62 | if(AL==0x0D)||(AL==0x0A)BREAK; |
63 | } |
63 | } |
64 | } |
64 | } |
65 | } |
65 | } |
66 | 66 | ||
67 | #include "if.h" |
67 | #include "if.h" |
68 | 68 | ||
69 | bool getparam() |
69 | bool getparam() |
70 | { |
70 | { |
71 | int i, param_len = strlen(#param); |
71 | int i, param_len = strlen(#param); |
72 | if (param[0]=='"') { |
72 | if (param[0]=='"') { |
73 | for (i=1; i |
73 | for (i=1; i |
74 | srcfilename = #param + 1; |
74 | srcfilename = #param + 1; |
75 | dstfilename = #param + strlen(#param) + 3; |
75 | dstfilename = #param + strlen(#param) + 3; |
76 | return true; |
76 | return true; |
77 | } |
77 | } |
78 | notify("'Wrong params specified. Use next format:\nAPPPATH \"PARAM1\" \"PARAM2\"' -E"); |
78 | notify("'Wrong params specified. Use next format:\nAPPPATH \"PARAM1\" \"PARAM2\"' -E"); |
79 | return false; |
79 | return false; |
80 | } |
80 | } |
81 | 81 | ||
82 | main(){ |
82 | main(){ |
83 | if (param[0]) getparam(); |
83 | if (param[0]) getparam(); |
84 | if (!srcfilename) || (!dstfilename) gui(); else console(); |
84 | if (!srcfilename) || (!dstfilename) gui(); else console(); |
85 | } |
85 | } |
86 | 86 | ||
87 | console() { |
87 | console() { |
88 | int i; |
88 | int i; |
89 | int p; |
89 | int p; |
90 | int bs,bd,bsc,bdc,bsp,bdp; |
90 | int bs,bd,bsc,bdc,bsp,bdp; |
91 | int cache[256]; |
91 | int cache[256]; |
92 | char s1; |
92 | char s1; |
93 | int s2; |
93 | int s2; |
94 | 94 | ||
95 | srcfile = io1.read(srcfilename); |
95 | srcfile = io1.read(srcfilename); |
96 | dstfile = io2.read(dstfilename); |
96 | dstfile = io2.read(dstfilename); |
97 | 97 | ||
98 | srcfilesize = io1.FILES_SIZE; |
98 | srcfilesize = io1.FILES_SIZE; |
99 | dstfilesize = io2.FILES_SIZE; |
99 | dstfilesize = io2.FILES_SIZE; |
100 | 100 | ||
101 | if (!srcfile) die("'First file not found' -E"); |
101 | if (!srcfile) die("'First file not found' -E"); |
102 | if (!dstfile) die("'Second file not found' -E"); |
102 | if (!dstfile) die("'Second file not found' -E"); |
103 | 103 | ||
104 | srcfilelines.TCollection(srcfilesize/40,8192); |
104 | srcfilelines.TCollection(srcfilesize/40,8192); |
105 | dstfilelines.TCollection(dstfilesize/40,8192); |
105 | dstfilelines.TCollection(dstfilesize/40,8192); |
106 | //fill line pointers |
106 | //fill line pointers |
107 | getstrings(srcfile,srcfilesize,#srcfilelines); |
107 | getstrings(srcfile,srcfilesize,#srcfilelines); |
108 | getstrings(dstfile,dstfilesize,#dstfilelines); |
108 | getstrings(dstfile,dstfilesize,#dstfilelines); |
109 | srcfilenums.TCollection(srcfilelines.Count,1000); |
109 | srcfilenums.TCollection(srcfilelines.Count,1000); |
110 | dstfilenums.TCollection(dstfilelines.Count,1000); |
110 | dstfilenums.TCollection(dstfilelines.Count,1000); |
111 | 111 | ||
112 | srcfilelinks=malloc(srcfilelines.Count*4); |
112 | srcfilelinks=malloc(srcfilelines.Count*4); |
113 | dstfilelinks=malloc(dstfilelines.Count*4); |
113 | dstfilelinks=malloc(dstfilelines.Count*4); |
114 | 114 | ||
115 | //fill links on the next strings with the same first symbols |
115 | //fill links on the next strings with the same first symbols |
116 | FillMemory(#cache,sizeof(cache),-1); i=srcfilelines.Count; |
116 | FillMemory(#cache,sizeof(cache),-1); i=srcfilelines.Count; |
117 | WHILE(i){ |
117 | WHILE(i){ |
118 | i--; |
118 | i--; |
119 | EBX=srcfilelines.At(i); EBX=DSBYTE[EBX]; |
119 | EBX=srcfilelines.At(i); EBX=DSBYTE[EBX]; |
120 | DSDWORD[i<<2+srcfilelinks]=cache[EBX*4]; |
120 | DSDWORD[i<<2+srcfilelinks]=cache[EBX*4]; |
121 | cache[EBX*4]=i; |
121 | cache[EBX*4]=i; |
122 | } |
122 | } |
123 | FillMemory(#cache,sizeof(cache),-1); i=dstfilelines.Count; |
123 | FillMemory(#cache,sizeof(cache),-1); i=dstfilelines.Count; |
124 | WHILE(i){ |
124 | WHILE(i){ |
125 | i--; |
125 | i--; |
126 | EBX=dstfilelines.At(i); EBX=DSBYTE[EBX]; |
126 | EBX=dstfilelines.At(i); EBX=DSBYTE[EBX]; |
127 | DSDWORD[i<<2+dstfilelinks]=cache[EBX*4]; |
127 | DSDWORD[i<<2+dstfilelinks]=cache[EBX*4]; |
128 | cache[EBX*4]=i; |
128 | cache[EBX*4]=i; |
129 | } |
129 | } |
130 | 130 | ||
131 | diffs.TSimpleCollection(); |
131 | diffs.TSimpleCollection(); |
132 | 132 | ||
133 | while( bsp < srcfilelines.Count ) || ( bdp < dstfilelines.Count ) |
133 | while( bsp < srcfilelines.Count ) || ( bdp < dstfilelines.Count ) |
134 | { |
134 | { |
135 | //////////////////////////////////////////////////////// |
135 | //////////////////////////////////////////////////////// |
136 | bsc=0; |
136 | bsc=0; |
137 | p=dstfilelines.At(bdp);//current dst position |
137 | p=dstfilelines.At(bdp);//current dst position |
138 | s1=DSBYTE[p]; |
138 | s1=DSBYTE[p]; |
139 | bs=bsp+1;//found src line, bsc - number of matched |
139 | bs=bsp+1;//found src line, bsc - number of matched |
140 | while( bs != -1 )//no next line starting with the same symbols |
140 | while( bs != -1 )//no next line starting with the same symbols |
141 | &&(bs-bsp<=maxcmpoffset)//check for 100 lines depth |
141 | &&(bs-bsp<=maxcmpoffset)//check for 100 lines depth |
142 | &&(bs |
142 | &&(bs |
143 | { |
143 | { |
144 | s2=srcfilelines.At(bs); |
144 | s2=srcfilelines.At(bs); |
145 | if(!strcmp(p,s2)) |
145 | if(!strcmp(p,s2)) |
146 | {//line found |
146 | {//line found |
147 | bsc=1; |
147 | bsc=1; |
148 | WHILE(bsc |
148 | WHILE(bsc |
149 | &&(bdp+bsc |
149 | &&(bdp+bsc |
150 | &&(bs+bsc |
150 | &&(bs+bsc |
151 | &&(!strcmp(dstfilelines.At(bdp+bsc),srcfilelines.At(bs+bsc)))bsc++; |
151 | &&(!strcmp(dstfilelines.At(bdp+bsc),srcfilelines.At(bs+bsc)))bsc++; |
152 | BREAK; |
152 | BREAK; |
153 | } |
153 | } |
154 | if(DSBYTE[s2]==s1)bs=DSDWORD[bs<<2+srcfilelinks];else bs++; |
154 | if(DSBYTE[s2]==s1)bs=DSDWORD[bs<<2+srcfilelinks];else bs++; |
155 | } |
155 | } |
156 | bdc=0; |
156 | bdc=0; |
157 | p=srcfilelines.At(bsp);//current src position |
157 | p=srcfilelines.At(bsp);//current src position |
158 | s1=DSBYTE[p]; |
158 | s1=DSBYTE[p]; |
159 | bd=bdp+1;//found dst line, bsc - number of matched |
159 | bd=bdp+1;//found dst line, bsc - number of matched |
160 | while( bd != -1 )//no next line starting with the same symbols |
160 | while( bd != -1 )//no next line starting with the same symbols |
161 | &&(bd-bdp<=maxcmpoffset)//check for 100 lines depth |
161 | &&(bd-bdp<=maxcmpoffset)//check for 100 lines depth |
162 | &&(bd |
162 | &&(bd |
163 | { |
163 | { |
164 | s2=dstfilelines.At(bd); |
164 | s2=dstfilelines.At(bd); |
165 | if(!strcmp(p,s2)) |
165 | if(!strcmp(p,s2)) |
166 | { |
166 | { |
167 | bdc=1; |
167 | bdc=1; |
168 | WHILE(bdc |
168 | WHILE(bdc |
169 | &&(bsp+bdc |
169 | &&(bsp+bdc |
170 | &&(bd+bdc |
170 | &&(bd+bdc |
171 | &&(!strcmp(srcfilelines.At(bsp+bdc),dstfilelines.At(bd+bdc)))bdc++; |
171 | &&(!strcmp(srcfilelines.At(bsp+bdc),dstfilelines.At(bd+bdc)))bdc++; |
172 | BREAK; |
172 | BREAK; |
173 | } |
173 | } |
174 | if(DSBYTE[s2]==s1)bd=DSDWORD[bd<<2+dstfilelinks];else bd++; |
174 | if(DSBYTE[s2]==s1)bd=DSDWORD[bd<<2+dstfilelinks];else bd++; |
175 | } |
175 | } |
176 | 176 | ||
177 | if(bsc |
177 | if(bsc |
178 | if(bd-bdp |
178 | if(bd-bdp |
179 | ||(bdc>=mincmpstrings) |
179 | ||(bdc>=mincmpstrings) |
180 | { |
180 | { |
181 | WHILE(bdp |
181 | WHILE(bdp |
182 | diffs.Insert(srcfilenums.Count); |
182 | diffs.Insert(srcfilenums.Count); |
183 | srcfilenums.Insert(-1); dstfilenums.Insert(bdp); bdp++; |
183 | srcfilenums.Insert(-1); dstfilenums.Insert(bdp); bdp++; |
184 | } |
184 | } |
185 | continue; |
185 | continue; |
186 | } |
186 | } |
187 | 187 | ||
188 | if(strcmp(srcfilelines.At(bsp),dstfilelines.At(bdp)))diffs.Insert(srcfilenums.Count); |
188 | if(strcmp(srcfilelines.At(bsp),dstfilelines.At(bdp)))diffs.Insert(srcfilenums.Count); |
189 | //lines are equal |
189 | //lines are equal |
190 | srcfilenums.Insert(bsp); bsp++; |
190 | srcfilenums.Insert(bsp); bsp++; |
191 | dstfilenums.Insert(bdp); bdp++; |
191 | dstfilenums.Insert(bdp); bdp++; |
192 | CONTINUE; |
192 | CONTINUE; |
193 | } |
193 | } |
194 | 194 | ||
195 | free(srcfilelinks); |
195 | free(srcfilelinks); |
196 | free(dstfilelinks); |
196 | free(dstfilelinks); |
197 | 197 | ||
198 | if(!diffs.Count) |
198 | if(!diffs.Count) |
199 | notify("'Nothing to compare' -E"); |
199 | notify("'Nothing to compare' -E"); |
200 | else ifinit(); |
200 | else ifinit(); |
201 | 201 | ||
202 | diffs.DeleteAll(); delete diffs; |
202 | diffs.DeleteAll(); delete diffs; |
203 | dstfilenums.DeleteAll(); delete dstfilenums; |
203 | dstfilenums.DeleteAll(); delete dstfilenums; |
204 | srcfilenums.DeleteAll(); delete srcfilenums; |
204 | srcfilenums.DeleteAll(); delete srcfilenums; |
205 | dstfilelines.DeleteAll(); delete dstfilelines; |
205 | dstfilelines.DeleteAll(); delete dstfilelines; |
206 | srcfilelines.DeleteAll(); delete srcfilelines; |
206 | srcfilelines.DeleteAll(); delete srcfilelines; |
207 | free(dstfile); |
207 | free(dstfile); |
208 | free(srcfile); |
208 | free(srcfile); |
209 | } |
209 | } |
210 | > |
210 | > |
211 | > |
211 | > |
212 | >2+dstfilelinks];else><2+dstfilelinks];else> |
212 | >2+dstfilelinks];else><2+dstfilelinks];else> |
213 | > |
213 | > |
214 | > |
214 | > |
215 | >=maxcmpoffset)//check>2+srcfilelinks];else><2+srcfilelinks];else> |
215 | >=maxcmpoffset)//check>2+srcfilelinks];else><2+srcfilelinks];else> |
216 | > |
216 | > |
217 | > |
217 | > |
218 | >=maxcmpoffset)//check>>>2+dstfilelinks]=cache[EBX*4]; |
218 | >=maxcmpoffset)//check>>>2+dstfilelinks]=cache[EBX*4]; |
219 | ><2+dstfilelinks]=cache[EBX*4]; |
219 | ><2+dstfilelinks]=cache[EBX*4]; |
220 | >2+srcfilelinks]=cache[EBX*4]; |
220 | >2+srcfilelinks]=cache[EBX*4]; |
221 | ><2+srcfilelinks]=cache[EBX*4]; |
221 | ><2+srcfilelinks]=cache[EBX*4]; |
222 | > |
222 | > |