0,0 → 1,209 |
//visual text comparer |
//by den po - jdp@bk.ru |
|
#define MEMSIZE 4096 * 60 |
#include "../lib/io.h" |
#include "../lib/strings.h" |
#include "../lib/obj/console.h" |
IO io1, io2; |
|
#define MAX_PATH 260 |
|
#include "32user32.h" |
#include "objects.h" |
#include "diff_gui.h" |
|
#define mincmpstrings 2 |
#define maxcmpstrings 10 |
#define maxcmpoffset 100 |
|
char window_title[] = "Kolibri Diff tool (Visual Text Comparer)"; |
|
char* srcfilename; |
char* dstfilename; |
dword srcfile; |
dword dstfile; |
dword srcfilesize; |
dword dstfilesize; |
TCollection srcfilelines; //file lines |
TCollection dstfilelines; |
TCollection srcfilenums; //lines numbers |
TCollection dstfilenums; |
|
struct TSimpleCollection:TSortedCollection |
{ |
TSimpleCollection(); |
int Compare( int Key1, Key2 ); |
}; |
int TSimpleCollection::Compare( int Key1, Key2 ){ |
return Key1-Key2; |
} |
TSimpleCollection::TSimpleCollection():TSortedCollection(1000,1000); |
{ |
comparemethod=#Compare; |
} |
|
TSimpleCollection diffs; //list of differing strings |
dword srcfilelinks; //pointer to the previos line with the same first symbol |
dword dstfilelinks; // |
|
getstrings(dword srcfile,srcfilesize,srcfilelines){ |
ECX=srcfilesize; |
ESI=srcfile; |
WHILE(ECX){ |
$push ECX,ESI |
EAX=srcfilelines; |
EAX.TCollection.Insert(ESI); |
$pop ESI,ECX |
WHILE(ECX){ |
$cld $lodsb ECX--; |
if(AL==0x0D)||(AL==0x0A)DSBYTE[ESI-1]=0; |
if(AL==0x0D)&&(DSBYTE[ESI]==0x0A){$lodsb;ECX--;} |
if(AL==0x0D)||(AL==0x0A)BREAK; |
} |
} |
} |
|
#include "if.h" |
|
bool getparam() |
{ |
int i, param_len = strlen(#param); |
if (param[0]=='"') { |
for (i=1; i<param_len; i++) if (param[i]=='"') param[i]=NULL; |
srcfilename = #param + 1; |
dstfilename = #param + strlen(#param) + 3; |
return true; |
} |
notify("'Wrong params specified. Use next format:\nAPPPATH \"PARAM1\" \"PARAM2\"' -E"); |
return false; |
} |
|
main(){ |
if (param[0]) getparam(); |
if (!srcfilename) || (!dstfilename) gui(); else console(); |
} |
|
console() { |
int i; |
int p; |
int bs,bd,bsc,bdc,bsp,bdp; |
int cache[256]; |
char s1; |
int s2; |
|
srcfile = io1.read(srcfilename); |
dstfile = io2.read(dstfilename); |
|
srcfilesize = io1.FILES_SIZE; |
dstfilesize = io2.FILES_SIZE; |
|
if (!srcfile) die("'First file not found' -E"); |
if (!dstfile) die("'Second file not found' -E"); |
|
srcfilelines.TCollection(srcfilesize/40,8192); |
dstfilelines.TCollection(dstfilesize/40,8192); |
//fill line pointers |
getstrings(srcfile,srcfilesize,#srcfilelines); |
getstrings(dstfile,dstfilesize,#dstfilelines); |
srcfilenums.TCollection(srcfilelines.Count,1000); |
dstfilenums.TCollection(dstfilelines.Count,1000); |
|
srcfilelinks=malloc(srcfilelines.Count*4); |
dstfilelinks=malloc(dstfilelines.Count*4); |
|
//fill links on the next strings with the same first symbols |
FillMemory(#cache,sizeof(cache),-1); i=srcfilelines.Count; |
WHILE(i){ |
i--; |
EBX=srcfilelines.At(i); EBX=DSBYTE[EBX]; |
DSDWORD[i<<2+srcfilelinks]=cache[EBX*4]; |
cache[EBX*4]=i; |
} |
FillMemory(#cache,sizeof(cache),-1); i=dstfilelines.Count; |
WHILE(i){ |
i--; |
EBX=dstfilelines.At(i); EBX=DSBYTE[EBX]; |
DSDWORD[i<<2+dstfilelinks]=cache[EBX*4]; |
cache[EBX*4]=i; |
} |
|
diffs.TSimpleCollection(); |
|
while( bsp < srcfilelines.Count ) || ( bdp < dstfilelines.Count ) |
{ |
//////////////////////////////////////////////////////// |
bsc=0; |
p=dstfilelines.At(bdp);//current dst position |
s1=DSBYTE[p]; |
bs=bsp+1;//foundĀ src line, bsc - number of matched |
while( bs != -1 )//no next line starting with the same symbols |
&&(bs-bsp<=maxcmpoffset)//check for 100 lines depth |
&&(bs<srcfilelines.Count) |
{ |
s2=srcfilelines.At(bs); |
if(!strcmp(p,s2)) |
{//line found |
bsc=1; |
WHILE(bsc<maxcmpstrings)//counting number of matching lines |
&&(bdp+bsc<dstfilelines.Count) |
&&(bs+bsc<srcfilelines.Count) |
&&(!strcmp(dstfilelines.At(bdp+bsc),srcfilelines.At(bs+bsc)))bsc++; |
BREAK; |
} |
if(DSBYTE[s2]==s1)bs=DSDWORD[bs<<2+srcfilelinks];else bs++; |
} |
bdc=0; |
p=srcfilelines.At(bsp);//current src position |
s1=DSBYTE[p]; |
bd=bdp+1;//foundĀ dst line, bsc - number of matched |
while( bd != -1 )//no next line starting with the same symbols |
&&(bd-bdp<=maxcmpoffset)//check for 100 lines depth |
&&(bd<dstfilelines.Count) |
{ |
s2=dstfilelines.At(bd); |
if(!strcmp(p,s2)) |
{ |
bdc=1; |
WHILE(bdc<maxcmpstrings)//counting number of matching lines |
&&(bsp+bdc<srcfilelines.Count) |
&&(bd+bdc<dstfilelines.Count) |
&&(!strcmp(srcfilelines.At(bsp+bdc),dstfilelines.At(bd+bdc)))bdc++; |
BREAK; |
} |
if(DSBYTE[s2]==s1)bd=DSDWORD[bd<<2+dstfilelinks];else bd++; |
} |
|
if(bsc<bdc) |
if(bd-bdp<bdc) |
||(bdc>=mincmpstrings) |
{ |
WHILE(bdp<bd){ |
diffs.Insert(srcfilenums.Count); |
srcfilenums.Insert(-1); dstfilenums.Insert(bdp); bdp++; |
} |
continue; |
} |
|
if(strcmp(srcfilelines.At(bsp),dstfilelines.At(bdp)))diffs.Insert(srcfilenums.Count); |
//lines are equal |
srcfilenums.Insert(bsp); bsp++; |
dstfilenums.Insert(bdp); bdp++; |
CONTINUE; |
} |
|
free(srcfilelinks); |
free(dstfilelinks); |
|
if(!diffs.Count) |
notify("'Nothing to compare' -E"); |
else ifinit(); |
|
diffs.DeleteAll(); delete diffs; |
dstfilenums.DeleteAll(); delete dstfilenums; |
srcfilenums.DeleteAll(); delete srcfilenums; |
dstfilelines.DeleteAll(); delete dstfilelines; |
srcfilelines.DeleteAll(); delete srcfilelines; |
free(dstfile); |
free(srcfile); |
} |