示例#1
0
        public void compare( ListAnchor secsComposite, ListAnchor linesLeft, ListAnchor linesRight, bool isIgnoreBlanks )
        {
            Section wholeLeft, wholeRight;
            ListAnchor secsLeft  = new ListAnchor();
            ListAnchor secsRight = new ListAnchor();

            bool bChanges;
            do {
                bChanges = false;	/* we have made no changes so far this time round the loop */

                /* make a section covering the whole file */
                wholeLeft  = new Section( (Line)linesLeft. GetHead(), (Line)linesLeft.GetTail()  );
                wholeRight = new Section( (Line)linesRight.GetHead(), (Line)linesRight.GetTail() );

                /* link up matching unique lines between these sections */
                if( wholeLeft.Match( wholeRight, isIgnoreBlanks ) ) bChanges = true;

                /* discard previous section lists if made */
                secsLeft. RemoveAll();
                secsRight.RemoveAll();
                /* build new section lists for both files */
                Section.MakeList( secsLeft,  linesLeft,  true ,isIgnoreBlanks);
                Section.MakeList( secsRight, linesRight, false,isIgnoreBlanks);

                /* match up sections - make links and corresponds between
                 * sections. Attempts to section_match corresponding
                 * sections that are not matched. returns true if any
                 * further links were made */
                if( Section.MatchList( secsLeft, secsRight, isIgnoreBlanks ) ) bChanges = true;

            /* repeat as long as we keep adding new links */
            } while( bChanges );

            /* all possible lines linked, and section lists made .
             * combine the two section lists to get a view of the
             * whole comparison - the composite section list. This also
             * sets the state of each section in the composite list. */
            Section.MakeComposite( secsComposite, secsLeft, secsRight );
        }
示例#2
0
文件: Section.cs 项目: otodo/Diffbycs
        /***************************************************************************
         * Function: section_makecomposite
         * Purpose:
         * Make a composite list of sections by traversing a list of sections.
         * Return a handle to a list of sections.
         * During this, set state, leftbase and rightbase for sections.
         * Comments:
         * This function creates a list that corresponds to the 'best' view
         * of the differences between the two lists. We place sections from the
         * two lists into one composite list. Sections that match each other are only
         * inserted once (from the right list). Sections that match, but in different
         * positions in the two lists are inserted twice, once in each position, with
         * status to indicate this. Unmatched sections are inserted in the correct
         * position.
         * - Take sections from the left list until the section is linked to one not
         *	 already taken.
         * - Then take sections from right until we find a section linked to one not
         *	 already taken.
         * - If the two sections waiting are linked to each other, take them both
         *	 (once- we take the right one and advance past both).
         * - Now we have to decide which to take in place and which to declare
         *	 'moved'. Consider the case where the only change is that the first line
         *	 has been moved to the end. We should take the first line (as a move),
         *	 then the bulk of the file (SAME) then the last line (as a move). Hence,
         *	 in difficult cases, we take the smaller section first, to ensure that
         *	 the larger section is taken as SAME.
         *	 To indicate which section has been output, we set the state field
         *	 to STATE.MARKED once we have taken it.	  States in left and right
         *	 lists are of no further interest once we have built the composite.
         *	 Up to this point we have worked off the STATE of a section.  By now
         *	 all the section links are in place, so we can use them too. */
        public static void MakeComposite(ListAnchor compo,ListAnchor secsleft, ListAnchor secsright)
        {
            Section left, right;

            compo.RemoveAll();

            left  = (Section)secsleft.GetHead();
            right = (Section)secsright.GetHead();

            while ( (left != null) || (right != null)) {

                if (left == null) {
                    /* no more in left list - take right section is it moved or just unmatched ? */
                    if( right.link == null ){
                        TakeSection( compo, null, right, STATE.RIGHTONLY );
                        right = (Section)right.GetNext();
                    } else {
                        TakeSection( compo, right.link, right, STATE.MOVEDRIGHT );
                        right = (Section)right.GetNext();
                    }
                }
                else if (right == null) {
                    /* right list empty - must be left next is it moved or just unmatched ? */
                    if (left.link == null) {
                        TakeSection(compo, left, null, STATE.LEFTONLY);
                        left = (Section)left.GetNext();
                    } else {
                        TakeSection(compo, left, left.link, STATE.MOVEDLEFT);
                        left = (Section)left.GetNext();
                    }
                }
                else if(left.state == STATE.LEFTONLY) {
                    /* unlinked section on left */
                    TakeSection(compo, left, null, STATE.LEFTONLY);
                    left = (Section)left.GetNext();
                } else if ( left.link == null ) {
                    /* This is an ignorable blank section on the left. We ignore it. (We will take any such from the right) */
                    left = (Section)left.GetNext();

                } else if (left.link.state==STATE.MARKED) {
                    /* left is linked to section that is already taken*/
                    TakeSection(compo, left, left.link, STATE.MOVEDLEFT);
                    left = (Section)left.GetNext();

                } else	if (right.link == null) {
                    /* take unlinked section on right Either unmatched or ignorable blanks */
                    TakeSection(compo, null, right, right.state);
                    right = (Section)right.GetNext();

                } else if (right.link.state==STATE.MARKED) {
                    /* right is linked to section that's already taken */
                    TakeSection(compo, right.link, right, STATE.MOVEDRIGHT);
                    right = (Section)right.GetNext();

                } else if (left.link == right) {
                    /* sections match */
                    TakeSection(compo, left, right, STATE.SAME);
                    right = (Section)right.GetNext();
                    left  = (Section)left.GetNext();
                } else {
                    /* both sections linked to forward sections
                     * decide first based on size of sections
                     * - smallest first as a move so that largest
                     * is an unchanged. */
                    if ( right.GetLineCount() > left.GetLineCount() ){
                        TakeSection(compo, left, left.link, STATE.MOVEDLEFT);
                        left = (Section)left.GetNext();
                    } else {
                        TakeSection(compo, right.link, right, STATE.MOVEDRIGHT);
                        right = (Section)right.GetNext();
                    }
                }
            }
        }