Mercurial > hg > xemacs-beta
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 |