Esempio n. 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 );
        }
Esempio n. 2
0
 public Document()
 {
     lines = new ListAnchor[2];
     lines[0] = new ListAnchor();
     lines[1] = new ListAnchor();
 }
Esempio n. 3
0
        /***************************************************************************
         * Function: TakeSection
         * Purpose:
         * Add a section to the composite list. Called from make_composites
         * to copy a section, add it to the composite list and set the state,
         * leftbase and rightbase.	 Note that the state could be STATE.SAME
         * with a null section on the left.	 May NOT call with STATE.SAME and
         * a null right section! */
        public static void TakeSection(ListAnchor compo, Section left, Section right, STATE state)
        {
            Section sec = null;

            /* select which section is being output, and change the state to indicate it has been output */
            switch( state ){
                case STATE.SAME:
                    /* both the same. we mark both as output, and
                     * take the right one.	It is possible that the
                     * left one could be null (an ignorable blank section) */
                    if( left != null ) left.state = STATE.MARKED;
                    right.state = STATE.MARKED;
                    sec = right;
                    break;

                case STATE.LEFTONLY:
                case STATE.MOVEDLEFT:
                    sec = left;
                    left.state = STATE.MARKED;
                    break;

                case STATE.RIGHTONLY:
                case STATE.MOVEDRIGHT:
                    sec = right;
                    right.state = STATE.MARKED;
                    break;
            }

            /* create a new section on the list */
            Section newsec = new Section( sec.first, sec.last );
            compo.AddTail( newsec );

            newsec.state = state;

            if (left != null)	newsec.leftbase = left.first.linenr;
            else				newsec.leftbase = 0;

            if (right != null)	newsec.rightbase = right.first.linenr;
            else				newsec.rightbase = 0;
        }
Esempio n. 4
0
        /***************************************************************************
         * Function: MatchList
         * Purpose:
         * Match up two lists of sections. Establish links between sections
         * that match, and establish 'correspondence' between sections that
         * are in the same place, but don't match.
         * For each pair of corresponding sections, we also call section_match
         * to try and link up more lines.
         * We return true if we made any more links between lines, or false
         * otherwise. */
        public static bool MatchList(ListAnchor secsleft, ListAnchor secsright,bool isIgnoreBlanks)
        {
            bool bLinked = false;
            Section sec1, sec2;

            /* match up linked sections - We know whether a section is
               supposed to link from its state, but we don't know what section
               it links to.	 Also we can have sections which are defined to
               be matching but actually contain nothing but ignorable blank lines */

            /*	for each linked section try to find the section	 linked to it. */
            for( sec1 = (Section)secsleft.GetHead(); sec1 != null; sec1 = (Section)sec1.GetNext() ) {
                if( sec1.state == STATE.SAME ){
                    Line FirstWithLink = sec1.FindFirstWithLink();
                    for( sec2 = (Section)secsright.GetHead(); sec2 != null; sec2 = (Section)sec2.GetNext() ) {
                        if( sec2.state == STATE.SAME &&
                            FirstWithLink.link == sec2.FindFirstWithLink() )
                        {
                            break;
                        }
                    }
                    if( sec2 != null ){		/* sec2 could be null if sec1 is all allowable blanks */
                        sec1.link = sec2;
                        sec2.link = sec1;
                    }
                }
            }

            /* go through all unmatched sections. Note that we need to complete
             * the link-up of matching sections before this, since we need
             * all the links in place for this to work. */
            for( sec1 = (Section)secsleft.GetHead(); sec1 != null; sec1 = (Section)sec1.GetNext() ) {

                if( sec1.state == STATE.SAME ) continue; /* skip the linked sections */

                /* check that the previous and next sections, if
                 * they exist, are linked. this should not fail since
                 * two consecutive unlinked sections should be made into one section */
                Section secTemp = (Section)sec1.GetPrev();
                if( secTemp != null && secTemp.state != STATE.SAME ) continue;
                secTemp = (Section)sec1.GetNext();
                if( secTemp != null && secTemp.state != STATE.SAME ) continue;

                /* find the section that corresponds to this - that is, the
                 * section following the section linked to our previous section.
                 * we could be at beginning or end of list. */
                if( sec1.GetPrev() != null ){
                    Section secOther = ((Section)sec1.GetPrev()).link;
                    if( secOther == null ) continue;

                    /* check this section is not linked */
                    sec2 = (Section)secOther.GetNext();
                    if( (sec2 == null) || (sec2.link != null) ) continue;

                    /* check that the section after these are linked to each other (or both are at end of list).*/
                    if( sec1.GetNext() != null ){
                        if( ((Section)sec1.GetNext()).link != sec2.GetNext() ) continue;
                    }
                    else {
                        if( sec2.GetNext() == null) continue;
                    }
                }
                else if( sec1.GetNext() != null ){
                    Section secOther = ((Section)sec1.GetNext()).link;
                    if( secOther == null ) continue;

                    /* check this section is not linked */
                    sec2 = (Section)secOther.GetPrev();
                    if( (sec2 == null) || (sec2.link != null) ) continue;

                    /* check that the section before these are linked to each other (or both are at start of list).*/
                    if( sec1.GetPrev() != null ){
                        if( ((Section)sec1.GetPrev()).link != (Section)sec2.GetPrev() ) continue;
                    }
                    else {
                        if( sec2.GetPrev() == null ) continue;
                    }
                }
                else {
                    /* there must be at most one section in each file, and they are unmatched. make these correspond.*/
                    sec2 = (Section)secsright.GetHead();
                }

                /* make the correspondence links */
                if ((sec1 != null) && (sec2 != null)) {
                    sec1.correspond = sec2;
                    sec2.correspond = sec1;
                }

                if ( sec1.Match( sec2,isIgnoreBlanks ) ) bLinked = true;	/* attempt to link up lines */
            }

            return bLinked;
        }
Esempio n. 5
0
 /***************************************************************************
 * Function: section_makelist
 * Purpose:
 * Make a list of sections by traversing a list of lines. Consecutive
 * linked lines that are linked to consecutive lines are put in a single
 * section. Blocks of unlinked lines are placed in a section.
 * If isIgnoreBlanks is set then we first try to link them as normal.
 * but if they won't link then we just skip over them and keep them
 * in the same section.
 * Left must be set true iff the list of lines is a left hand section.
 * Returns a handle to a list of sections */
 public static void MakeList(ListAnchor sections, ListAnchor linelist, bool left,bool isIgnoreBlanks)
 {
     /* for each line in the list */
     for( Line line1 = (Line)linelist.GetHead(); line1 != null; line1 = (Line)line1.GetNext() ){
         /* is it linked ? */
         bool matched;
         Line line2;
         if( line1.link != null || ( isIgnoreBlanks && line1.IsBlank() ) ){
             line2 = FindEndOfMatched(line1,isIgnoreBlanks);
             matched = true;
         } else {
             line2 = FindEndOfUnmatched(line1);
             matched = false;
         }
         Section sect = new Section(line1, line2);	/* create the section and add to list */
         sections.AddTail( sect );
         sect.state = (
               matched ? STATE.SAME
             : left	  ? STATE.LEFTONLY
             :			STATE.RIGHTONLY
             );
         line1 = line2;	/* advance to end of section (no-op if 1 line section) */
     }
 }
Esempio n. 6
0
        /***************************************************************************
         * 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();
                    }
                }
            }
        }