Esempio n. 1
0
        private static void WriteUnifiedDiffSection(TextWriter writer, ArrayList hunks)
        {
            Diff.Hunk first = (Diff.Hunk)hunks[0];
            Diff.Hunk last  = (Diff.Hunk)hunks[hunks.Count - 1];

            writer.Write("@@ -");
            writer.Write(first.Left.Start + 1);
            writer.Write(",");
            writer.Write(last.Left.End - first.Left.Start + 1);
            writer.Write(" +");
            writer.Write(first.Right.Start + 1);
            writer.Write(",");
            writer.Write(last.Right.End - first.Right.Start + 1);
            writer.WriteLine(" @@");

            foreach (Diff.Hunk hunk in hunks)
            {
                if (hunk.Same)
                {
                    WriteBlock(writer, ' ', hunk.Left);
                    continue;
                }

                WriteBlock(writer, '-', hunk.Left);
                WriteBlock(writer, '+', hunk.Right);
            }
        }
Esempio n. 2
0
            private void AddHunk(int lcount, int rcount, bool same)
            {
                if (hunks.Count > 0 && same == ((Diff.Hunk)hunks[hunks.Count - 1]).Same)
                {
                    Diff.Hunk prev = (Diff.Hunk)hunks[hunks.Count - 1];
                    hunks[hunks.Count - 1] = new Diff.Hunk(
                        leftlist,
                        rightlist,
                        prev.Left.Start,
                        prev.Left.End + lcount,
                        prev.Right.Start,
                        prev.Right.End + rcount,
                        same);
                    return;
                }

                int le = -1;
                int re = -1;

                if (hunks.Count > 0)
                {
                    Diff.Hunk prev = (Diff.Hunk)hunks[hunks.Count - 1];
                    le = prev.Left.End;
                    re = prev.Right.End;
                }

                hunks.Add(new Diff.Hunk(
                              leftlist,
                              rightlist,
                              le + 1,
                              le + lcount,
                              re + 1,
                              re + rcount,
                              same));
            }
		public Merge(IDiff[] diffs) {
			this.diffs = diffs;
			
			// initialize data structures
			
			IEnumerator[] enumerators = new IEnumerator[diffs.Length];
			ArrayList[] hunks = new ArrayList[diffs.Length];

			for (int i = 0; i < hunks.Length; i++) {
				enumerators[i] = ((IEnumerable)diffs[i]).GetEnumerator();
				hunks[i] = new ArrayList();
			}
			
			int startline = 0;
			
			while (true) {
				int endline = -1;
				bool hasmore = false;

				// Get the next hunk for each diff, and find the longest
				// hunk for which there are changes.
				
				for (int i = 0; i < hunks.Length; i++) {
					if (hunks[i].Count > 0) continue;
					if (!enumerators[i].MoveNext()) return;
					hasmore = true;
					Diff.Hunk hunk = (Diff.Hunk)enumerators[i].Current;
					hunks[i].Add(hunk);
					if (!hunk.Same && hunk.Left.End > endline)
						endline = hunk.Left.End;
				}
				
				if (!hasmore) return;
				
				if (endline == -1) {
					// All of the hunks represented no change. Find the shortest hunk,
					// create a hunk from the current start line to the end of the
					// shortest hunk, and retain all of the hunks that overlap into that
					// hunk's next region.  (Clear the rest.)
					int start = int.MaxValue;
					for (int i = 0; i < hunks.Length; i++) {
						Diff.Hunk h = (Diff.Hunk)hunks[i][0];
						if (h.Left.End < start) start = h.Left.End;
					}
					
					// Crop all of the hunks to the shortest region.
					Diff.Hunk[][] h2 = new Diff.Hunk[hunks.Length][];
					for (int i = 0; i < hunks.Length; i++) {
						h2[i] = new Diff.Hunk[1];
						h2[i][0] = (Diff.Hunk)hunks[i][0];
						h2[i][0] = h2[i][0].Crop(startline - h2[i][0].Left.Start, h2[i][0].Left.End - start);
					}
					this.hunks.Add( new Hunk(this, h2, startline, start - startline + 1, true) );
					
					for (int i = 0; i < hunks.Length; i++) {
						Diff.Hunk h = (Diff.Hunk)hunks[i][0];
						if (h.Left.End == start) hunks[i].Clear();
					}
					startline = start+1;
					continue;
				}
				
				// For each diff, add in all of the non-same hunks that fall
				// at least partially within the largest hunk region.  If
				// a hunk crosses the edge, push the edge further and then
				// add more hunks again.
				bool moreToAdd = true;
				while (moreToAdd) {
					moreToAdd = false;
					
					for (int i = 0; i < hunks.Length; i++) {
						Diff.Hunk last = (Diff.Hunk)hunks[i][hunks[i].Count-1];
						while (last.Left.End < endline) {
							if (!enumerators[i].MoveNext()) continue;
							last = (Diff.Hunk)enumerators[i].Current;
							hunks[i].Add(last);
							if (last.Same) continue;
							if (last.Left.End > endline) {
								endline = last.Left.End;
								moreToAdd = true;
							}
						}
					}
				}
				
				Diff.Hunk[][] hunks2 = new Diff.Hunk[hunks.Length][];
				for (int i = 0; i < hunks.Length; i++) {
					// any same hunks that overlap the start or end need to be replaced
					ArrayList hunks3 = new ArrayList();
					foreach (Diff.Hunk h in hunks[i]) {
						Diff.Hunk h2 = h;
						int shiftstart = 0, shiftend = 0;
						if (h2.Same && h2.Left.Start < startline)
							shiftstart = startline - h2.Left.Start;
						if (h2.Same && h2.Left.End > endline)
							shiftend = h2.Left.End - endline;
						if (shiftstart != 0 || shiftend != 0)
							h2 = h2.Crop(shiftstart, shiftend);
						hunks3.Add(h2);
					}
					hunks2[i] = (Diff.Hunk[])hunks3.ToArray(typeof(Diff.Hunk));
				}
				this.hunks.Add( new Hunk(this, hunks2, startline, endline - startline + 1, false) );
				
				// In each hunk list, retain only the last hunk if it
				// overlaps into the next region.
				startline = endline+1;
				for (int i = 0; i < hunks.Length; i++) {
					if (hunks[i].Count == 0) continue;
					Diff.Hunk h = (Diff.Hunk)hunks[i][hunks[i].Count-1];
					hunks[i].Clear();
					if (h.Left.End >= startline)
						hunks[i].Add(h);
				}
				
			}
		}
