Function: ediff-extract-diffs3

ediff-extract-diffs3 is a byte-compiled function defined in ediff-diff.el.gz.

Signature

(ediff-extract-diffs3 DIFF-BUFFER WORD-MODE THREE-WAY-COMP &optional BOUNDS)

Source Code

;; Defined in /usr/src/emacs/lisp/vc/ediff-diff.el.gz
;; If WORD-MODE, construct vector of diffs using word numbers.
;; Else, use point values.
;; WORD-MODE also tells if we are in the word-mode or not.
;; If THREE-WAY-COMP, then it is a 3-way comparison. Else, it is merging
;; with ancestor, in which case buffer-C contents is identical to buffer-A/B,
;; contents (unless buffer-A is narrowed) depending on ediff-default-variant's
;; value.
;; BOUNDS specifies visibility bounds to use.
(defun ediff-extract-diffs3 (diff-buffer word-mode three-way-comp
					  &optional bounds)
  (let ((A-buffer ediff-buffer-A)
	(B-buffer ediff-buffer-B)
	(C-buffer ediff-buffer-C)
	(anc-buffer ediff-ancestor-buffer)
	(a-prev 1) ; needed to set the first diff line correctly
	(a-prev-pt nil)
	(b-prev 1)
	(b-prev-pt nil)
	(c-prev 1)
	(c-prev-pt nil)
	(anc-prev 1)
	diff-list shift-A shift-B shift-C
	)

    ;; diff list contains word numbers or points, depending on word-mode
    (setq diff-list (cons (if word-mode 'words 'points)
			  diff-list))
    (if bounds
	(setq shift-A
	      (ediff-overlay-start
	       (ediff-get-value-according-to-buffer-type 'A bounds))
	      shift-B
	      (ediff-overlay-start
	       (ediff-get-value-according-to-buffer-type 'B bounds))
	      shift-C
	      (if three-way-comp
		  (ediff-overlay-start
		   (ediff-get-value-according-to-buffer-type 'C bounds)))))

    ;; reset point in buffers A, B, C
    (ediff-with-current-buffer A-buffer
      (goto-char (if shift-A shift-A (point-min))))
    (ediff-with-current-buffer B-buffer
      (goto-char (if shift-B shift-B (point-min))))
    (if three-way-comp
	(ediff-with-current-buffer C-buffer
	  (goto-char (if shift-C shift-C (point-min)))))
    (if (ediff-buffer-live-p anc-buffer)
	(ediff-with-current-buffer anc-buffer
	  (goto-char (point-min))))

    (ediff-with-current-buffer diff-buffer
      (goto-char (point-min))
      (while (re-search-forward ediff-match-diff3-line nil t)
	;; leave point after matched line
       (beginning-of-line 2)
       (let ((agreement (buffer-substring (match-beginning 1) (match-end 1))))
	 ;; if the files A and B are the same and not 3way-comparison,
	 ;; ignore the difference
	 (if (or three-way-comp (not (string-equal agreement "3")))
	     (let* ((a-begin (car (ediff-get-diff3-group "1")))
		    (a-end  (nth 1 (ediff-get-diff3-group "1")))
		    (b-begin (car (ediff-get-diff3-group "2")))
		    (b-end (nth 1 (ediff-get-diff3-group "2")))
		    (c-or-anc-begin (car (ediff-get-diff3-group "3")))
		    (c-or-anc-end (nth 1 (ediff-get-diff3-group "3")))
		    (state-of-merge
		     (cond ((string-equal agreement "1") 'prefer-A)
			   ((string-equal agreement "2") 'prefer-B)
			   (t ediff-default-variant)))
		    (state-of-diff-merge
		     (if (memq state-of-merge '(default-A prefer-A)) 'B 'A))
		    (state-of-diff-comparison
		     (cond ((string-equal agreement "1") 'A)
			   ((string-equal agreement "2") 'B)
			   ((string-equal agreement "3") 'C)))
		    state-of-ancestor
		    c-begin c-end
		    a-begin-pt a-end-pt
		    b-begin-pt b-end-pt
		    c-begin-pt c-end-pt
		    anc-begin-pt anc-end-pt)

	       (setq state-of-ancestor
		     (= c-or-anc-begin c-or-anc-end))

	       (cond (three-way-comp
		      (setq c-begin c-or-anc-begin
			    c-end c-or-anc-end))
		     ((eq ediff-default-variant 'default-B)
		      (setq c-begin b-begin
			    c-end b-end))
		     (t
		      (setq c-begin a-begin
			    c-end a-end)))

	       ;; compute main diff vector
	       (if word-mode
		   ;; make diff-list contain word numbers
		   (setq diff-list
			 (nconc diff-list
				(list (vector
				       (- a-begin a-prev) (- a-end a-begin)
				       (- b-begin b-prev) (- b-end b-begin)
				       (- c-begin c-prev) (- c-end c-begin)
				       nil nil ; dummy ancestor
				       nil     ; state of diff
				       nil     ; state of merge
				       nil     ; state of ancestor
				       )))
			 a-prev a-end
			 b-prev b-end
			 c-prev c-end)
		 ;; else convert lines to points
		 (ediff-with-current-buffer A-buffer
		   (goto-char (or a-prev-pt shift-A (point-min)))
		   (forward-line (- a-begin a-prev))
		   (setq a-begin-pt (point))
		   (forward-line (- a-end a-begin))
		   (setq a-end-pt (point)
			 a-prev a-end
			 a-prev-pt a-end-pt))
		 (ediff-with-current-buffer B-buffer
		   (goto-char (or b-prev-pt shift-B (point-min)))
		   (forward-line (- b-begin b-prev))
		   (setq b-begin-pt (point))
		   (forward-line (- b-end b-begin))
		   (setq b-end-pt (point)
			 b-prev b-end
			 b-prev-pt b-end-pt))
		 (ediff-with-current-buffer C-buffer
		   (goto-char (or c-prev-pt shift-C (point-min)))
		   (forward-line (- c-begin c-prev))
		   (setq c-begin-pt (point))
		   (forward-line (- c-end c-begin))
		   (setq c-end-pt (point)
			 c-prev c-end
			 c-prev-pt c-end-pt))
		 (if (ediff-buffer-live-p anc-buffer)
		     (ediff-with-current-buffer anc-buffer
		       (forward-line (- c-or-anc-begin anc-prev))
		       (setq anc-begin-pt (point))
		       (forward-line (- c-or-anc-end c-or-anc-begin))
		       (setq anc-end-pt (point)
			     anc-prev c-or-anc-end)))
		 (setq diff-list
		       (nconc
			diff-list
			;; if comparing with ancestor, then there also is a
			;; state-of-difference marker
			(if three-way-comp
			    (list (vector
				   a-begin-pt a-end-pt
				   b-begin-pt b-end-pt
				   c-begin-pt c-end-pt
				   nil nil ; ancestor begin/end
				   state-of-diff-comparison
				   nil	; state of merge
				   nil  ; state of ancestor
				   ))
			  (list (vector a-begin-pt a-end-pt
					b-begin-pt b-end-pt
					c-begin-pt c-end-pt
					anc-begin-pt anc-end-pt
					state-of-diff-merge
					state-of-merge
					state-of-ancestor
					)))
			)))
	       ))

	 ))) ; end ediff-with-current-buffer
    diff-list
    ))