Mercurial > hg > xemacs-beta
diff lisp/efs/efs-ovwrt.el @ 22:8fc7fe29b841 r19-15b94
Import from CVS: tag r19-15b94
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:50:29 +0200 |
parents | |
children | 7e54bd776075 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lisp/efs/efs-ovwrt.el Mon Aug 13 08:50:29 2007 +0200 @@ -0,0 +1,106 @@ +;; -*-Emacs-Lisp-*- +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; File: efs-ovwrt.el +;; Release: $efs release: 1.15 $ +;; Version: $Revision: 1.1 $ +;; RCS: +;; Description: Utilities for overwriting functions with new definitions. +;; Author: Andy Norman <ange@hplb.hpl.hp.com> +;; Modified: Sun Nov 27 18:40:20 1994 by sandy on gandalf +;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;;; Although used by efs, these utilities could be of general use to other +;;; packages too. Keeping them separate from the main efs program +;;; makes it easier for other programs to require them. + +(provide 'efs-ovwrt) + +(defconst efs-ovwrt-version + (concat (substring "$efs release: 1.15 $" 14 -2) + "/" + (substring "$Revision: 1.1 $" 11 -2))) + +(defvar efs-overwrite-fmt + "Note: This function has been modified to work with %s.") + +;; Make the byte compiler happy. +(defvar file-name-handler-alist) +(defvar inhibit-file-name-handlers) +(defvar inhibit-file-name-operation) + +(defun efs-safe-documentation (fun) + "A documentation function that isn't quite as fragile." + (condition-case () + (documentation fun) + (error nil))) + +(defun efs-overwrite-fn (package fun &optional newfun) + "Overwrites a function with a new definition from PACKAGE. +PACKAGE should be a string. The the function to be overwritten is FUN. +The new definition is obtained from the optional NEWFUN. If ommitted, +NEWFUN is taken to be PACKAGE-FUN. The original definition is stored in +PACKAGE-real-FUN. The original documentation is placed on the new +definition suitably augmented." + (let* ((name (symbol-name fun)) + (saved (intern (concat package "-real-" name))) + (new (or newfun (intern (concat package "-" name)))) + (nfun (symbol-function new)) + (exec-directory (if (or (equal (nth 3 command-line-args) "dump") + (equal (nth 4 command-line-args) "dump")) + "../etc/" + exec-directory))) + + (while (symbolp nfun) + (setq nfun (symbol-function nfun))) + + ;; Interpose the new function between the function symbol and the + ;; original definition of the function symbol AT TIME OF FIRST LOAD. + ;; We must only redefine the symbol-function of FUN the very first + ;; time, to avoid blowing away stuff that overloads FUN after this. + + ;; We direct the function symbol to the new function symbol + ;; rather than function definition to allow reloading of this file or + ;; redefining of the individual function (e.g., during debugging) + ;; later after some other code has been loaded on top of our stuff. + + (or (fboundp saved) + (progn + (fset saved (symbol-function fun)) + (fset fun new))) + + ;; Rewrite the doc string on the new function. This should + ;; be done every time the file is loaded (or a function is redefined), + ;; because the underlying overloaded function may have changed its doc + ;; string. + + (let* ((doc-str (efs-safe-documentation saved)) + (ndoc-str (concat doc-str (and doc-str "\n") + (format efs-overwrite-fmt package)))) + + (cond ((listp nfun) + ;; Probe to test whether function is in preloaded read-only + ;; memory, and if so make writable copy: + (condition-case nil + (setcar nfun (car nfun)) + (error + (setq nfun (copy-sequence nfun)) ; shallow copy only + (fset new nfun))) + (let ((ndoc-cdr (nthcdr 2 nfun))) + (if (stringp (car ndoc-cdr)) + ;; Replace the existing docstring. + (setcar ndoc-cdr ndoc-str) + ;; There is no docstring. Insert the overwrite msg. + (setcdr ndoc-cdr (cons (car ndoc-cdr) (cdr ndoc-cdr))) + (setcar ndoc-cdr (format efs-overwrite-fmt package))))) + (t + ;; it's an emacs19 compiled-code object + (let ((new-code (append nfun nil))) ; turn it into a list + (if (nthcdr 4 new-code) + (setcar (nthcdr 4 new-code) ndoc-str) + (setcdr (nthcdr 3 new-code) (cons ndoc-str nil))) + (fset new (apply 'make-byte-code new-code)))))))) + + +;;; end of efs-ovwrt.el