Subversion Repositories Kolibri OS

Rev

Rev 7985 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

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