comparison lisp/ediff/ediff-ptch.el @ 78:c7528f8e288d r20-0b34

Import from CVS: tag r20-0b34
author cvs
date Mon, 13 Aug 2007 09:05:42 +0200
parents 131b0175ea99
children 1ce6082ce73f
comparison
equal deleted inserted replaced
77:6cb4f478e7bc 78:c7528f8e288d
22 ;; Boston, MA 02111-1307, USA. 22 ;; Boston, MA 02111-1307, USA.
23 23
24 24
25 ;;; Code: 25 ;;; Code:
26 26
27 (require 'ediff-init)
28
27 (defvar ediff-last-dir-patch nil 29 (defvar ediff-last-dir-patch nil
28 "Last directory used by an Ediff command for file to patch.") 30 "Last directory used by an Ediff command for file to patch.")
29 31
30 (defvar ediff-backup-extension 32 (defvar ediff-backup-extension
31 (if (memq system-type '(vax-vms axp-vms emx ms-dos windows-nt windows-95)) 33 (if (memq system-type '(vax-vms axp-vms emx ms-dos windows-nt windows-95))
32 "_orig" ".orig") 34 "_orig" ".orig")
33 "Default backup extension for the patch program.") 35 "Backup extension used by the patch program.
36 See also `ediff-backup-specs'.")
37
38 (defvar ediff-backup-specs (format "-b %s" ediff-backup-extension)
39 "*Backup directives to pass to the patch program.
40 Ediff requires that the old version of the file \(before applying the patch\)
41 is saved in a file named `the-patch-file.extension'. Usually `extension' is
42 `.orig', but this can be changed by the user and may depend on the system.
43 Therefore, Ediff needs to know the backup extension used by the patch program.
44
45 Some versions of the patch program let you specify `-b backup-extension'.
46 Other versions only permit `-b', which assumes some canned extension
47 \(usually `.orig'\).
48
49 Note that both `ediff-backup-extension' and `ediff-backup-specs'
50 must be properly set. If your patch program takes the option `-b',
51 but not `-b extension', the variable `ediff-backup-extension' must
52 still be set so Ediff will know which extension to use.")
53
34 54
35 (defvar ediff-patch-default-directory nil 55 (defvar ediff-patch-default-directory nil
36 "*Default directory to look for patches.") 56 "*Default directory to look for patches.")
37 57
38 (defvar ediff-context-diff-label-regexp 58 (defvar ediff-context-diff-label-regexp
39 (concat "\\(" ; context diff 2-liner 59 (concat "\\(" ; context diff 2-liner
40 "^\\*\\*\\* \\([^ \t]+\\)[^*]+[\t ]*\n--- \\([^ \t]+\\)" 60 "^\\*\\*\\* \\([^ \t]+\\)[^*]+[\t ]*\n--- \\([^ \t]+\\)"
41 "\\|" ; GNU unified format diff 2-liner 61 "\\|" ; GNU unified format diff 2-liner
42 "^--- \\([^ \t]+\\)[^-]+[\t ]*\n\\+\\+\\+ \\([^ \t]+\\)" 62 "^--- \\([^ \t]+\\)[\t ]+.*\n\\+\\+\\+ \\([^ \t]+\\)"
43 "\\)") 63 "\\)")
44 "*Regexp matching filename 2-liners at the start of each context diff.") 64 "*Regexp matching filename 2-liners at the start of each context diff.")
45 65
46 (defvar ediff-patch-program "patch" 66 (defvar ediff-patch-program "patch"
47 "*Name of the program that applies patches.") 67 "*Name of the program that applies patches.
48 (defvar ediff-patch-options "" 68 It is recommended to use GNU-compatible versions.")
49 "*Options to pass to ediff-patch-program.") 69 (defvar ediff-patch-options "-f"
70 "*Options to pass to ediff-patch-program.
71
72 Note: the `-b' option should be specified in `ediff-backup-specs'.
73
74 It is recommended to pass the `-f' option to the patch program, so it won't ask
75 questions. However, some implementations don't accept this option, in which
76 case the default value for this variable should be changed.")
50 77
51 ;; The buffer of the patch file. Local to control buffer. 78 ;; The buffer of the patch file. Local to control buffer.
52 (ediff-defvar-local ediff-patchbufer nil "") 79 (ediff-defvar-local ediff-patchbufer nil "")
53 80
54 ;; The buffer where patch displays its diagnostics. 81 ;; The buffer where patch displays its diagnostics.
108 (re-search-forward ediff-context-diff-label-regexp nil t)) 135 (re-search-forward ediff-context-diff-label-regexp nil t))
109 (if (= opoint (point)) 136 (if (= opoint (point))
110 (forward-char 1) ; ensure progress towards the end 137 (forward-char 1) ; ensure progress towards the end
111 (setq mark2 (move-marker (make-marker) (match-beginning 0)) 138 (setq mark2 (move-marker (make-marker) (match-beginning 0))
112 mark2-end (match-end 0) 139 mark2-end (match-end 0)
113 beg1 (match-beginning 2) 140 beg1 (or (match-beginning 2) (match-beginning 4))
114 end1 (match-end 2) 141 end1 (or (match-end 2) (match-end 4))
115 beg2 (match-beginning 3) 142 beg2 (or (match-beginning 3) (match-beginning 5))
116 end2 (match-end 3)) 143 end2 (or (match-end 3) (match-end 5)))
117 ;; possible-file-names is holding the new file names until we 144 ;; possible-file-names is holding the new file names until we
118 ;; insert the old file name in the patch map 145 ;; insert the old file name in the patch map
119 ;; It is a pair (filename from 1st header line . fn from 2nd line) 146 ;; It is a pair (filename from 1st header line . fn from 2nd line)
120 (setq possible-file-names 147 (setq possible-file-names
121 (cons (if (and beg1 end1) 148 (cons (if (and beg1 end1)
195 (progn 222 (progn
196 (with-output-to-temp-buffer ediff-msg-buffer 223 (with-output-to-temp-buffer ediff-msg-buffer
197 (princ 224 (princ
198 (format " 225 (format "
199 The patch file contains a context diff for 226 The patch file contains a context diff for
227
200 %s 228 %s
201 %s 229 %s
202 230
203 However, Ediff cannot infer the name of the actual file 231 However, Ediff cannot infer the name of the actual file
204 to be patched on your system. If you know the correct file name, 232 to be patched on your system. If you know the correct file name,
316 (read-buffer 344 (read-buffer
317 "Which buffer contains the patch? " 345 "Which buffer contains the patch? "
318 (current-buffer) 'must-match))) 346 (current-buffer) 'must-match)))
319 (setq patch-buf 347 (setq patch-buf
320 (find-file-noselect 348 (find-file-noselect
321 (read-file-name "Which file contains the patch? " dir)))) 349 (read-file-name "Which file contains the patch? "
350 dir nil 'must-match))))
322 351
323 (ediff-eval-in-buffer patch-buf 352 (ediff-eval-in-buffer patch-buf
324 (goto-char (point-min)) 353 (goto-char (point-min))
325 (or (ediff-get-visible-buffer-window patch-buf) 354 (or (ediff-get-visible-buffer-window patch-buf)
326 (progn 355 (progn
402 431
403 (defun ediff-patch-file-internal (patch-buf source-filename 432 (defun ediff-patch-file-internal (patch-buf source-filename
404 &optional startup-hooks) 433 &optional startup-hooks)
405 (setq source-filename (expand-file-name source-filename)) 434 (setq source-filename (expand-file-name source-filename))
406 435
407 (let* ((backup-extension 436 (let* ((shell-file-name ediff-shell)
408 ;; if the user specified a -b option, extract the backup
409 ;; extension from there; else use ediff-backup-extension
410 (substring ediff-patch-options
411 (if (string-match "-b[ \t]+" ediff-patch-options)
412 (match-end 0) 0)
413 (if (string-match "-b[ \t]+[^ \t]+" ediff-patch-options)
414 (match-end 0) 0)))
415 (shell-file-name ediff-shell)
416 (patch-diagnostics (get-buffer-create "*ediff patch diagnostics*")) 437 (patch-diagnostics (get-buffer-create "*ediff patch diagnostics*"))
417 ;; ediff-find-file may use a temp file to do the patch 438 ;; ediff-find-file may use a temp file to do the patch
418 ;; so, we save source-filename and true-source-filename as a var 439 ;; so, we save source-filename and true-source-filename as a var
419 ;; that initially is source-filename but may be changed to a temp 440 ;; that initially is source-filename but may be changed to a temp
420 ;; file for the purpose of patching. 441 ;; file for the purpose of patching.
421 (true-source-filename source-filename) 442 (true-source-filename source-filename)
422 (target-filename source-filename) 443 (target-filename source-filename)
423 target-buf buf-to-patch file-name-magic-p ctl-buf backup-style) 444 target-buf buf-to-patch file-name-magic-p
445 patch-return-code ctl-buf backup-style aux-wind)
424 446
425 ;; if the user didn't specify a backup extension, use
426 ;; ediff-backup-extension
427 (if (string= backup-extension "")
428 (setq backup-extension ediff-backup-extension))
429 (if (string-match "-V" ediff-patch-options) 447 (if (string-match "-V" ediff-patch-options)
430 (error 448 (error
431 "Ediff doesn't take the -V option in `ediff-patch-options'--sorry")) 449 "Ediff doesn't take the -V option in `ediff-patch-options'--sorry"))
432 450
433 ;; Make a temp file, if source-filename has a magic file handler (or if 451 ;; Make a temp file, if source-filename has a magic file handler (or if
442 ;; true-source-filename should be either the original name or a 460 ;; true-source-filename should be either the original name or a
443 ;; temporary file where we put the after-product of the file handler. 461 ;; temporary file where we put the after-product of the file handler.
444 (setq file-name-magic-p (not (equal (file-truename true-source-filename) 462 (setq file-name-magic-p (not (equal (file-truename true-source-filename)
445 (file-truename source-filename)))) 463 (file-truename source-filename))))
446 464
447 ;; Checkout orig file, if necessary, so that the patched file could be 465 ;; Checkout orig file, if necessary, so that the patched file
448 ;; checked back in. 466 ;; could be checked back in.
449 (if (ediff-file-checked-in-p (buffer-file-name buf-to-patch)) 467 (ediff-maybe-checkout buf-to-patch)
450 (ediff-toggle-read-only buf-to-patch))
451 468
452 (ediff-eval-in-buffer patch-diagnostics 469 (ediff-eval-in-buffer patch-diagnostics
453 (insert-buffer patch-buf) 470 (insert-buffer patch-buf)
454 (message "Applying patch ... ") 471 (message "Applying patch ... ")
455 ;; fix environment for gnu patch, so it won't make numbered extensions 472 ;; fix environment for gnu patch, so it won't make numbered extensions
456 (setq backup-style (getenv "VERSION_CONTROL")) 473 (setq backup-style (getenv "VERSION_CONTROL"))
457 (setenv "VERSION_CONTROL" nil) 474 (setenv "VERSION_CONTROL" nil)
458 ;; always pass patch the -f option, so it won't ask any questions 475 (setq patch-return-code
459 (shell-command-on-region 476 (call-process-region
460 (point-min) (point-max) 477 (point-min) (point-max)
461 (format "%s -f %s -b %s %s" 478 shell-file-name
462 ediff-patch-program ediff-patch-options 479 t ; delete region (which contains the patch
463 backup-extension 480 t ; insert output (patch diagnostics) in current buffer
464 (expand-file-name true-source-filename)) 481 nil ; don't redisplay
465 t) 482 shell-command-switch ; usually -c
483 (format "%s %s %s %s"
484 ediff-patch-program
485 ediff-patch-options
486 ediff-backup-specs
487 (expand-file-name true-source-filename))
488 ))
489
466 ;; restore environment for gnu patch 490 ;; restore environment for gnu patch
467 (setenv "VERSION_CONTROL" backup-style)) 491 (setenv "VERSION_CONTROL" backup-style))
468 492
469 (message "Applying patch ... done") 493 (message "Applying patch ... done")
470 (message "") 494 (message "")
471 495
472 (switch-to-buffer patch-diagnostics) 496 (switch-to-buffer patch-diagnostics)
473 (sit-for 0) ; synchronize - let the user see diagnostics 497 (sit-for 0) ; synchronize - let the user see diagnostics
474 498
475 (or (file-exists-p (concat true-source-filename backup-extension)) 499 (or (and (eq patch-return-code 0) ; patch reported success
476 (error "Patch appears to have failed")) 500 (file-exists-p
477 501 (concat true-source-filename ediff-backup-extension)))
502 (progn
503 (with-output-to-temp-buffer ediff-msg-buffer
504 (princ (format "
505 Patch has failed OR the backup version of the patched file was not created by
506 the patch program.
507
508 One reason may be that the values of the variables
509
510 ediff-patch-options = %S
511 ediff-backup-extension = %S
512 ediff-backup-specs = %S
513
514 are not appropriate for the program specified in the variable
515
516 ediff-patch-program = %S
517
518 Another reason could be that the %S program doesn't understand
519 the format of the patch file you used.
520
521 See Ediff on-line manual for more details on these variables.
522 \(Or use a GNU-compatible patch program and stay out of trouble.\)
523
524 Type any key to continue...
525 "
526 ediff-patch-options
527 ediff-backup-extension
528 ediff-backup-specs
529 ediff-patch-program
530 ediff-patch-program)))
531 (beep 1)
532 (if (setq aux-wind (get-buffer-window ediff-msg-buffer))
533 (progn
534 (select-window aux-wind)
535 (goto-char (point-max))))
536 (read-char-exclusive)
537 (if aux-wind (bury-buffer)) ; ediff-msg-buffer
538 (if (setq aux-wind (get-buffer-window patch-diagnostics))
539 (progn
540 (select-window aux-wind)
541 (bury-buffer)))
542 (error "Patch appears to have failed")))
543
478 ;; If black magic is involved, apply patch to a temp copy of the 544 ;; If black magic is involved, apply patch to a temp copy of the
479 ;; file. Otherwise, apply patch to the orig copy. If patch is applied 545 ;; file. Otherwise, apply patch to the orig copy. If patch is applied
480 ;; to temp copy, we name the result old-name_patched for local files 546 ;; to temp copy, we name the result old-name_patched for local files
481 ;; and temp-copy_patched for remote files. The orig file name isn't 547 ;; and temp-copy_patched for remote files. The orig file name isn't
482 ;; changed, and the temp copy of the original is later deleted. 548 ;; changed, and the temp copy of the original is later deleted.
483 ;; Without magic, the original file is renamed (usually into 549 ;; Without magic, the original file is renamed (usually into
484 ;; old-name_orig) and the result of patching will have the same name as 550 ;; old-name_orig) and the result of patching will have the same name as
485 ;; the original. 551 ;; the original.
486 (if (not file-name-magic-p) 552 (if (not file-name-magic-p)
487 (ediff-eval-in-buffer buf-to-patch 553 (ediff-eval-in-buffer buf-to-patch
488 (set-visited-file-name (concat source-filename backup-extension)) 554 (set-visited-file-name
555 (concat source-filename ediff-backup-extension))
489 (set-buffer-modified-p nil)) 556 (set-buffer-modified-p nil))
490 557
491 ;; Black magic in effect. 558 ;; Black magic in effect.
492 ;; If orig file was remote, put the patched file in the temp directory. 559 ;; If orig file was remote, put the patched file in the temp directory.
493 ;; If orig file is local, put the patched file in the directory of 560 ;; If orig file is local, put the patched file in the directory of
500 "_patched")) 567 "_patched"))
501 568
502 (rename-file true-source-filename target-filename t) 569 (rename-file true-source-filename target-filename t)
503 570
504 ;; arrange that the temp copy of orig will be deleted 571 ;; arrange that the temp copy of orig will be deleted
505 (rename-file (concat true-source-filename backup-extension) 572 (rename-file (concat true-source-filename ediff-backup-extension)
506 true-source-filename t)) 573 true-source-filename t))
507 574
508 ;; make orig buffer read-only 575 ;; make orig buffer read-only
509 (setq startup-hooks 576 (setq startup-hooks
510 (cons 'ediff-set-read-only-in-buf-A startup-hooks)) 577 (cons 'ediff-set-read-only-in-buf-A startup-hooks))
511 578
512 ;; set up a buf for the patched file 579 ;; set up a buf for the patched file
513 (setq target-buf (find-file-noselect target-filename)) 580 (setq target-buf (find-file-noselect target-filename))
514 581
515 (setq ctl-buf 582 (setq ctl-buf
516 (ediff-buffers-internal 583 (ediff-buffers-internal
553 620
554 621
555 ;;; Local Variables: 622 ;;; Local Variables:
556 ;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun) 623 ;;; eval: (put 'ediff-defvar-local 'lisp-indent-hook 'defun)
557 ;;; eval: (put 'ediff-eval-in-buffer 'lisp-indent-hook 1) 624 ;;; eval: (put 'ediff-eval-in-buffer 'lisp-indent-hook 1)
625 ;;; eval: (put 'ediff-eval-in-buffer 'edebug-form-spec '(form body))
558 ;;; End: 626 ;;; End:
559 627
560 (provide 'ediff-ptch) 628 (provide 'ediff-ptch)
561 629
562 ;;; ediff-ptch.el ends here 630 ;;; ediff-ptch.el ends here