Esempio n. 4
0
        public Merge(IDiff[] diffs)
        {
            this.diffs = diffs;

            // initialize data structures

            IEnumerator[] enumerators = new IEnumerator[diffs.Length];
            ArrayList[]   hunks       = new ArrayList[diffs.Length];

            for (int i = 0; i < hunks.Length; i++)
            {
                enumerators[i] = ((IEnumerable)diffs[i]).GetEnumerator();
                hunks[i]       = new ArrayList();
            }

            int startline = 0;

            while (true)
            {
                int  endline = -1;
                bool hasmore = false;

                // Get the next hunk for each diff, and find the longest
                // hunk for which there are changes.

                for (int i = 0; i < hunks.Length; i++)
                {
                    if (hunks[i].Count > 0)
                    {
                        continue;
                    }
                    if (!enumerators[i].MoveNext())
                    {
                        return;
                    }
                    hasmore = true;
                    Diff.Hunk hunk = (Diff.Hunk)enumerators[i].Current;
                    hunks[i].Add(hunk);
                    if (!hunk.Same && hunk.Left.End > endline)
                    {
                        endline = hunk.Left.End;
                    }
                }

                if (!hasmore)
                {
                    return;
                }

                if (endline == -1)
                {
                    // All of the hunks represented no change. Find the shortest hunk,
                    // create a hunk from the current start line to the end of the
                    // shortest hunk, and retain all of the hunks that overlap into that
                    // hunk's next region.  (Clear the rest.)
                    int start = int.MaxValue;
                    for (int i = 0; i < hunks.Length; i++)
                    {
                        Diff.Hunk h = (Diff.Hunk)hunks[i][0];
                        if (h.Left.End < start)
                        {
                            start = h.Left.End;
                        }
                    }

                    // Crop all of the hunks to the shortest region.
                    Diff.Hunk[][] h2 = new Diff.Hunk[hunks.Length][];
                    for (int i = 0; i < hunks.Length; i++)
                    {
                        h2[i]    = new Diff.Hunk[1];
                        h2[i][0] = (Diff.Hunk)hunks[i][0];
                        h2[i][0] = h2[i][0].Crop(startline - h2[i][0].Left.Start, h2[i][0].Left.End - start);
                    }
                    this.hunks.Add(new Hunk(this, h2, startline, start - startline + 1, true));

                    for (int i = 0; i < hunks.Length; i++)
                    {
                        Diff.Hunk h = (Diff.Hunk)hunks[i][0];
                        if (h.Left.End == start)
                        {
                            hunks[i].Clear();
                        }
                    }
                    startline = start + 1;
                    continue;
                }

                // For each diff, add in all of the non-same hunks that fall
                // at least partially within the largest hunk region.  If
                // a hunk crosses the edge, push the edge further and then
                // add more hunks again.
                bool moreToAdd = true;
                while (moreToAdd)
                {
                    moreToAdd = false;

                    for (int i = 0; i < hunks.Length; i++)
                    {
                        Diff.Hunk last = (Diff.Hunk)hunks[i][hunks[i].Count - 1];
                        while (last.Left.End < endline)
                        {
                            if (!enumerators[i].MoveNext())
                            {
                                continue;
                            }
                            last = (Diff.Hunk)enumerators[i].Current;
                            hunks[i].Add(last);
                            if (last.Same)
                            {
                                continue;
                            }
                            if (last.Left.End > endline)
                            {
                                endline   = last.Left.End;
                                moreToAdd = true;
                            }
                        }
                    }
                }

                Diff.Hunk[][] hunks2 = new Diff.Hunk[hunks.Length][];
                for (int i = 0; i < hunks.Length; i++)
                {
                    // any same hunks that overlap the start or end need to be replaced
                    ArrayList hunks3 = new ArrayList();
                    foreach (Diff.Hunk h in hunks[i])
                    {
                        Diff.Hunk h2 = h;
                        int       shiftstart = 0, shiftend = 0;
                        if (h2.Same && h2.Left.Start < startline)
                        {
                            shiftstart = startline - h2.Left.Start;
                        }
                        if (h2.Same && h2.Left.End > endline)
                        {
                            shiftend = h2.Left.End - endline;
                        }
                        if (shiftstart != 0 || shiftend != 0)
                        {
                            h2 = h2.Crop(shiftstart, shiftend);
                        }
                        hunks3.Add(h2);
                    }
                    hunks2[i] = (Diff.Hunk[])hunks3.ToArray(typeof(Diff.Hunk));
                }
                this.hunks.Add(new Hunk(this, hunks2, startline, endline - startline + 1, false));

                // In each hunk list, retain only the last hunk if it
                // overlaps into the next region.
                startline = endline + 1;
                for (int i = 0; i < hunks.Length; i++)
                {
                    if (hunks[i].Count == 0)
                    {
                        continue;
                    }
                    Diff.Hunk h = (Diff.Hunk)hunks[i][hunks[i].Count - 1];
                    hunks[i].Clear();
                    if (h.Left.End >= startline)
                    {
                        hunks[i].Add(h);
                    }
                }
            }
        }
