2016-11-20 22:48:03 +01:00
|
|
|
|
//visual text comparer
|
|
|
|
|
//by den po - jdp@bk.ru
|
|
|
|
|
|
|
|
|
|
#define MEMSIZE 4096 * 60
|
2020-12-13 02:21:31 +01:00
|
|
|
|
#include "../lib/fs.h"
|
2016-11-20 22:48:03 +01:00
|
|
|
|
#include "../lib/strings.h"
|
|
|
|
|
#include "../lib/obj/console.h"
|
|
|
|
|
|
|
|
|
|
#define MAX_PATH 260
|
|
|
|
|
|
|
|
|
|
#include "32user32.h"
|
|
|
|
|
#include "objects.h"
|
2016-11-23 12:37:13 +01:00
|
|
|
|
#include "diff_gui.h"
|
2016-11-20 22:48:03 +01:00
|
|
|
|
|
|
|
|
|
#define mincmpstrings 2
|
|
|
|
|
#define maxcmpstrings 10
|
|
|
|
|
#define maxcmpoffset 100
|
|
|
|
|
|
2016-11-23 12:37:13 +01:00
|
|
|
|
char window_title[] = "Kolibri Diff tool (Visual Text Comparer)";
|
2016-11-20 22:48:03 +01:00
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
2020-05-26 02:59:44 +02:00
|
|
|
|
notify("'Wrong params! Use format:\nAPPPATH \"PARAM1\" \"PARAM2\"' -E");
|
2016-11-20 22:48:03 +01:00
|
|
|
|
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;
|
|
|
|
|
|
2020-12-13 02:21:31 +01:00
|
|
|
|
read_file(srcfilename, #srcfile, #srcfilesize);
|
|
|
|
|
read_file(dstfilename, #dstfile, #dstfilesize);
|
2016-11-20 22:48:03 +01:00
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
}
|