Main Page | Class Hierarchy | Class List | File List | Class Members

diff.cs

00001 namespace JLibDiff
00002 {
00003         using System;
00004         using System.Collections.Specialized;
00005         
00006 
00082         public class diff : define, HunkVisitable
00083         {
00084                 
00085                 internal System.Collections.ArrayList v = new System.Collections.ArrayList();
00086                 
00087                 /*
00088                 * Allocates a new <code>diff</code> containing no Hunks.
00089                 */
00090                 public diff()
00091                 {
00092                 }
00093                 
00094                 /*
00095                 * Allocates a new <code>diff</code> which contains Hunks corresponding 
00096                 * to the difference between the two files passed in arguments.
00097                 *
00098                 * @param s1  first file to compare.
00099                 * @param s2  second file to compare.
00100                 */
00101                 public diff(System.String s1, System.String s2)
00102                 {
00103                         diffFile(s1, s2);
00104                 }
00105                 
00106                 /*
00107                 * Returns a vector containing Hunks.
00108                 */
00109                 public virtual System.Collections.ArrayList getHunk()
00110                 {
00111                         return v;
00112                 }
00113                 
00114                 /*
00115                 * Returns the number of hunks in the vector.
00116                 */
00117                 public virtual int numberOfHunk()
00118                 {
00119                         return v.Count;
00120                 }
00121                 
00122                 /*
00123                 * Return the hunk at the specified index.
00124                 *
00125                 * @param i  index of the hunk that will be returned.
00126                 */
00127                 public virtual Hunk hunkAt(int i)
00128                 {
00129                         return (Hunk) v[i];
00130                 }
00131                 
00132                 /*
00133                 * Accept a visitor in order to visit the collection of hunks.
00134                 *
00135                 * @param visitor  the HunkVisitor.
00136                 */
00137                 public virtual void  accept(HunkVisitor visitor)
00138                 {
00139                          for (System.Collections.IEnumerator e = v.GetEnumerator(); e.MoveNext(); )
00140                         {
00141                                 Hunk h = (Hunk) e.Current;
00142                                 h.accept(visitor);
00143                         }
00144                 }
00145                 
00146                 /*
00147                 * Compares two files and updates the vector of Hunks.
00148                 *
00149                 * @param s1  first file to compare.
00150                 * @param s2  second file to compare.
00151                 */
00152                 public virtual void  diffFile(System.String s1, System.String s2)
00153                 {
00154                         
00155                         System.IO.StreamReader in_Renamed = new System.IO.StreamReader(new System.IO.StreamReader(s1).BaseStream);
00156                         System.IO.StreamReader inn = new System.IO.StreamReader(new System.IO.StreamReader(s2).BaseStream);
00157                         diffBuffer(in_Renamed, inn);
00158                         in_Renamed.Close();
00159                         inn.Close();
00160                 }
00161                 
00162                 /*
00163                 * Compares two BufferedReaders and updates the vector of Hunks.
00164                 *
00165                 * @param in  first BufferedReader to compare.
00166                 * @param inn second BufferedReader to compare.
00167                 */
00168                 public virtual void  diffBuffer(System.IO.StreamReader in_Renamed, System.IO.StreamReader inn)
00169                 {
00170                         // first create the string buffers to determine our array size
00171                         System.String s;
00172                         StringCollection listA = new StringCollection();
00173                         StringCollection listB = new StringCollection();
00174                         
00175                         while ((s = in_Renamed.ReadLine()) != null)
00176                         {
00177                                 listA.Add(s);
00178                         }
00179                         while ((s = inn.ReadLine()) != null)
00180                         {
00181                                 listB.Add(s);
00182                         }
00183                         
00184                         System.String[] A = new string[listA.Count];
00185                         listA.CopyTo(A, 0);
00186                         System.String[] B = new string[listB.Count];
00187                         listB.CopyTo(B, 0);
00188                         
00189                         int m = (int) (A.Length);
00190                         int n = (int) (B.Length);
00191                         int maxlines = ((m > n)?m:n);
00192                         int origin = maxlines;
00193                         int max_d = 2 * maxlines;
00194                         int d = 1;
00195                         int /*i, j,*/ k, lower, upper, row, col;
00196                         
00197                         int[] last_d = new int[2 * maxlines + 1]; //row containing last d
00198                         //pour chaque diag
00199                         edit[] script = new edit[2 * maxlines + 1]; //correspond a l'edit script */
00200                         
00201                         
00202                          for (row = 0; row < m && row < n && A[row].Equals(B[row]); row++)
00203                                 ;
00204                         last_d[origin] = row;
00205                         script[origin] = null;
00206                         if (row == m)
00207                                 lower = origin + 1;
00208                         else
00209                                 lower = origin - 1;
00210                         if (row == n)
00211                                 upper = origin - 1;
00212                         else
00213                                 upper = origin + 1;
00214                         if (lower > upper)
00215                                 return ;
00216                         else
00217                         {
00218                                 
00219                                  for (d = 1; d <= max_d; d++)
00220                                 {
00221                                         //for each value of edit distance  
00222                                          for (k = lower; k <= upper; k += 2)
00223                                         {
00224                                                 edit e = new edit();
00225                                                 if (e == null)
00226                                                 {
00227                                                         System.Console.Out.WriteLine(";;;;exceed" + d);
00228                                                         System.Environment.Exit(0);
00229                                                 }
00230                                                 if (k == origin - d || k != origin + d && last_d[k + 1] >= last_d[k - 1])
00231                                                 {
00232                                                         row = last_d[k + 1] + 1;
00233                                                         e.setnext(script[k + 1]);
00234                                                         e.setop(JLibDiff.define_Fields.DELETE);
00235                                                 }
00236                                                 else
00237                                                 {
00238                                                         row = last_d[k - 1];
00239                                                         e.setnext(script[k - 1]);
00240                                                         e.setop(JLibDiff.define_Fields.INSERT);
00241                                                 }
00242                                                 e.setline1(row);
00243                                                 col = row + k - origin;
00244                                                 e.setline2(col);
00245                                                 script[k] = e;
00246                                                 while (row < m && col < n && A[row].Equals(B[col]))
00247                                                 {
00248                                                         row++;
00249                                                         col++;
00250                                                 }
00251                                                 last_d[k] = row;
00252                                                 if (row == m && col == n)
00253                                                 {
00254                                                         v = getHunk(script[k], A, B);
00255                                                         return ;
00256                                                 }
00257                                                 if (row == m)
00258                                                         lower = k + 2;
00259                                                 if (col == n)
00260                                                         upper = k - 2;
00261                                         }
00262                                         
00263                                         lower--;
00264                                         upper++;
00265                                         
00266                                 }
00267                         }
00268                 }
00269                 
00270                 /*
00271                 * Compares two strings and updates the vector of Hunks.
00272                 *
00273                 * @param s1   first string to compare.
00274                 * @param s2   second string to compare.
00275                 */
00276                 public virtual void  diffString(System.String s1, System.String s2)
00277                 {
00278                         
00279                         int /*i, j,*/ max_d = 2 * JLibDiff.define_Fields.MAXLINES, m = 0, n = 0, lower, upper, d = 1, k, row, col;
00280                         
00281                         
00282                         int[] last_d = new int[2 * JLibDiff.define_Fields.MAXLINES + 1];
00283                         
00284                         edit[] script = new edit[2 * JLibDiff.define_Fields.MAXLINES + 1];
00285                         
00286                         
00287 //                      char c;
00288                         char[] A = new char[JLibDiff.define_Fields.MAXLINES], B = new char[JLibDiff.define_Fields.MAXLINES];
00289                         
00290                         //UPGRADE_NOTE: This code will be optimized in the future;
00291                         int i2;
00292                         int j2;
00293                         i2 = 0;
00294                         j2 = 0;
00295                         while (i2 < s1.Length)
00296                         {
00297                                 A[j2] = s1[i2];
00298                                 i2++;
00299                                 j2++;
00300                         }
00301                         //UPGRADE_NOTE: This code will be optimized in the future;
00302                         int i3;
00303                         int j3;
00304                         i3 = 0;
00305                         j3 = 0;
00306                         while (i3 < s2.Length)
00307                         {
00308                                 B[j3] = s2[i3];
00309                                 i3++;
00310                                 j3++;
00311                         }
00312                         
00313                         m = s1.Length;
00314                         n = s2.Length;
00315                         
00316                          for (row = 0; row < m && row < n && A[row] == B[row]; row++)
00317                                 ;
00318                         last_d[JLibDiff.define_Fields.ORIGIN] = row;
00319                         script[JLibDiff.define_Fields.ORIGIN] = null;
00320                         if (row == m)
00321                                 lower = JLibDiff.define_Fields.ORIGIN + 1;
00322                         else
00323                                 lower = JLibDiff.define_Fields.ORIGIN - 1;
00324                         if (row == n)
00325                                 upper = JLibDiff.define_Fields.ORIGIN - 1;
00326                         else
00327                                 upper = JLibDiff.define_Fields.ORIGIN + 1;
00328                         if (lower > upper)
00329                                 return ;
00330                         else
00331                         {
00332                                 
00333                                  for (d = 1; d <= max_d; d++)
00334                                 {
00335                                          for (k = lower; k <= upper; k += 2)
00336                                         {
00337                                                 edit e = new edit();
00338                                                 if (e == null)
00339                                                 {
00340                                                         System.Console.Out.WriteLine(";;;;exceed" + d);
00341                                                         System.Environment.Exit(0);
00342                                                 }
00343                                                 if (k == JLibDiff.define_Fields.ORIGIN - d || k != JLibDiff.define_Fields.ORIGIN + d && last_d[k + 1] >= last_d[k - 1])
00344                                                 {
00345                                                         row = last_d[k + 1] + 1;
00346                                                         e.setnext(script[k + 1]);
00347                                                         e.setop(JLibDiff.define_Fields.DELETE);
00348                                                 }
00349                                                 else
00350                                                 {
00351                                                         row = last_d[k - 1];
00352                                                         e.setnext(script[k - 1]);
00353                                                         e.setop(JLibDiff.define_Fields.INSERT);
00354                                                 }
00355                                                 e.setline1(row);
00356                                                 col = row + k - JLibDiff.define_Fields.ORIGIN;
00357                                                 e.setline2(col);
00358                                                 script[k] = e;
00359                                                 while (row < m && col < n && A[row] == B[col])
00360                                                 {
00361                                                         row++;
00362                                                         col++;
00363                                                 }
00364                                                 last_d[k] = row;
00365                                                 if (row == m && col == n)
00366                                                 {
00367                                                         v = getHunk(script[k], A, B);
00368                                                         return ;
00369                                                 }
00370                                                 if (row == m)
00371                                                         lower = k + 2;
00372                                                 if (col == n)
00373                                                         upper = k - 2;
00374                                         }
00375                                         
00376                                         lower--;
00377                                         upper++;
00378                                         
00379                                 }
00380                                 System.Console.Out.WriteLine(";;;;exceed" + d);
00381                         }
00382                 }
00383                 
00384                 /*
00385                 * Generates Hunks and returns them in a vector.
00386                 */
00387                 private static System.Collections.ArrayList getHunk(edit start, System.String[] A, System.String[] B)
00388                 {
00389                         System.Collections.ArrayList v = new System.Collections.ArrayList();
00390                         bool change;
00391                         int i;
00392                         edit ep = new edit();
00393                         edit behind = new edit();
00394                         edit ahead = new edit();
00395                         edit a = new edit();
00396                         edit b = new edit();
00397                         ahead = start;
00398                         ahead = start;
00399                         ep = null;
00400                         while (ahead != null)
00401                         {
00402                                 behind = ep;
00403                                 ep = ahead;
00404                                 ahead = ahead.next;
00405                                 ep.next = behind;
00406                         }
00407                         
00408                         while (ep != null)
00409                         {
00410                                 b = ep;
00411                                 if (ep.op == JLibDiff.define_Fields.INSERT)
00412                                 {
00413                                         a = ep;
00414                                         behind = ep.next;
00415                                         while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && ep.line1 == behind.line1)
00416                                         {
00417                                                 a = behind;
00418                                                 behind = behind.next;
00419                                         }
00420                                         HunkAdd add = new HunkAdd();
00421                                         add.ld1 = ep.line1;
00422                                         add.ld2 = ep.line2;
00423                                         add.lf2 = a.line2;
00424                                         do 
00425                                         {
00426                                                 add.b.Add(B[ep.line2 - 1] + "\n");
00427                                                 ep = ep.next;
00428                                         }
00429                                         while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00430                                         add.next = null;
00431                                         if (v.Count != 0)
00432                                         {
00433                                                 System.Collections.ArrayList temp_arraylist;
00434                                                 temp_arraylist = v;
00435                                                 ((Hunk) temp_arraylist[temp_arraylist.Count - 1]).next = add;
00436                                         }
00437                                         v.Add(add);
00438                                 }
00439                                 else
00440                                 {
00441                                         do 
00442                                         {
00443                                                 a = b;
00444                                                 b = b.next;
00445                                         }
00446                                         while (b != null && b.op == JLibDiff.define_Fields.DELETE && b.line1 == a.line1 + 1);
00447                                         change = (b != null && b.op == JLibDiff.define_Fields.INSERT && b.line1 == a.line1);
00448                                         if (change)
00449                                         {
00450                                                 HunkChange cha = new HunkChange();
00451                                                 cha.ld1 = ep.line1;
00452                                                 cha.lf1 = a.line1;
00453                                                 i = 0;
00454                                                 behind = b;
00455                                                 while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && behind.line1 == b.line1)
00456                                                 {
00457                                                         i++;
00458                                                         behind = behind.next;
00459                                                 }
00460                                                 cha.ld2 = b.line2;
00461                                                 cha.lf2 = i - 1 + b.line2;
00462                                                 do 
00463                                                 {
00464                                                         cha.a.Add(A[ep.line1 - 1] + "\n");
00465                                                         ep = ep.next;
00466                                                 }
00467                                                 while (ep != b);
00468                                                 if (!change)
00469                                                         continue;
00470                                                 do 
00471                                                 {
00472                                                         cha.b.Add(B[ep.line2 - 1] + "\n");
00473                                                         ep = ep.next;
00474                                                 }
00475                                                 while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00476                                                 cha.next = null;
00477                                                 if (v.Count != 0)
00478                                                 {
00479                                                         System.Collections.ArrayList temp_arraylist2;
00480                                                         temp_arraylist2 = v;
00481                                                         ((Hunk) temp_arraylist2[temp_arraylist2.Count - 1]).next = cha;
00482                                                 }
00483                                                 v.Add(cha);
00484                                         }
00485                                         else
00486                                         {
00487                                                 
00488                                                 HunkDel del = new HunkDel();
00489                                                 del.ld1 = ep.line1;
00490                                                 del.lf1 = a.line1;
00491                                                 del.ld2 = ep.line2;
00492                                                 
00493                                                 do 
00494                                                 {
00495                                                         del.a.Add(A[ep.line1 - 1] + "\n");
00496                                                         ep = ep.next;
00497                                                 }
00498                                                 while (ep != b);
00499                                                 del.next = null;
00500                                                 if (v.Count != 0)
00501                                                 {
00502                                                         System.Collections.ArrayList temp_arraylist3;
00503                                                         temp_arraylist3 = v;
00504                                                         ((Hunk) temp_arraylist3[temp_arraylist3.Count - 1]).next = del;
00505                                                 }
00506                                                 v.Add(del);
00507                                                 
00508                                         }
00509                                 }
00510                         }
00511                         return v;
00512                 }
00513                 
00514                 /*
00515                 * Generates Hunks and returns them in a vector.
00516                 */
00517                 private static System.Collections.ArrayList getHunk(edit start, char[] A, char[] B)
00518                 {
00519                         System.Collections.ArrayList v = new System.Collections.ArrayList();
00520                         
00521                         bool change;
00522                         int i;
00523                         edit ep = new edit();
00524                         edit behind = new edit();
00525                         edit ahead = new edit();
00526                         edit a = new edit();
00527                         edit b = new edit();
00528                         ahead = start;
00529                         ep = null;
00530                         while (ahead != null)
00531                         {
00532                                 behind = ep;
00533                                 ep = ahead;
00534                                 ahead = ahead.next;
00535                                 ep.next = behind;
00536                         }
00537                         while (ep != null)
00538                         {
00539                                 b = ep;
00540                                 if (ep.op == JLibDiff.define_Fields.INSERT)
00541                                 {
00542                                         a = ep;
00543                                         behind = ep.next;
00544                                         while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && ep.line1 == behind.line1)
00545                                         {
00546                                                 a = behind;
00547                                                 behind = behind.next;
00548                                         }
00549                                         HunkAdd add = new HunkAdd();
00550                                         add.ld1 = ep.line1;
00551                                         add.ld2 = ep.line2;
00552                                         add.lf2 = a.line2;
00553                                         System.String s = new System.String("".ToCharArray());
00554                                         do 
00555                                         {
00556                                                 s = s + B[ep.line2 - 1];
00557                                                 ep = ep.next;
00558                                         }
00559                                         while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00560                                         add.b.Add(s + "\n");
00561                                         v.Add(add);
00562                                 }
00563                                 else
00564                                 {
00565                                         do 
00566                                         {
00567                                                 a = b;
00568                                                 b = b.next;
00569                                         }
00570                                         while (b != null && b.op == JLibDiff.define_Fields.DELETE && b.line1 == a.line1 + 1);
00571                                         change = (b != null && b.op == JLibDiff.define_Fields.INSERT && b.line1 == a.line1);
00572                                         if (change)
00573                                         {
00574                                                 HunkChange cha = new HunkChange();
00575                                                 cha.ld1 = ep.line1;
00576                                                 cha.lf1 = a.line1;
00577                                                 i = 0;
00578                                                 behind = b;
00579                                                 while (behind != null && behind.op == JLibDiff.define_Fields.INSERT && behind.line1 == b.line1)
00580                                                 {
00581                                                         i++;
00582                                                         behind = behind.next;
00583                                                 }
00584                                                 cha.ld2 = b.line2;
00585                                                 cha.lf2 = i - 1 + b.line2;
00586                                                 System.String s = new System.String("".ToCharArray());
00587                                                 do 
00588                                                 {
00589                                                         s = s + A[ep.line1 - 1];
00590                                                         ep = ep.next;
00591                                                 }
00592                                                 while (ep != b);
00593                                                 cha.a.Add(s + "\n");
00594                                                 s = new System.String("".ToCharArray());
00595                                                 do 
00596                                                 {
00597                                                         s = s + B[ep.line2 - 1];
00598                                                         ep = ep.next;
00599                                                 }
00600                                                 while (ep != null && ep.op == JLibDiff.define_Fields.INSERT && ep.line1 == b.line1);
00601                                                 cha.b.Add(s + "\n");
00602                                                 v.Add(cha);
00603                                         }
00604                                         else
00605                                         {
00606                                                 HunkDel del = new HunkDel();
00607                                                 del.ld1 = ep.line1;
00608                                                 del.lf1 = a.line1;
00609                                                 del.ld2 = ep.line2;
00610                                                 System.String s = new System.String("".ToCharArray());
00611                                                 do 
00612                                                 {
00613                                                         s = s + A[ep.line1 - 1];
00614                                                         ep = ep.next;
00615                                                 }
00616                                                 while (ep != b);
00617                                                 del.a.Add(s + "\n");
00618                                                 v.Add(del);
00619                                         }
00620                                         
00621                                 }
00622                         }
00623                         return v;
00624                 }
00625                 
00626                 /*
00627                 * Print Hunks with normal format.
00628                 */
00629                 // use only in diff3 (to be deleted)
00630                 public virtual void  print()
00631                 {
00632                          for (System.Collections.IEnumerator e = v.GetEnumerator(); e.MoveNext(); )
00633                         {
00634                                 System.Console.Out.Write(((Hunk) e.Current).convert());
00635                         }
00636                 }
00637                 
00638                 /*
00639                 * Print Hunks with ED_script format.
00640                 */
00641                 //     public void print_ED(){
00642                 //      for (Enumeration e = v.elements() ; e.hasMoreElements() ;)
00643                 //          System.out.print(((Hunk)e.nextElement()).convert_ED());
00644                 //     }
00645                 
00646                 /*
00647                 * Print Hunks with RCS format.
00648                 */
00649                 //     public void print_RCS(){
00650                 //      for (Enumeration e = v.elements() ; e.hasMoreElements() ;)
00651                 //          System.out.print(((Hunk)e.nextElement()).convert_RCS());
00652                 //     }
00653                 
00654                 /*
00655                 * Save Hunks with normal format at the specified file.
00656                 *
00657                 * @param file   file in which Hunks will be saved.
00658                 */
00659                 //     public void save(String file)throws IOException{
00660                 //      PrintWriter out
00661                 //          = new PrintWriter(new BufferedWriter(new FileWriter(file))); 
00662                 //      for (Enumeration e = v.elements() ; e.hasMoreElements() ;)
00663                 //          out.write(((Hunk)e.nextElement()).convert()); 
00664                 //      out.flush();
00665                 //      out.close();
00666                 //     }
00667                 
00668                 /*
00669                 * Save Hunks with ED_script format at the specified file.
00670                 *
00671                 * @param file   file in which Hunks will be saved.
00672                 */
00673                 //     public void save_ED(String file)throws IOException{
00674                 //      PrintWriter out
00675                 //          = new PrintWriter(new BufferedWriter(new FileWriter(file))); 
00676                 //      for (Enumeration e = v.elements() ; e.hasMoreElements() ;)
00677                 //          out.write(((Hunk)e.nextElement()).convert_ED());
00678                 //      out.flush();
00679                 //      out.close();
00680                 //     }
00681                 
00682                 /*
00683                 * Save Hunks with RCS format at the specified file.
00684                 *
00685                 * @param file   file in which Hunks will be saved.
00686                 */
00687                 //     public void save_RCS(String file)throws IOException{
00688                 //      PrintWriter out
00689                 //          = new PrintWriter(new BufferedWriter(new FileWriter(file))); 
00690                 //      for (Enumeration e = v.elements() ; e.hasMoreElements() ;)
00691                 //          out.write(((Hunk)e.nextElement()).convert_RCS());
00692                 //      out.flush();
00693                 //      out.close();
00694                 //     }
00695         }
00696 }

Generated on Mon May 8 22:07:27 2006 by  doxygen 1.3.9.1