Esempio n. 5
0
        public static void WriteUnifiedDiff(Diff diff, TextWriter writer, string fromfile, string tofile, int context)
        {
            writer.Write("--- ");
            writer.WriteLine(fromfile);
            writer.Write("+++ ");
            writer.WriteLine(tofile);

            ArrayList hunkset = new ArrayList();

            foreach (Diff.Hunk hunk in diff)
            {
                Diff.Hunk lasthunk = null;
                if (hunkset.Count > 0)
                {
                    lasthunk = (Diff.Hunk)hunkset[hunkset.Count - 1];
                }

                if (hunk.Same)
                {
                    // At the start of a hunk set, keep only context lines of context.
                    if (lasthunk == null)
                    {
                        if (hunk.Left.Count > context)
                        {
                            hunkset.Add(hunk.Crop(hunk.Left.Count - context, 0));
                        }
                        else
                        {
                            hunkset.Add(hunk);
                        }
                        // Can't have two same hunks in a row, so the last one was a difference.
                    }
                    else
                    {
                        // Small enough context that this unified diff range will not stop.
                        if (hunk.Left.Count <= context * 2)
                        {
                            hunkset.Add(hunk);

                            // Too much of the same.  Keep context lines and end this section.
                            // And then keep the last context lines as context for the next section.
                        }
                        else
                        {
                            hunkset.Add(hunk.Crop(0, hunk.Left.Count - context));
                            WriteUnifiedDiffSection(writer, hunkset);
                            hunkset.Clear();

                            if (hunk.Left.Count > context)
                            {
                                hunkset.Add(hunk.Crop(hunk.Left.Count - context, 0));
                            }
                            else
                            {
                                hunkset.Add(hunk);
                            }
                        }
                    }
                }
                else
                {
                    hunkset.Add(hunk);
                }
            }

            if (hunkset.Count > 0 && !(hunkset.Count == 1 && ((Diff.Hunk)hunkset[0]).Same))
            {
                WriteUnifiedDiffSection(writer, hunkset);
            }
        }