diff options
| author | Stefan Monnier | 2012-11-09 17:20:47 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2012-11-09 17:20:47 -0500 |
| commit | 32e5c58ca969ec30d31520da52c9866cafa62927 (patch) | |
| tree | aab212d158443e5a04d5828b78a26eca4d5db88c | |
| parent | da03ef8a9d38ef6f059aaeddb8c97dc7e76d3917 (diff) | |
| download | emacs-32e5c58ca969ec30d31520da52c9866cafa62927.tar.gz emacs-32e5c58ca969ec30d31520da52c9866cafa62927.zip | |
Provide new `defalias-fset-function' symbol property.
* src/lisp.h (AUTOLOADP): New macro.
* src/eval.c (Fautoload): Don't attach to loadhist, call Fdefalias instead.
* src/data.c (Ffset): Remove special ad-advice-info handling.
(Fdefalias): Handle autoload definitions and new Qdefalias_fset_function.
(Fsubr_arity): CSE.
(Finteractive_form): Simplify.
(Fquo): Don't insist on having at least 2 arguments.
(Qdefalias_fset_function): New var.
* lisp/emacs-lisp/advice.el (ad-set-advice-info): Set defalias-fset-function.
(ad--defalias-fset): New function.
(ad-safe-fset): Remove.
(ad-make-freeze-definition): Use cl-letf*.
| -rw-r--r-- | etc/NEWS | 3 | ||||
| -rw-r--r-- | lisp/ChangeLog | 7 | ||||
| -rw-r--r-- | lisp/emacs-lisp/advice.el | 150 | ||||
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/data.c | 71 | ||||
| -rw-r--r-- | src/eval.c | 21 | ||||
| -rw-r--r-- | src/lisp.h | 2 |
7 files changed, 134 insertions, 133 deletions
| @@ -38,6 +38,9 @@ spurious warnings about an unused var. | |||
| 38 | ** Docstrings can be made dynamic by adding a `dynamic-docstring-function' | 38 | ** Docstrings can be made dynamic by adding a `dynamic-docstring-function' |
| 39 | text-property on the first char. | 39 | text-property on the first char. |
| 40 | 40 | ||
| 41 | ** The `defalias-fset-function' property lets you catch calls to defalias | ||
| 42 | and redirect them to your own function instead of `fset'. | ||
| 43 | |||
| 41 | * Changes in Emacs 24.4 on non-free operating systems | 44 | * Changes in Emacs 24.4 on non-free operating systems |
| 42 | 45 | ||
| 43 | 46 | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 6f10e311eac..a07749e4f18 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,12 @@ | |||
| 1 | 2012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * emacs-lisp/advice.el (ad-set-advice-info): Set defalias-fset-function. | ||
| 4 | (ad--defalias-fset): New function. | ||
| 5 | (ad-safe-fset): Remove. | ||
| 6 | (ad-make-freeze-definition): Use cl-letf*. | ||
| 7 | |||
| 8 | 2012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 9 | |||
| 3 | * subr.el (dolist): Don't bind VAR in RESULT. | 10 | * subr.el (dolist): Don't bind VAR in RESULT. |
| 4 | 11 | ||
| 5 | * emacs-lisp/advice.el: Miscellaneous cleanup. Use lexical-binding. | 12 | * emacs-lisp/advice.el: Miscellaneous cleanup. Use lexical-binding. |
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el index 92becb8bea9..42c25a4613d 100644 --- a/lisp/emacs-lisp/advice.el +++ b/lisp/emacs-lisp/advice.el | |||
| @@ -1846,8 +1846,12 @@ On each iteration VAR will be bound to the name of an advised function | |||
| 1846 | (defmacro ad-get-advice-info-macro (function) | 1846 | (defmacro ad-get-advice-info-macro (function) |
| 1847 | `(get ,function 'ad-advice-info)) | 1847 | `(get ,function 'ad-advice-info)) |
| 1848 | 1848 | ||
| 1849 | (defmacro ad-set-advice-info (function advice-info) | 1849 | (defsubst ad-set-advice-info (function advice-info) |
| 1850 | `(put ,function 'ad-advice-info ,advice-info)) | 1850 | (cond |
| 1851 | (advice-info (put function 'defalias-fset-function #'ad--defalias-fset)) | ||
| 1852 | ((get function 'defalias-fset-function) | ||
| 1853 | (put function 'defalias-fset-function nil))) | ||
| 1854 | (put function 'ad-advice-info advice-info)) | ||
| 1851 | 1855 | ||
| 1852 | (defmacro ad-copy-advice-info (function) | 1856 | (defmacro ad-copy-advice-info (function) |
| 1853 | `(copy-tree (get ,function 'ad-advice-info))) | 1857 | `(copy-tree (get ,function 'ad-advice-info))) |
| @@ -1954,18 +1958,10 @@ Redefining advices affect the construction of an advised definition." | |||
| 1954 | ;; @@ Dealing with automatic advice activation via `fset/defalias': | 1958 | ;; @@ Dealing with automatic advice activation via `fset/defalias': |
| 1955 | ;; ================================================================ | 1959 | ;; ================================================================ |
| 1956 | 1960 | ||
| 1957 | ;; Since Emacs 19.26 the built-in versions of `fset' and `defalias' | 1961 | ;; Automatic activation happens when a function gets defined via `defalias', |
| 1958 | ;; take care of automatic advice activation, hence, we don't have to | 1962 | ;; which calls the `defalias-fset-function' (which we set to |
| 1959 | ;; hack it anymore by advising `fset/defun/defmacro/byte-code/etc'. | 1963 | ;; `ad--defalias-fset') instead of `fset', if non-nil. |
| 1960 | 1964 | ||
| 1961 | ;; The functionality of the new `fset' is as follows: | ||
| 1962 | ;; | ||
| 1963 | ;; fset(sym,newdef) | ||
| 1964 | ;; assign NEWDEF to SYM | ||
| 1965 | ;; if (get SYM 'ad-advice-info) | ||
| 1966 | ;; ad-activate-internal(SYM, nil) | ||
| 1967 | ;; return (symbol-function SYM) | ||
| 1968 | ;; | ||
| 1969 | ;; Whether advised definitions created by automatic activations will be | 1965 | ;; Whether advised definitions created by automatic activations will be |
| 1970 | ;; compiled depends on the value of `ad-default-compilation-action'. | 1966 | ;; compiled depends on the value of `ad-default-compilation-action'. |
| 1971 | 1967 | ||
| @@ -1977,6 +1973,10 @@ Redefining advices affect the construction of an advised definition." | |||
| 1977 | ;; to `ad-activate' by using `ad-with-auto-activation-disabled' where | 1973 | ;; to `ad-activate' by using `ad-with-auto-activation-disabled' where |
| 1978 | ;; appropriate, especially in a safe version of `fset'. | 1974 | ;; appropriate, especially in a safe version of `fset'. |
| 1979 | 1975 | ||
| 1976 | (defun ad--defalias-fset (function definition) | ||
| 1977 | (fset function definition) | ||
| 1978 | (ad-activate-internal function nil)) | ||
| 1979 | |||
| 1980 | ;; For now define `ad-activate-internal' to the dummy definition: | 1980 | ;; For now define `ad-activate-internal' to the dummy definition: |
| 1981 | (defun ad-activate-internal (_function &optional _compile) | 1981 | (defun ad-activate-internal (_function &optional _compile) |
| 1982 | "Automatic advice activation is disabled. `ad-start-advice' enables it." | 1982 | "Automatic advice activation is disabled. `ad-start-advice' enables it." |
| @@ -1994,12 +1994,6 @@ Redefining advices affect the construction of an advised definition." | |||
| 1994 | `(let ((ad-activate-on-top-level nil)) | 1994 | `(let ((ad-activate-on-top-level nil)) |
| 1995 | ,@body)) | 1995 | ,@body)) |
| 1996 | 1996 | ||
| 1997 | (defun ad-safe-fset (symbol definition) | ||
| 1998 | "A safe `fset' which will never call `ad-activate-internal' recursively." | ||
| 1999 | (ad-with-auto-activation-disabled | ||
| 2000 | (fset symbol definition))) | ||
| 2001 | |||
| 2002 | |||
| 2003 | ;; @@ Access functions for original definitions: | 1997 | ;; @@ Access functions for original definitions: |
| 2004 | ;; ============================================ | 1998 | ;; ============================================ |
| 2005 | ;; The advice-info of an advised function contains its `origname' which is | 1999 | ;; The advice-info of an advised function contains its `origname' which is |
| @@ -2019,8 +2013,7 @@ Redefining advices affect the construction of an advised definition." | |||
| 2019 | (symbol-function origname)))) | 2013 | (symbol-function origname)))) |
| 2020 | 2014 | ||
| 2021 | (defmacro ad-set-orig-definition (function definition) | 2015 | (defmacro ad-set-orig-definition (function definition) |
| 2022 | `(ad-safe-fset | 2016 | `(fset (ad-get-advice-info-field ,function 'origname) ,definition)) |
| 2023 | (ad-get-advice-info-field ,function 'origname) ,definition)) | ||
| 2024 | 2017 | ||
| 2025 | (defmacro ad-clear-orig-definition (function) | 2018 | (defmacro ad-clear-orig-definition (function) |
| 2026 | `(fmakunbound (ad-get-advice-info-field ,function 'origname))) | 2019 | `(fmakunbound (ad-get-advice-info-field ,function 'origname))) |
| @@ -3151,7 +3144,7 @@ advised definition from scratch." | |||
| 3151 | (ad-set-advice-info function old-advice-info) | 3144 | (ad-set-advice-info function old-advice-info) |
| 3152 | ;; Don't `fset' function to nil if it was previously unbound: | 3145 | ;; Don't `fset' function to nil if it was previously unbound: |
| 3153 | (if function-defined-p | 3146 | (if function-defined-p |
| 3154 | (ad-safe-fset function old-definition) | 3147 | (fset function old-definition) |
| 3155 | (fmakunbound function))))) | 3148 | (fmakunbound function))))) |
| 3156 | 3149 | ||
| 3157 | 3150 | ||
| @@ -3182,61 +3175,54 @@ advised definition from scratch." | |||
| 3182 | (error | 3175 | (error |
| 3183 | "ad-make-freeze-definition: `%s' is not yet defined" | 3176 | "ad-make-freeze-definition: `%s' is not yet defined" |
| 3184 | function)) | 3177 | function)) |
| 3185 | (let* ((name (ad-advice-name advice)) | 3178 | (cl-letf* |
| 3186 | ;; With a unique origname we can have multiple freeze advices | 3179 | ((name (ad-advice-name advice)) |
| 3187 | ;; for the same function, each overloading the previous one: | 3180 | ;; With a unique origname we can have multiple freeze advices |
| 3188 | (unique-origname | 3181 | ;; for the same function, each overloading the previous one: |
| 3189 | (intern (format "%s-%s-%s" (ad-make-origname function) class name))) | 3182 | (unique-origname |
| 3190 | (orig-definition | 3183 | (intern (format "%s-%s-%s" (ad-make-origname function) class name))) |
| 3191 | ;; If FUNCTION is already advised, we'll use its current origdef | 3184 | (orig-definition |
| 3192 | ;; as the original definition of the frozen advice: | 3185 | ;; If FUNCTION is already advised, we'll use its current origdef |
| 3193 | (or (ad-get-orig-definition function) | 3186 | ;; as the original definition of the frozen advice: |
| 3194 | (symbol-function function))) | 3187 | (or (ad-get-orig-definition function) |
| 3195 | (old-advice-info | 3188 | (symbol-function function))) |
| 3196 | (if (ad-is-advised function) | 3189 | (old-advice-info |
| 3197 | (ad-copy-advice-info function))) | 3190 | (if (ad-is-advised function) |
| 3198 | (real-docstring-fn | 3191 | (ad-copy-advice-info function))) |
| 3199 | (symbol-function 'ad-make-advised-definition-docstring)) | 3192 | ;; Make sure we construct a proper docstring: |
| 3200 | (real-origname-fn | 3193 | ((symbol-function 'ad-make-advised-definition-docstring) |
| 3201 | (symbol-function 'ad-make-origname)) | 3194 | #'ad-make-freeze-docstring) |
| 3202 | (frozen-definition | 3195 | ;; Make sure `unique-origname' is used as the origname: |
| 3203 | (unwind-protect | 3196 | ((symbol-function 'ad-make-origname) (lambda (_x) unique-origname)) |
| 3204 | (progn | 3197 | (frozen-definition |
| 3205 | ;; Make sure we construct a proper docstring: | 3198 | (unwind-protect |
| 3206 | (ad-safe-fset 'ad-make-advised-definition-docstring | 3199 | (progn |
| 3207 | 'ad-make-freeze-docstring) | 3200 | ;; No we reset all current advice information to nil and |
| 3208 | ;; Make sure `unique-origname' is used as the origname: | 3201 | ;; generate an advised definition that's solely determined |
| 3209 | (ad-safe-fset 'ad-make-origname (lambda (_x) unique-origname)) | 3202 | ;; by ADVICE and the current origdef of FUNCTION: |
| 3210 | ;; No we reset all current advice information to nil and | 3203 | (ad-set-advice-info function nil) |
| 3211 | ;; generate an advised definition that's solely determined | 3204 | (ad-add-advice function advice class position) |
| 3212 | ;; by ADVICE and the current origdef of FUNCTION: | 3205 | ;; The following will provide proper real docstrings as |
| 3213 | (ad-set-advice-info function nil) | 3206 | ;; well as a definition that will make the compiler happy: |
| 3214 | (ad-add-advice function advice class position) | 3207 | (ad-set-orig-definition function orig-definition) |
| 3215 | ;; The following will provide proper real docstrings as | 3208 | (ad-make-advised-definition function)) |
| 3216 | ;; well as a definition that will make the compiler happy: | 3209 | ;; Restore the old advice state: |
| 3217 | (ad-set-orig-definition function orig-definition) | 3210 | (ad-set-advice-info function old-advice-info)))) |
| 3218 | (ad-make-advised-definition function)) | ||
| 3219 | ;; Restore the old advice state: | ||
| 3220 | (ad-set-advice-info function old-advice-info) | ||
| 3221 | ;; Restore functions: | ||
| 3222 | (ad-safe-fset | ||
| 3223 | 'ad-make-advised-definition-docstring real-docstring-fn) | ||
| 3224 | (ad-safe-fset 'ad-make-origname real-origname-fn)))) | ||
| 3225 | (if frozen-definition | 3211 | (if frozen-definition |
| 3226 | (let* ((macro-p (ad-macro-p frozen-definition)) | 3212 | (let* ((macro-p (ad-macro-p frozen-definition)) |
| 3227 | (body (cdr (if macro-p | 3213 | (body (cdr (if macro-p |
| 3228 | (ad-lambdafy frozen-definition) | 3214 | (ad-lambdafy frozen-definition) |
| 3229 | frozen-definition)))) | 3215 | frozen-definition)))) |
| 3230 | `(progn | 3216 | `(progn |
| 3231 | (if (not (fboundp ',unique-origname)) | 3217 | (if (not (fboundp ',unique-origname)) |
| 3232 | (fset ',unique-origname | 3218 | (fset ',unique-origname |
| 3233 | ;; avoid infinite recursion in case the function | 3219 | ;; avoid infinite recursion in case the function |
| 3234 | ;; we want to freeze is already advised: | 3220 | ;; we want to freeze is already advised: |
| 3235 | (or (ad-get-orig-definition ',function) | 3221 | (or (ad-get-orig-definition ',function) |
| 3236 | (symbol-function ',function)))) | 3222 | (symbol-function ',function)))) |
| 3237 | (,(if macro-p 'defmacro 'defun) | 3223 | (,(if macro-p 'defmacro 'defun) |
| 3238 | ,function | 3224 | ,function |
| 3239 | ,@body)))))) | 3225 | ,@body)))))) |
| 3240 | 3226 | ||
| 3241 | 3227 | ||
| 3242 | ;; @@ Activation and definition handling: | 3228 | ;; @@ Activation and definition handling: |
| @@ -3269,7 +3255,7 @@ The current definition and its cache-id will be put into the cache." | |||
| 3269 | (let ((verified-cached-definition | 3255 | (let ((verified-cached-definition |
| 3270 | (if (ad-verify-cache-id function) | 3256 | (if (ad-verify-cache-id function) |
| 3271 | (ad-get-cache-definition function)))) | 3257 | (ad-get-cache-definition function)))) |
| 3272 | (ad-safe-fset function | 3258 | (fset function |
| 3273 | (or verified-cached-definition | 3259 | (or verified-cached-definition |
| 3274 | (ad-make-advised-definition function))) | 3260 | (ad-make-advised-definition function))) |
| 3275 | (if (ad-should-compile function compile) | 3261 | (if (ad-should-compile function compile) |
| @@ -3311,7 +3297,7 @@ the value of `ad-redefinition-action' and de/activate again." | |||
| 3311 | (error "ad-handle-definition (see its doc): `%s' %s" | 3297 | (error "ad-handle-definition (see its doc): `%s' %s" |
| 3312 | function "invalidly redefined") | 3298 | function "invalidly redefined") |
| 3313 | (if (eq ad-redefinition-action 'discard) | 3299 | (if (eq ad-redefinition-action 'discard) |
| 3314 | (ad-safe-fset function original-definition) | 3300 | (fset function original-definition) |
| 3315 | (ad-set-orig-definition function current-definition) | 3301 | (ad-set-orig-definition function current-definition) |
| 3316 | (if (eq ad-redefinition-action 'warn) | 3302 | (if (eq ad-redefinition-action 'warn) |
| 3317 | (message "ad-handle-definition: `%s' got redefined" | 3303 | (message "ad-handle-definition: `%s' got redefined" |
| @@ -3386,7 +3372,7 @@ a call to `ad-activate'." | |||
| 3386 | (if (not (ad-get-orig-definition function)) | 3372 | (if (not (ad-get-orig-definition function)) |
| 3387 | (error "ad-deactivate: `%s' has no original definition" | 3373 | (error "ad-deactivate: `%s' has no original definition" |
| 3388 | function) | 3374 | function) |
| 3389 | (ad-safe-fset function (ad-get-orig-definition function)) | 3375 | (fset function (ad-get-orig-definition function)) |
| 3390 | (ad-set-advice-info-field function 'active nil) | 3376 | (ad-set-advice-info-field function 'active nil) |
| 3391 | (eval (ad-make-hook-form function 'deactivation)) | 3377 | (eval (ad-make-hook-form function 'deactivation)) |
| 3392 | function))))) | 3378 | function))))) |
| @@ -3424,7 +3410,7 @@ Use in emergencies." | |||
| 3424 | (completing-read "Recover advised function: " obarray nil t)))) | 3410 | (completing-read "Recover advised function: " obarray nil t)))) |
| 3425 | (cond ((ad-is-advised function) | 3411 | (cond ((ad-is-advised function) |
| 3426 | (cond ((ad-get-orig-definition function) | 3412 | (cond ((ad-get-orig-definition function) |
| 3427 | (ad-safe-fset function (ad-get-orig-definition function)) | 3413 | (fset function (ad-get-orig-definition function)) |
| 3428 | (ad-clear-orig-definition function))) | 3414 | (ad-clear-orig-definition function))) |
| 3429 | (ad-set-advice-info function nil) | 3415 | (ad-set-advice-info function nil) |
| 3430 | (ad-pop-advised-function function)))) | 3416 | (ad-pop-advised-function function)))) |
| @@ -3658,8 +3644,7 @@ undone on exit of this macro." | |||
| 3658 | (setq index -1) | 3644 | (setq index -1) |
| 3659 | (mapcar (lambda (function) | 3645 | (mapcar (lambda (function) |
| 3660 | (setq index (1+ index)) | 3646 | (setq index (1+ index)) |
| 3661 | `(ad-safe-fset | 3647 | `(fset ',function |
| 3662 | ',function | ||
| 3663 | (or (ad-get-orig-definition ',function) | 3648 | (or (ad-get-orig-definition ',function) |
| 3664 | ,(car (nth index current-bindings))))) | 3649 | ,(car (nth index current-bindings))))) |
| 3665 | functions)) | 3650 | functions)) |
| @@ -3670,8 +3655,7 @@ undone on exit of this macro." | |||
| 3670 | (setq index -1) | 3655 | (setq index -1) |
| 3671 | (mapcar (lambda (function) | 3656 | (mapcar (lambda (function) |
| 3672 | (setq index (1+ index)) | 3657 | (setq index (1+ index)) |
| 3673 | `(ad-safe-fset | 3658 | `(fset ',function |
| 3674 | ',function | ||
| 3675 | ,(car (nth index current-bindings)))) | 3659 | ,(car (nth index current-bindings)))) |
| 3676 | functions)))))) | 3660 | functions)))))) |
| 3677 | 3661 | ||
| @@ -3684,7 +3668,7 @@ undone on exit of this macro." | |||
| 3684 | (interactive) | 3668 | (interactive) |
| 3685 | ;; Advising `ad-activate-internal' means death!! | 3669 | ;; Advising `ad-activate-internal' means death!! |
| 3686 | (ad-set-advice-info 'ad-activate-internal nil) | 3670 | (ad-set-advice-info 'ad-activate-internal nil) |
| 3687 | (ad-safe-fset 'ad-activate-internal 'ad-activate)) | 3671 | (fset 'ad-activate-internal 'ad-activate)) |
| 3688 | 3672 | ||
| 3689 | (defun ad-stop-advice () | 3673 | (defun ad-stop-advice () |
| 3690 | "Stop the automatic advice handling magic. | 3674 | "Stop the automatic advice handling magic. |
| @@ -3692,7 +3676,7 @@ You should only need this in case of Advice-related emergencies." | |||
| 3692 | (interactive) | 3676 | (interactive) |
| 3693 | ;; Advising `ad-activate-internal' means death!! | 3677 | ;; Advising `ad-activate-internal' means death!! |
| 3694 | (ad-set-advice-info 'ad-activate-internal nil) | 3678 | (ad-set-advice-info 'ad-activate-internal nil) |
| 3695 | (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off)) | 3679 | (fset 'ad-activate-internal 'ad-activate-internal-off)) |
| 3696 | 3680 | ||
| 3697 | (defun ad-recover-normality () | 3681 | (defun ad-recover-normality () |
| 3698 | "Undo all advice related redefinitions and unadvises everything. | 3682 | "Undo all advice related redefinitions and unadvises everything. |
| @@ -3700,7 +3684,7 @@ Use only in REAL emergencies." | |||
| 3700 | (interactive) | 3684 | (interactive) |
| 3701 | ;; Advising `ad-activate-internal' means death!! | 3685 | ;; Advising `ad-activate-internal' means death!! |
| 3702 | (ad-set-advice-info 'ad-activate-internal nil) | 3686 | (ad-set-advice-info 'ad-activate-internal nil) |
| 3703 | (ad-safe-fset 'ad-activate-internal 'ad-activate-internal-off) | 3687 | (fset 'ad-activate-internal 'ad-activate-internal-off) |
| 3704 | (ad-recover-all) | 3688 | (ad-recover-all) |
| 3705 | (ad-do-advised-functions (function) | 3689 | (ad-do-advised-functions (function) |
| 3706 | (message "Oops! Left over advised function %S" function) | 3690 | (message "Oops! Left over advised function %S" function) |
diff --git a/src/ChangeLog b/src/ChangeLog index 43d60936d70..da3e96bbcc3 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,14 @@ | |||
| 1 | 2012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * lisp.h (AUTOLOADP): New macro. | ||
| 4 | * eval.c (Fautoload): Don't attach to loadhist, call Fdefalias instead. | ||
| 5 | * data.c (Ffset): Remove special ad-advice-info handling. | ||
| 6 | (Fdefalias): Handle autoload definitions and new Qdefalias_fset_function. | ||
| 7 | (Fsubr_arity): CSE. | ||
| 8 | (Finteractive_form): Simplify. | ||
| 9 | (Fquo): Don't insist on having at least 2 arguments. | ||
| 10 | (Qdefalias_fset_function): New var. | ||
| 11 | |||
| 1 | 2012-11-09 Jan Djärv <jan.h.d@swipnet.se> | 12 | 2012-11-09 Jan Djärv <jan.h.d@swipnet.se> |
| 2 | 13 | ||
| 3 | * image.c (xpm_make_color_table_h): Change to hashtest_equal. | 14 | * image.c (xpm_make_color_table_h): Change to hashtest_equal. |
| @@ -26,7 +37,7 @@ | |||
| 26 | 37 | ||
| 27 | 2012-11-09 Jan Djärv <jan.h.d@swipnet.se> | 38 | 2012-11-09 Jan Djärv <jan.h.d@swipnet.se> |
| 28 | 39 | ||
| 29 | * nsfont.m (ns_descriptor_to_entity): Qcondesed and Qexpanded has | 40 | * nsfont.m (ns_descriptor_to_entity): Qcondensed and Qexpanded has |
| 30 | been removed, so remove them here also. | 41 | been removed, so remove them here also. |
| 31 | 42 | ||
| 32 | 2012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> | 43 | 2012-11-09 Stefan Monnier <monnier@iro.umontreal.ca> |
diff --git a/src/data.c b/src/data.c index abcdd4dca0d..663e25e7063 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -80,7 +80,7 @@ static Lisp_Object Qsubrp, Qmany, Qunevalled; | |||
| 80 | Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; | 80 | Lisp_Object Qfont_spec, Qfont_entity, Qfont_object; |
| 81 | static Lisp_Object Qdefun; | 81 | static Lisp_Object Qdefun; |
| 82 | 82 | ||
| 83 | Lisp_Object Qinteractive_form; | 83 | Lisp_Object Qinteractive_form, Qdefalias_fset_function; |
| 84 | 84 | ||
| 85 | static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); | 85 | static void swap_in_symval_forwarding (struct Lisp_Symbol *, struct Lisp_Buffer_Local_Value *); |
| 86 | 86 | ||
| @@ -444,7 +444,7 @@ DEFUN ("floatp", Ffloatp, Sfloatp, 1, 1, 0, | |||
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | 446 | ||
| 447 | /* Extract and set components of lists */ | 447 | /* Extract and set components of lists. */ |
| 448 | 448 | ||
| 449 | DEFUN ("car", Fcar, Scar, 1, 1, 0, | 449 | DEFUN ("car", Fcar, Scar, 1, 1, 0, |
| 450 | doc: /* Return the car of LIST. If arg is nil, return nil. | 450 | doc: /* Return the car of LIST. If arg is nil, return nil. |
| @@ -608,27 +608,18 @@ DEFUN ("fset", Ffset, Sfset, 2, 2, 0, | |||
| 608 | (register Lisp_Object symbol, Lisp_Object definition) | 608 | (register Lisp_Object symbol, Lisp_Object definition) |
| 609 | { | 609 | { |
| 610 | register Lisp_Object function; | 610 | register Lisp_Object function; |
| 611 | |||
| 612 | CHECK_SYMBOL (symbol); | 611 | CHECK_SYMBOL (symbol); |
| 613 | if (NILP (symbol) || EQ (symbol, Qt)) | ||
| 614 | xsignal1 (Qsetting_constant, symbol); | ||
| 615 | 612 | ||
| 616 | function = XSYMBOL (symbol)->function; | 613 | function = XSYMBOL (symbol)->function; |
| 617 | 614 | ||
| 618 | if (!NILP (Vautoload_queue) && !EQ (function, Qunbound)) | 615 | if (!NILP (Vautoload_queue) && !EQ (function, Qunbound)) |
| 619 | Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); | 616 | Vautoload_queue = Fcons (Fcons (symbol, function), Vautoload_queue); |
| 620 | 617 | ||
| 621 | if (CONSP (function) && EQ (XCAR (function), Qautoload)) | 618 | if (AUTOLOADP (function)) |
| 622 | Fput (symbol, Qautoload, XCDR (function)); | 619 | Fput (symbol, Qautoload, XCDR (function)); |
| 623 | 620 | ||
| 624 | set_symbol_function (symbol, definition); | 621 | set_symbol_function (symbol, definition); |
| 625 | /* Handle automatic advice activation. */ | 622 | |
| 626 | if (CONSP (XSYMBOL (symbol)->plist) | ||
| 627 | && !NILP (Fget (symbol, Qad_advice_info))) | ||
| 628 | { | ||
| 629 | call2 (Qad_activate_internal, symbol, Qnil); | ||
| 630 | definition = XSYMBOL (symbol)->function; | ||
| 631 | } | ||
| 632 | return definition; | 623 | return definition; |
| 633 | } | 624 | } |
| 634 | 625 | ||
| @@ -642,15 +633,32 @@ The return value is undefined. */) | |||
| 642 | (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) | 633 | (register Lisp_Object symbol, Lisp_Object definition, Lisp_Object docstring) |
| 643 | { | 634 | { |
| 644 | CHECK_SYMBOL (symbol); | 635 | CHECK_SYMBOL (symbol); |
| 645 | if (CONSP (XSYMBOL (symbol)->function) | ||
| 646 | && EQ (XCAR (XSYMBOL (symbol)->function), Qautoload)) | ||
| 647 | LOADHIST_ATTACH (Fcons (Qt, symbol)); | ||
| 648 | if (!NILP (Vpurify_flag) | 636 | if (!NILP (Vpurify_flag) |
| 649 | /* If `definition' is a keymap, immutable (and copying) is wrong. */ | 637 | /* If `definition' is a keymap, immutable (and copying) is wrong. */ |
| 650 | && !KEYMAPP (definition)) | 638 | && !KEYMAPP (definition)) |
| 651 | definition = Fpurecopy (definition); | 639 | definition = Fpurecopy (definition); |
| 652 | definition = Ffset (symbol, definition); | 640 | |
| 653 | LOADHIST_ATTACH (Fcons (Qdefun, symbol)); | 641 | { |
| 642 | bool autoload = AUTOLOADP (definition); | ||
| 643 | if (NILP (Vpurify_flag) || !autoload) | ||
| 644 | { /* Only add autoload entries after dumping, because the ones before are | ||
| 645 | not useful and else we get loads of them from the loaddefs.el. */ | ||
| 646 | |||
| 647 | if (AUTOLOADP (XSYMBOL (symbol)->function)) | ||
| 648 | /* Remember that the function was already an autoload. */ | ||
| 649 | LOADHIST_ATTACH (Fcons (Qt, symbol)); | ||
| 650 | LOADHIST_ATTACH (Fcons (autoload ? Qautoload : Qdefun, symbol)); | ||
| 651 | } | ||
| 652 | } | ||
| 653 | |||
| 654 | { /* Handle automatic advice activation. */ | ||
| 655 | Lisp_Object hook = Fget (symbol, Qdefalias_fset_function); | ||
| 656 | if (!NILP (hook)) | ||
| 657 | call2 (hook, symbol, definition); | ||
| 658 | else | ||
| 659 | Ffset (symbol, definition); | ||
| 660 | } | ||
| 661 | |||
| 654 | if (!NILP (docstring)) | 662 | if (!NILP (docstring)) |
| 655 | Fput (symbol, Qfunction_documentation, docstring); | 663 | Fput (symbol, Qfunction_documentation, docstring); |
| 656 | /* We used to return `definition', but now that `defun' and `defmacro' expand | 664 | /* We used to return `definition', but now that `defun' and `defmacro' expand |
| @@ -680,12 +688,10 @@ function with `&rest' args, or `unevalled' for a special form. */) | |||
| 680 | CHECK_SUBR (subr); | 688 | CHECK_SUBR (subr); |
| 681 | minargs = XSUBR (subr)->min_args; | 689 | minargs = XSUBR (subr)->min_args; |
| 682 | maxargs = XSUBR (subr)->max_args; | 690 | maxargs = XSUBR (subr)->max_args; |
| 683 | if (maxargs == MANY) | 691 | return Fcons (make_number (minargs), |
| 684 | return Fcons (make_number (minargs), Qmany); | 692 | maxargs == MANY ? Qmany |
| 685 | else if (maxargs == UNEVALLED) | 693 | : maxargs == UNEVALLED ? Qunevalled |
| 686 | return Fcons (make_number (minargs), Qunevalled); | 694 | : make_number (maxargs)); |
| 687 | else | ||
| 688 | return Fcons (make_number (minargs), make_number (maxargs)); | ||
| 689 | } | 695 | } |
| 690 | 696 | ||
| 691 | DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0, | 697 | DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0, |
| @@ -711,7 +717,7 @@ Value, if non-nil, is a list \(interactive SPEC). */) | |||
| 711 | return Qnil; | 717 | return Qnil; |
| 712 | 718 | ||
| 713 | /* Use an `interactive-form' property if present, analogous to the | 719 | /* Use an `interactive-form' property if present, analogous to the |
| 714 | function-documentation property. */ | 720 | function-documentation property. */ |
| 715 | fun = cmd; | 721 | fun = cmd; |
| 716 | while (SYMBOLP (fun)) | 722 | while (SYMBOLP (fun)) |
| 717 | { | 723 | { |
| @@ -735,6 +741,8 @@ Value, if non-nil, is a list \(interactive SPEC). */) | |||
| 735 | if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE) | 741 | if ((ASIZE (fun) & PSEUDOVECTOR_SIZE_MASK) > COMPILED_INTERACTIVE) |
| 736 | return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE)); | 742 | return list2 (Qinteractive, AREF (fun, COMPILED_INTERACTIVE)); |
| 737 | } | 743 | } |
| 744 | else if (AUTOLOADP (fun)) | ||
| 745 | return Finteractive_form (Fautoload_do_load (fun, cmd, Qnil)); | ||
| 738 | else if (CONSP (fun)) | 746 | else if (CONSP (fun)) |
| 739 | { | 747 | { |
| 740 | Lisp_Object funcar = XCAR (fun); | 748 | Lisp_Object funcar = XCAR (fun); |
| @@ -742,14 +750,6 @@ Value, if non-nil, is a list \(interactive SPEC). */) | |||
| 742 | return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); | 750 | return Fassq (Qinteractive, Fcdr (Fcdr (XCDR (fun)))); |
| 743 | else if (EQ (funcar, Qlambda)) | 751 | else if (EQ (funcar, Qlambda)) |
| 744 | return Fassq (Qinteractive, Fcdr (XCDR (fun))); | 752 | return Fassq (Qinteractive, Fcdr (XCDR (fun))); |
| 745 | else if (EQ (funcar, Qautoload)) | ||
| 746 | { | ||
| 747 | struct gcpro gcpro1; | ||
| 748 | GCPRO1 (cmd); | ||
| 749 | Fautoload_do_load (fun, cmd, Qnil); | ||
| 750 | UNGCPRO; | ||
| 751 | return Finteractive_form (cmd); | ||
| 752 | } | ||
| 753 | } | 753 | } |
| 754 | return Qnil; | 754 | return Qnil; |
| 755 | } | 755 | } |
| @@ -2695,10 +2695,10 @@ usage: (* &rest NUMBERS-OR-MARKERS) */) | |||
| 2695 | return arith_driver (Amult, nargs, args); | 2695 | return arith_driver (Amult, nargs, args); |
| 2696 | } | 2696 | } |
| 2697 | 2697 | ||
| 2698 | DEFUN ("/", Fquo, Squo, 2, MANY, 0, | 2698 | DEFUN ("/", Fquo, Squo, 1, MANY, 0, |
| 2699 | doc: /* Return first argument divided by all the remaining arguments. | 2699 | doc: /* Return first argument divided by all the remaining arguments. |
| 2700 | The arguments must be numbers or markers. | 2700 | The arguments must be numbers or markers. |
| 2701 | usage: (/ DIVIDEND DIVISOR &rest DIVISORS) */) | 2701 | usage: (/ DIVIDEND &rest DIVISORS) */) |
| 2702 | (ptrdiff_t nargs, Lisp_Object *args) | 2702 | (ptrdiff_t nargs, Lisp_Object *args) |
| 2703 | { | 2703 | { |
| 2704 | ptrdiff_t argnum; | 2704 | ptrdiff_t argnum; |
| @@ -3063,6 +3063,7 @@ syms_of_data (void) | |||
| 3063 | DEFSYM (Qfont_object, "font-object"); | 3063 | DEFSYM (Qfont_object, "font-object"); |
| 3064 | 3064 | ||
| 3065 | DEFSYM (Qinteractive_form, "interactive-form"); | 3065 | DEFSYM (Qinteractive_form, "interactive-form"); |
| 3066 | DEFSYM (Qdefalias_fset_function, "defalias-fset-function"); | ||
| 3066 | 3067 | ||
| 3067 | defsubr (&Sindirect_variable); | 3068 | defsubr (&Sindirect_variable); |
| 3068 | defsubr (&Sinteractive_form); | 3069 | defsubr (&Sinteractive_form); |
diff --git a/src/eval.c b/src/eval.c index 975204da017..dcd48cb7250 100644 --- a/src/eval.c +++ b/src/eval.c | |||
| @@ -1876,26 +1876,19 @@ this does nothing and returns nil. */) | |||
| 1876 | CHECK_STRING (file); | 1876 | CHECK_STRING (file); |
| 1877 | 1877 | ||
| 1878 | /* If function is defined and not as an autoload, don't override. */ | 1878 | /* If function is defined and not as an autoload, don't override. */ |
| 1879 | if ((CONSP (XSYMBOL (function)->function) | 1879 | if (!EQ (XSYMBOL (function)->function, Qunbound) |
| 1880 | && EQ (XCAR (XSYMBOL (function)->function), Qautoload))) | 1880 | && !AUTOLOADP (XSYMBOL (function)->function)) |
| 1881 | /* Remember that the function was already an autoload. */ | ||
| 1882 | LOADHIST_ATTACH (Fcons (Qt, function)); | ||
| 1883 | else if (!EQ (XSYMBOL (function)->function, Qunbound)) | ||
| 1884 | return Qnil; | 1881 | return Qnil; |
| 1885 | 1882 | ||
| 1886 | if (NILP (Vpurify_flag)) | 1883 | if (!NILP (Vpurify_flag) && EQ (docstring, make_number (0))) |
| 1887 | /* Only add entries after dumping, because the ones before are | ||
| 1888 | not useful and else we get loads of them from the loaddefs.el. */ | ||
| 1889 | LOADHIST_ATTACH (Fcons (Qautoload, function)); | ||
| 1890 | else if (EQ (docstring, make_number (0))) | ||
| 1891 | /* `read1' in lread.c has found the docstring starting with "\ | 1884 | /* `read1' in lread.c has found the docstring starting with "\ |
| 1892 | and assumed the docstring will be provided by Snarf-documentation, so it | 1885 | and assumed the docstring will be provided by Snarf-documentation, so it |
| 1893 | passed us 0 instead. But that leads to accidental sharing in purecopy's | 1886 | passed us 0 instead. But that leads to accidental sharing in purecopy's |
| 1894 | hash-consing, so we use a (hopefully) unique integer instead. */ | 1887 | hash-consing, so we use a (hopefully) unique integer instead. */ |
| 1895 | docstring = make_number (XUNTAG (function, Lisp_Symbol)); | 1888 | docstring = make_number (XHASH (function)); |
| 1896 | return Ffset (function, | 1889 | return Fdefalias (function, |
| 1897 | Fpurecopy (list5 (Qautoload, file, docstring, | 1890 | list5 (Qautoload, file, docstring, interactive, type), |
| 1898 | interactive, type))); | 1891 | Qnil); |
| 1899 | } | 1892 | } |
| 1900 | 1893 | ||
| 1901 | Lisp_Object | 1894 | Lisp_Object |
diff --git a/src/lisp.h b/src/lisp.h index e2c1cc0e169..72e38fa4653 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -1694,6 +1694,8 @@ typedef struct { | |||
| 1694 | #define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) | 1694 | #define MARKERP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Marker) |
| 1695 | #define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) | 1695 | #define SAVE_VALUEP(x) (MISCP (x) && XMISCTYPE (x) == Lisp_Misc_Save_Value) |
| 1696 | 1696 | ||
| 1697 | #define AUTOLOADP(x) (CONSP (x) && EQ (Qautoload, XCAR (x))) | ||
| 1698 | |||
| 1697 | #define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) | 1699 | #define INTFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Int) |
| 1698 | #define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) | 1700 | #define BOOLFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Bool) |
| 1699 | #define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) | 1701 | #define OBJFWDP(x) (XFWDTYPE (x) == Lisp_Fwd_Obj) |